漏洞介绍
Apache Struts2 是一个开源的 Java Web 应用程序开发框架,旨在帮助开发人员构建灵活、可维护和可扩展的企业级Web应用程序。CVE-2023-50164 Apache Struts文件上传漏洞,攻击者可利用该漏洞污染相关上传参数导致目录遍历,可导致上传webshell,执行任意代码。
解题思路
首先要知道,这道题考察的是Struts2 S2-006漏洞。
题目提供了附件下载,下载下来后是一个ROOT.war,解压后查看WEB-INF文件下有class文件,首先通过反编译查看源码,这里使用的反编译工具是jad:
1 | jad.exe -o -r -s java -d src HeaderIconAction.class |

进行源代码审计,通过查看be.more.elegant.filter.JspFilter#doFilter发现只有在view文件夹下才能够运行jsp文件,其他目录下都被过滤了:

审计be.more.elegant.HeaderIconAction#doUpload对应的路由是/upload.action

String remoteAddr = request.getRemoteAddr();这行代码从request对象中获取远程客户端(即上传文件的用户)的 IP 地址。String md5ForIp = md5Ip(remoteAddr);这行调用了一个名为md5Ip的方法,输入参数是远程地址(客户端的 IP),并返回该 IP 地址的 MD5 散列值。File sandBox = new File(UPLOAD_DIR, md5ForIp);这行代码创建了一个File对象,代表一个目录,该目录位于一个名为UPLOAD_DIR的父目录下,目录名为该 IP 的 MD5 散列值。File fileToCreate = new File(sandBox, fileUploadFileName);这行代码创建了一个新的File对象,代表要创建的文件,它位于上一步创建的沙箱目录下,文件名由变量fileUploadFileName指定。FileUtils.copyFile(fileUpload, fileToCreate);使用 Apache Commons IO 库的FileUtils.copyFile方法将上传的文件(fileUpload)复制到新位置(fileToCreate)。uploadedPath = (new StringBuilder()).append("statics/uploads/").append(md5ForIp).append("/").append(fileUploadFileName).toString();这行代码构建了上传文件的相对路径字符串,并将其赋值给uploadedPath变量。
由于Struts2 对大小写不敏感,所以我们可以使用改变大小写对fileUploadFileName进行二次赋值,让实际的fileUploadFileName内容改编为../../../views/o.jsp,这样就可以把jsp文件放到views目录下了。
首先尝试上传一个正常的文件。

构造的payload:
1 | POST /upload.action |
结果显示上传成功

访问http://<ip>/views/o.jsp?pwd=666&o=./readflag获取flag值rwctf{Y0U K0wn S2 sooooo!!! w3ll}