Skip to content

Commit

Permalink
Updated plugin code (#2)
Browse files Browse the repository at this point in the history
* merged updates from mjokic

* Updated readme with arguments

* Contribution section added to readme
  • Loading branch information
Cx01N authored Oct 15, 2020
1 parent f1c264d commit afb4e76
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 77 deletions.
15 changes: 11 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -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)
`<start|stop> [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.
Expand All @@ -24,4 +28,7 @@ Prerequisites:

## Future Features
- Add multiple socks server support (similar to agents and listeners)
- Add UDP and bind request support
- Add UDP and bind request support

## Contributions
Updates made from @mjokic plugin [code](https://github.com/BC-SECURITY/Empire/pull/351)
138 changes: 65 additions & 73 deletions plugins/SocksServer.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,92 +2,104 @@

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': '<start|stop> [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

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 <start|stop> [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:
dock_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
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(
Expand All @@ -97,48 +109,47 @@ 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:
return None
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:
Expand All @@ -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()

0 comments on commit afb4e76

Please sign in to comment.