diff --git a/examples/ntlmrelayx.py b/examples/ntlmrelayx.py index 5377a695e7..e3efbbf818 100755 --- a/examples/ntlmrelayx.py +++ b/examples/ntlmrelayx.py @@ -57,10 +57,11 @@ RELAY_SERVERS = [] class MiniShell(cmd.Cmd): - def __init__(self, relayConfig, threads): + def __init__(self, relayConfig, threads, api_address): cmd.Cmd.__init__(self) self.prompt = 'ntlmrelayx> ' + self.api_address = api_address self.tid = None self.relayConfig = relayConfig self.intro = 'Type help for list of commands' @@ -108,7 +109,7 @@ def do_socks(self, line): ''' headers = ["Protocol", "Target", "Username", "AdminStatus", "Port"] - url = "http://localhost:9090/ntlmrelayx/api/v1.0/relays" + url = "http://{}/ntlmrelayx/api/v1.0/relays".format(self.api_address) try: proxy_handler = ProxyHandler({}) opener = build_opener(proxy_handler) @@ -305,6 +306,9 @@ def stop_servers(threads): 'SMB Server (16 hex bytes long. eg: 1122334455667788)') parser.add_argument('-socks', action='store_true', default=False, help='Launch a SOCKS proxy for the connection relayed') + parser.add_argument('-socks-address', default='127.0.0.1', help='SOCKS5 server address (also used for HTTP API)') + parser.add_argument('-socks-port', default=1080, type=int, help='SOCKS5 server port') + parser.add_argument('-http-api-port', default=9090, type=int, help='SOCKS5 HTTP API port') parser.add_argument('-wh','--wpad-host', action='store',help='Enable serving a WPAD file for Proxy Authentication attack, ' 'setting the proxy host to the one supplied.') parser.add_argument('-wa','--wpad-auth-num', action='store', type=int, default=1, help='Prompt for authentication N times for clients without MS16-077 installed ' @@ -471,8 +475,9 @@ def stop_servers(threads): threads = set() socksServer = None if options.socks is True: + # Start a SOCKS proxy in the background - socksServer = SOCKS() + socksServer = SOCKS(server_address=(options.socks_address, options.socks_port), api_port=options.http_api_port) socksServer.daemon_threads = True socks_thread = Thread(target=socksServer.serve_forever) socks_thread.daemon = True @@ -485,7 +490,7 @@ def stop_servers(threads): logging.info("Servers started, waiting for connections") try: if options.socks: - shell = MiniShell(c, threads) + shell = MiniShell(c, threads, api_address='{}:{}'.format(options.socks_address, options.http_api_port)) shell.cmdloop() else: sys.stdin.read() diff --git a/impacket/examples/ntlmrelayx/servers/socksserver.py b/impacket/examples/ntlmrelayx/servers/socksserver.py index 2fe53989ec..616142e541 100644 --- a/impacket/examples/ntlmrelayx/servers/socksserver.py +++ b/impacket/examples/ntlmrelayx/servers/socksserver.py @@ -243,36 +243,40 @@ def activeConnectionsWatcher(server): LOG.info('Relay connection for %s at %s(%d) already exists. Discarding' % (userName, target, port)) client.killConnection() -def webService(server): - from flask import Flask, jsonify - app = Flask(__name__) +def webService(addr, port): + def _webService(server): + from flask import Flask, jsonify - log = logging.getLogger('werkzeug') - log.setLevel(logging.ERROR) + app = Flask(__name__) - @app.route('/') - def index(): - print(server.activeRelays) - return "Relays available: %s!" % (len(server.activeRelays)) + log = logging.getLogger('werkzeug') + log.setLevel(logging.ERROR) - @app.route('/ntlmrelayx/api/v1.0/relays', methods=['GET']) - def get_relays(): - relays = [] - for target in server.activeRelays: - for port in server.activeRelays[target]: - for user in server.activeRelays[target][port]: - if user != 'data' and user != 'scheme': - protocol = server.activeRelays[target][port]['scheme'] - isAdmin = server.activeRelays[target][port][user]['isAdmin'] - relays.append([protocol, target, user, isAdmin, str(port)]) - return jsonify(relays) + @app.route('/') + def index(): + print(server.activeRelays) + return "Relays available: %s!" % (len(server.activeRelays)) - @app.route('/ntlmrelayx/api/v1.0/relays', methods=['GET']) - def get_info(relay): - pass + @app.route('/ntlmrelayx/api/v1.0/relays', methods=['GET']) + def get_relays(): + relays = [] + for target in server.activeRelays: + for port in server.activeRelays[target]: + for user in server.activeRelays[target][port]: + if user != 'data' and user != 'scheme': + protocol = server.activeRelays[target][port]['scheme'] + isAdmin = server.activeRelays[target][port][user]['isAdmin'] + relays.append([protocol, target, user, isAdmin, str(port)]) + return jsonify(relays) - app.run(host='0.0.0.0', port=9090) + @app.route('/ntlmrelayx/api/v1.0/relays', methods=['GET']) + def get_info(relay): + pass + + app.run(host=addr, port=port) + + return _webService class SocksRequestHandler(socketserver.BaseRequestHandler): def __init__(self, request, client_address, server): @@ -453,8 +457,8 @@ def handle(self): class SOCKS(socketserver.ThreadingMixIn, socketserver.TCPServer): - def __init__(self, server_address=('0.0.0.0', 1080), handler_class=SocksRequestHandler): - LOG.info('SOCKS proxy started. Listening at port %d', server_address[1] ) + def __init__(self, server_address=('127.0.0.1', 1080), handler_class=SocksRequestHandler, api_port=9090): + LOG.info('SOCKS proxy started. Listening on %s:%d', server_address[0], server_address[1]) self.activeRelays = {} self.socksPlugins = {} @@ -476,7 +480,7 @@ def __init__(self, server_address=('0.0.0.0', 1080), handler_class=SocksRequestH self.__timer = RepeatedTimer(KEEP_ALIVE_TIMER, keepAliveTimer, self) # Let's start our RESTful API - self.restAPI = Thread(target=webService, args=(self, )) + self.restAPI = Thread(target=webService(server_address[0], api_port), args=(self, )) self.restAPI.daemon = True self.restAPI.start()