diff --git a/README.md b/README.md index d9e171d..daa5d2d 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,14 @@ # SocksProxyServer-Plugin The Socks Proxy Plugin runs a Socks Proxy Server for [Invoke-SocksProxy](https://github.com/BC-SECURITY/Invoke-SocksProxy) that supports Socks 4 and 5 protocols. This plugin is entirely contained in [Empire](https://github.com/BC-SECURITY/Empire/) -and runs in the background. Use command `socksproxyserver` to configure and start the Socks Proxy Server. You can shutdown -the socks proxy by running the command `socksproxyserver kill` or by exiting Empire. +and runs in the background. -![image](https://user-images.githubusercontent.com/20302208/95637897-d8221480-0a47-11eb-8a69-3f132fe5d079.png) +` [handler port] [proxy port] [certificate] [private key]` + +Use command `socksproxyserver start` to configure and start the Socks Proxy Server. You can shutdown +the socks proxy by running the command `socksproxyserver stop` or by exiting Empire. + +![image](https://user-images.githubusercontent.com/20302208/96073581-92a48380-0e5b-11eb-8a14-e5fff1c55e48.png) ## Getting Started * To run the plugin, you can download it fom the releases [Releases](https://github.com/BC-SECURITY/Invoke-SocksProxy/releases) page. @@ -24,4 +28,7 @@ Prerequisites: ## Future Features - Add multiple socks server support (similar to agents and listeners) -- Add UDP and bind request support \ No newline at end of file +- Add UDP and bind request support + +## Contributions +Updates made from @mjokic plugin [code](https://github.com/BC-SECURITY/Empire/pull/351) \ No newline at end of file diff --git a/plugins/SocksServer.py b/plugins/SocksServer.py index 76bb700..a959460 100644 --- a/plugins/SocksServer.py +++ b/plugins/SocksServer.py @@ -2,29 +2,39 @@ from lib.common.plugins import Plugin import lib.common.helpers as helpers + import socket import _thread -import time import ssl import queue import os -import multiprocessing class Plugin(Plugin): description = "Launches a Socks Proxy Server to run in the background of Empire" def onLoad(self): - self.commands = {'do_socksproxyserver': {'Description': 'Launch a Socks Proxy Server', - 'arg': 'the argument required and it''s description' - } + """ any custom loading behavior - called by init, so any + behavior you'd normally put in __init__ goes here """ + self.commands = {'do_socksproxyserver': {'Description': 'Manages socks proxy server', + 'arg': ' [handler port] [proxy port] [certificate] [private key]' + } } - self.proxy = SocksProxy() + # load default ports + self.handler_port = '443' + self.proxy_port = '1080' + + # load default empire certs + self.cert_path = os.path.abspath("./data/") + self.certificate = "%s/empire-chain.pem" % self.cert_path + self.private_key = "%s/empire-priv.key" % self.cert_path + + self.running = False - def execute(self, dict): + def execute(self, command_list): try: - if dict['command'] == 'do_socksproxyserver': - results = self.do_socksproxyserver(dict['arguments']['arg']) + if command_list['command'] == 'do_socksproxyserver': + results = self.do_socksproxyserver(command_list['arguments']['arg']) return results except: return False @@ -32,47 +42,46 @@ def execute(self, dict): def get_commands(self): return self.commands - def register(self, mainMenu): + def register(self, main_menu): """ any modifications to the mainMenu go here - e.g. registering functions to be run by user commands """ - mainMenu.__class__.do_socksproxyserver = self.do_socksproxyserver + main_menu.__class__.do_socksproxyserver = self.do_socksproxyserver - def do_socksproxyserver(self, line): + def do_socksproxyserver(self, args): "Launches a SocksProxy Server to run in the background of Empire" - parts = line.split(' ') - if parts[0].lower() == "kill": - if self.proxy.running: - self.proxy.end() - elif not self.proxy.running: - self.proxy.start() + args = args.split(" ") + if args[0].lower() == "start": + self.start_socks_server(args) + elif args[0].lower() == "stop": + self.shutdown() + else: + print(helpers.color("[!] socksserver [handler port] [proxy port] [certificate] [private key]")) + + def start_socks_server(self, args): + if not self.running: + self.running = True + if len(args) > 4: + self.certificate = args[3] + self.private_key = args[4] + if len(args) > 2: + self.handler_port = args[1] + self.proxy_port = args[2] + _thread.start_new_thread(self.server, + (self.handler_port, self.proxy_port, self.certificate, self.private_key)) else: print(helpers.color("[!] Socks Proxy Server Already Running!")) def shutdown(self): """if the plugin spawns a process provide a shutdown method for when Empire exits else leave it as pass""" - if self.proxy.running: - self.proxy.end() - -class SocksProxy(object): - def __init__(self): - self.cert_path = os.path.abspath("./data/") - self.cert = "%s/empire-chain.pem" % (self.cert_path) - self.private_key = "%s/empire-priv.key" % (self.cert_path) - if not (os.path.isfile(self.cert) and os.path.isfile(self.private_key)): - print(helpers.color("[!] Unable to find default certificate.")) - - self.handler_port = "443" - self.proxy_port = "1080" - self.running = False - self.process = None - - - def main(self, handler_port, proxy_port, certificate, private_key): - _thread.start_new_thread(self.server, (handler_port, proxy_port, certificate, private_key)) - while True: - time.sleep(60) + if self.running: + self.running = False + print(helpers.color("[*] Stopping socks proxy server...")) + socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect(("127.0.0.1", int(self.handler_port))) + socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect(("127.0.0.1", int(self.proxy_port))) + else: + print(helpers.color("[!] Server is not running!")) - def handlerServer(self, q, handler_port, certificate, private_key): + def handler_server(self, q, handler_port, certificate, private_key): context = ssl.SSLContext(ssl.PROTOCOL_TLSv1) context.load_cert_chain(certificate, private_key) try: @@ -80,14 +89,17 @@ def handlerServer(self, q, handler_port, certificate, private_key): dock_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) dock_socket.bind(('', int(handler_port))) dock_socket.listen(5) - print(helpers.color("\r[+] Handler listening on: " + handler_port)) - while True: + print(helpers.color("[*] Handler listening on: " + handler_port)) + print(helpers.color("[*] Using certificate: " + certificate)) + print(helpers.color("[*] Using private key: " + private_key)) + print(helpers.color("[+] Socks proxy server started")) + while self.running: try: clear_socket, address = dock_socket.accept() client_socket = context.wrap_socket(clear_socket, server_side=True) try: data = b"" - while (data.count(b'\n') < 3): + while data.count(b'\n') < 3: data_recv = client_socket.recv() data += data_recv client_socket.send( @@ -97,14 +109,13 @@ def handlerServer(self, q, handler_port, certificate, private_key): pass q.put(client_socket) except Exception as e: - print(e) pass except Exception as e: - print(e) + pass finally: dock_socket.close() - def getActiveConnection(self, q): + def get_active_connection(self, q): try: client_socket = q.get(block=True, timeout=10) except: @@ -112,33 +123,33 @@ def getActiveConnection(self, q): try: client_socket.send(b"HELLO") except: - return self.getActiveConnection(q) + return self.get_active_connection(q) return client_socket def server(self, handler_port, proxy_port, certificate, private_key): q = queue.Queue() - _thread.start_new_thread(self.handlerServer, (q, handler_port, certificate, private_key)) + _thread.start_new_thread(self.handler_server, (q, handler_port, certificate, private_key)) try: dock_socket2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM) dock_socket2.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) dock_socket2.bind(('127.0.0.1', int(proxy_port))) dock_socket2.listen(5) - print(helpers.color("\n[+] Socks Proxy Server listening on: " + proxy_port)) - while True: + print(helpers.color("\n[*] Socks server listening on: " + proxy_port)) + while self.running: try: client_socket2, address = dock_socket2.accept() - client_socket = self.getActiveConnection(q) + client_socket = self.get_active_connection(q) if client_socket == None: client_socket2.close() _thread.start_new_thread(self.forward, (client_socket, client_socket2)) _thread.start_new_thread(self.forward, (client_socket2, client_socket)) except Exception as e: - print(e) - pass + print(helpers.color("[!] Exception: %s" % e)) except Exception as e: - print(e) + print(helpers.color("[!] Exception: %s" % e)) finally: dock_socket2.close() + print(helpers.color("\n[+] Socks proxy server stopped")) def forward(self, source, destination): try: @@ -157,22 +168,3 @@ def forward(self, source, destination): except: pass pass - - def start(self): - print(helpers.color("[*] Starting Socks Proxy Server")) - handler_port = input(helpers.color("[>] Enter Handler Port [443]: ")) - if handler_port == "": - self.handler_port = "443" - proxy_port = input(helpers.color("[>] Enter Proxy Port [1080]: ")) - if proxy_port == "": - self.proxy_port = "1080" - self.process = multiprocessing.Process(target=self.main, - args=(self.handler_port, self.proxy_port, self.cert, self.private_key)) - self.running = True - self.process.daemon = True - self.process.start() - - def end(self): - print(helpers.color("[!] Killing Socks Proxy Server")) - self.running = False - self.process.terminate()