Skip to content

Commit

Permalink
ntlmrelayx.py: Make SOCKS5 address and port configurable (fortra#1636)
Browse files Browse the repository at this point in the history
* ntlmrelayx.py: Make SOCKS5 address and port configurable

* Fix API port
  • Loading branch information
rtpt-erikgeiser authored Jan 11, 2024
1 parent 4b56c18 commit 6c9a1aa
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 31 deletions.
13 changes: 9 additions & 4 deletions examples/ntlmrelayx.py
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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 '
Expand Down Expand Up @@ -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
Expand All @@ -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()
Expand Down
58 changes: 31 additions & 27 deletions impacket/examples/ntlmrelayx/servers/socksserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down Expand Up @@ -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 = {}
Expand All @@ -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()

Expand Down

0 comments on commit 6c9a1aa

Please sign in to comment.