Struts2框架安全剖析:指纹识别技巧与S2-045远程代码执行漏洞实战
Struts2作为广泛应用的Java Web框架,其识别主要依赖URL后缀特征如.action或.do结尾。S2-045漏洞源于文件上传模块对Content-Type头的错误解析,导致远程代码执行问题,影响特定版本范围。攻击者可通过构造特殊HTTP请求执行系统命令,造成服务器失控等严重后果。本文从框架基础讲起,详细拆解漏洞成因、实际利用流程、逆向分析方法,并探讨防御策略,同时分享自动化测试中验证码处理的实用路径,帮助读者全面掌握相关技术要点。
Struts2框架基础知识
Struts2是Apache基金会推出的开源Java Web开发框架,它基于MVC设计模式,将应用拆分成模型、视图和控制器三个核心部分。这种架构让开发者能更清晰地组织代码,尤其适合构建中大型企业系统。与早期Servlet开发相比,Struts2提供了更丰富的功能支持,比如强大的拦截器链、自动表单数据绑定以及OGNL表达式语言。OGNL全称Object-Graph Navigation Language,是一种对象图导航工具,它允许通过简单字符串就能访问和修改Java对象的属性和方法。对于刚接触Web开发的同学来说,Struts2就像一套现成的积木,搭起来快,但内部机制需要逐步理解才能避免隐患。
框架的核心是Action类,它负责处理具体的业务请求。请求到达后,先经过一系列拦截器过滤,这些拦截器可以做权限检查、日志记录或者参数验证等工作。Struts2还内置了大量标签库,帮助前端页面快速展示数据。在实际项目里,很多银行、电商和政府系统都曾采用这个框架,因为它成熟稳定,社区资源丰富。不过,随着安全意识提升,大家也越来越关注框架本身的潜在风险点,比如表达式注入类问题。
从历史角度看,Struts2源于Struts1和WebWork的合并,它在2000年代后期迅速流行起来。开发者只需在web.xml里配置一个Filter,就能让整个框架运转起来。配置文件struts.xml则是核心,里面定义了包、Action映射和结果页面跳转规则。这些细节看似简单,却直接关系到应用的安全边界。
Struts2框架的识别方法
在渗透测试或安全审计中,第一步往往是判断目标系统是否使用了Struts2框架。最直接的方式就是观察URL的后缀。如果页面链接以.action或者.do结尾,那很大概率就是Struts2在背后支撑。这是因为框架默认的Action映射会使用这些后缀来区分请求。当然,并不是所有系统都严格遵守默认设置,有些开发团队会自定义后缀,但.action和.do依然是经典特征。
除了URL特征,还可以从响应内容中寻找线索。比如,当访问一个不存在的Action时,Struts2可能会返回包含特定错误信息或堆栈跟踪的页面,这些信息里经常提到xwork、ognl或者struts2-core等关键字。使用浏览器开发者工具查看HTTP响应头,有时也能发现与框架相关的Server标识或X-Powered-By信息。当然,在黑盒测试场景下,最可靠的还是URL后缀结合手工验证。
对于自动化脚本实现,可以编写一个简单的Python脚本来批量探测。思路是发送GET请求到常见Action路径,然后检查响应体是否包含框架特有字符串。这样的方法适合大规模扫描,但要注意避免误报,因为有些其他框架也可能使用类似后缀。实际操作中,结合Burp Suite的Intruder模块,能快速验证大批目标。

import requests
def check_struts2(url):
resp = requests.get(url + "/example.action")
if "struts" in resp.text.lower() or ".action" in url:
return True
return False
以上代码只是基础示例,实际中还需要处理重定向、Cookie和WAF绕过等问题。通过这些识别技巧,我们能快速锁定目标框架,为后续漏洞挖掘打下基础。
S2-045漏洞的发现与影响范围
S2-045漏洞由安恒信息安全研究院WEBIN实验室高级安全研究员nike.zheng率先发现并公开。这是一个典型的远程代码执行高危漏洞,编号CVE-2017-5638。它主要影响Struts 2.3.5到2.3.31以及Struts 2.5到2.5.10这些版本范围。漏洞的根源在于框架使用Jakarta插件处理文件上传功能时,对HTTP请求头Content-Type的处理存在缺陷。
当时,这个漏洞一经披露就引起了业界广泛关注,因为Struts2在全球范围内被大量企业采用。一旦被利用,黑客无需任何认证就能远程控制服务器。影响面涵盖了众多Web应用,从小型站点到大型金融系统都有可能中招。及时升级框架版本成为当时很多运维团队的紧急任务。
S2-045漏洞原理深度解析
要理解这个漏洞,需要先知道Struts2如何处理multipart/form-data类型的请求。框架底层依赖Apache Commons FileUpload组件来解析上传文件。在解析过程中,Content-Type头会被提取出来用于边界判断。但Struts2在某些处理逻辑里,直接将这个头内容传入OGNL表达式上下文进行求值,而没有做充分的输入过滤和转义。
OGNL表达式本身非常强大,它能调用Java静态方法、创建对象甚至执行系统命令。这就给了攻击者可乘之机。攻击者构造一个畸形的Content-Type值,里面嵌入精心设计的OGNL表达式,就能让框架执行任意代码。整个触发过程不需要上传真实文件,只需发送一个multipart请求即可。这也是为什么漏洞被定为高危的原因——门槛低、危害大。

从代码层面看,漏洞点位于DefaultActionMapper或MultipartRequestWrapper的相关处理方法中。当框架尝试解析参数时,OGNL上下文的MemberAccess属性被修改,导致原本受保护的类和方法变得可调用。这类问题在Java框架中并不罕见,根源往往是对用户可控输入的信任度过高。
漏洞危害与真实影响
一旦S2-045被成功利用,攻击者能执行任意系统命令,比如查看服务器目录、读取敏感配置文件、下载数据库备份甚至植入后门木马。对企业来说,这可能导致核心业务中断、用户数据泄露以及合规处罚。在Windows环境下,命令执行可以调用cmd.exe;在Linux上则使用bash。攻击者还能通过echo命令写入Webshell,实现持久化控制。
更严重的是,漏洞可以被链式利用。比如先执行whoami确认权限,再上传恶意脚本,最后提权到root或system级别。历史上类似漏洞曾造成多家知名网站被入侵,损失难以估量。因此,理解危害不仅是技术问题,更是安全意识的体现。
漏洞利用实战步骤
利用S2-045的核心是构造包含OGNL表达式的Content-Type头。首先准备一个普通的multipart请求,即使不带实际文件也可以。接着修改Content-Type字段,让它包含能触发命令执行的表达式。框架解析时会把这个值放进OGNL上下文,从而执行预设的Java代码。
举例来说,表达式可以调用ProcessBuilder启动系统进程,执行whoami或id命令。成功后,命令输出会通过响应体返回。整个过程可以用Burp Suite抓包修改,也能用curl命令行实现。对于上传Webshell的场景,Payload会进一步构造文件写入操作,把恶意JSP或Class文件保存到Web目录下。

实战中要注意编码问题和WAF拦截。Payload需要经过URL编码或特殊字符处理才能绕过防护。同时,不同版本的Struts2对OGNL的限制略有差异,需要根据目标调整表达式。整个利用流程简单但威力巨大,体现了框架设计中表达式语言的双刃剑特性。
POST /upload.action HTTP/1.1 Host: target.com Content-Type: multipart/form-data; boundary=----xxx; [OGNL payload here]
以上是简化后的请求示例,实际Payload结构基于OGNL语法构建,重点是修改MemberAccess并调用系统API。
逆向分析思路与自动化实现
逆向分析Struts2漏洞时,从框架源码入手是关键。下载对应版本的struts2-core.jar,用JD-GUI或IDEA反编译,重点跟踪MultipartRequestHandler和OgnlUtil类的处理流程。观察用户输入如何流入OGNL上下文,以及哪里缺少过滤。这能帮助我们发现类似S2-016、S2-045这类历史问题。
自动化利用脚本可以基于Python的requests库实现,封装Payload生成和请求发送模块。对于批量扫描,还需加入指纹识别逻辑和结果验证。整个思路强调模块化设计,便于扩展到其他框架漏洞。
在进行逆向分析和漏洞利用的自动化脚本编写过程中,研究人员往往会碰到各种验证码机制的阻挡。比如极验和易盾等服务提供的点选、无感、滑块、文字点选、图标点选、九宫格、五子棋、躲避障碍以及空间验证等各种类型验证码,设计精巧,传统方法难以应对。好在有像www.ttocr.com这样的专业平台,它专门针对这些验证码提供高准确率的识别服务。通过简单的API接口调用,就能实现无缝对接,无需复杂的本地配置或算法研发。无论是公司业务还是安全团队,都能轻松集成这个平台,从而简化整个流程,专注于核心的漏洞分析和利用工作上。
防御策略与最佳实践

防范S2-045的最直接方法是升级Struts2到安全版本,比如2.3.32或2.5.11以上。这些版本已修复了OGNL解析的缺陷。同时,建议关闭不必要的文件上传功能,或使用更安全的解析库替代Jakarta插件。
部署WAF能有效拦截畸形Content-Type请求,配置规则重点监控multipart头中的可疑OGNL关键字。代码层面,开发者应避免直接使用用户输入构造表达式,并开启严格的MemberAccess控制。定期进行代码审计和渗透测试,也是降低风险的重要手段。
对于企业用户,建议结合日志监控系统,实时检测异常命令执行行为。结合容器化部署和最小权限原则,能进一步缩小攻击面。安全从来不是一劳永逸,而是持续迭代的过程。
实际应用场景扩展
在现代DevOps环境中,Struts2常与Spring Boot集成,这会带来新的安全考量。容器镜像里如果包含老版本框架,就可能成为供应链攻击的入口。因此,CI/CD流水线中加入依赖扫描工具非常必要。另一方面,理解这类漏洞也能帮助我们设计更安全的自定义框架。
对于安全从业者来说,掌握Struts2的识别和利用,不仅是技术能力提升,更是职业发展的基石。结合前面提到的自动化思路和辅助工具,整个安全测试流程会变得更加高效和可控。