From ac80dc1646ac57d33fb269e86578d66b23c15c76 Mon Sep 17 00:00:00 2001 From: Anthony Rose <20302208+Cx01N@users.noreply.github.com> Date: Thu, 1 Jul 2021 18:52:56 -0700 Subject: [PATCH] Release 4.0 (#3) * updated to Empire 4.0 release format * updated readme --- README.md | 26 +++++++-------- chiselserver.py | 85 +++++++++++++++++++++++++------------------------ 2 files changed, 54 insertions(+), 57 deletions(-) diff --git a/README.md b/README.md index 5768850..8c19b1e 100644 --- a/README.md +++ b/README.md @@ -1,33 +1,29 @@ # SharpChisel-Plugin The SharpChisel Plugin runs the Chisel server for Invoke-SharpChisel. The Powershell script loads SharpChisel which has the embeded Golang Chisel binary -- client only to save space. This plugin is entirely contained in [Empire](https://github.com/BC-SECURITY/Empire/) -and runs in the background. - -`sharpchisel [port]` - -![image](https://user-images.githubusercontent.com/20302208/97376340-5a00a300-187a-11eb-902d-ec9b75389beb.png) - -Use command `chiselserver start` to configure and start the Chisel Server. You can shutdown -the socks proxy by running the command `chiselserver stop` or by exiting Empire. Check out the original [Chisel project](https://github.com/jpillora/chisel) +and runs in the background. Use command `start` to configure and start the Chisel Server. You can shutdown +the socks proxy by running the command `stop` or by exiting Empire. Check out the original [Chisel project](https://github.com/jpillora/chisel) and [SharpChisel](https://github.com/shantanu561993/SharpChisel). - ## Getting Started * To run the plugin, you can download it fom the releases [Releases](https://github.com/BC-SECURITY/ChiselServer-Plugin/releases) page. ## Install Prerequisites: -- Empire 3.6.0+ - -1. Add ChiselServer.py and binaries to the plugins folder of Empire. Make sure to put your compiled chisel binary in the data/misc directory, calling it chiselserver_mac or chiselserver_linux depending on your platform +- Empire >= 4.0.0 +1. Add chiselserver.py to plugins folder of Empire. -![image](https://user-images.githubusercontent.com/20302208/95636534-49f85f00-0a44-11eb-87c1-754a2368febb.png) +![image](https://user-images.githubusercontent.com/20302208/120246969-b4098280-c226-11eb-9345-4ff994ee5312.png) +2. Add [Chisel binaries](https://github.com/jpillora/chisel/releases) to the /empire/server/data/misc folder. Files must be labeled as chiselserver_mac or chiselserver_linux + depending on your platform. -2. Plugins are automatically loaded into Empire as of 3.4.0, otherwise run ```plugin ChiselServer``` +![image](https://user-images.githubusercontent.com/20302208/120248850-a277a900-c22d-11eb-87e6-df3220089444.png) -![image](https://user-images.githubusercontent.com/20302208/95636737-b5dac780-0a44-11eb-9f82-34dcb66c24fe.png) +## Usage +### Client +![image](https://user-images.githubusercontent.com/20302208/120249004-3c3f5600-c22e-11eb-962c-c9107c77b624.gif) ## Contributions Plugin created by [Kevin Clark](https://gitlab.com/KevinJClark/invoke-sharpchisel/) diff --git a/chiselserver.py b/chiselserver.py index 297c9b7..9e2ed31 100644 --- a/chiselserver.py +++ b/chiselserver.py @@ -1,6 +1,7 @@ from __future__ import print_function -from lib.common.plugins import Plugin -import lib.common.helpers as helpers + +from empire.server.common.plugins import Plugin +import empire.server.common.helpers as helpers import subprocess import platform @@ -14,7 +15,7 @@ class Plugin(Plugin): def onLoad(self): print(helpers.color("[*] Loading Chisel server plugin")) - + self.main_menu = None self.enabled = False self.socks_connections = {} self.connection_times = {} @@ -27,7 +28,9 @@ def onLoad(self): 'Author': ['@kevin'], - 'Description': ('Chisel server for invoke_sharpchisel module.'), + 'Description': ('Chisel server for invoke_sharpchisel module. ' + 'Requires: chisel server binaries to be placed in the data/misc directory with ' + 'names chiselserver_linux and chiselserver_mac'), 'Software': '', @@ -40,7 +43,9 @@ def onLoad(self): 'status': { 'Description': '', 'Required': True, - 'Value': 'start' + 'Value': 'start', + 'SuggestedValues': ['start', 'stop', 'status'], + 'Strict': True }, 'port': { 'Description': 'Port number.', @@ -55,9 +60,10 @@ def execute(self, command): # essentially switches to parse the proper command to execute self.options['status']['Value'] = command['status'] self.options['port']['Value'] = command['port'] - results = self.do_chiselserver('') + results = self.do_chiselserver() return results - except: + except Exception as e: + print(e) return False def register(self, mainMenu): @@ -68,8 +74,9 @@ def register(self, mainMenu): mainMenu.__class__.do_chiselserver = self.do_chiselserver self.installPath = mainMenu.installPath + self.main_menu = mainMenu - def do_chiselserver(self, args): + def do_chiselserver(self): """ Check if the Chisel server is already running. @@ -100,56 +107,47 @@ def register_sessions(output_lines): except: # Capture error message or warning error_message = line[line.find('session#' + session_number) + len('session#' + session_number) + 2:] - print(helpers.color("[!] Warning: " + error_message)) + self.main_menu.plugin_socketio_message(self.info[0]['Name'], "[!] Warning: " + error_message) # Check if the Chisel server is already running - if not self.chisel_proc or self.chisel_proc.poll(): - self.enabled = False - else: + if self.chisel_proc: self.enabled = True - - # If no arguments then run with defaults. API will pass arguments and still give this message. - if not args: - print(helpers.color("[!] Usage: chiselserver [port]")) - self.start = self.options['status']['Value'] - self.port = self.options['port']['Value'] - print(helpers.color("[+] Defaults: chiselserver " + self.start + " " + self.port)) else: - self.start = args.split(" ")[0] + self.enabled = False + + # API will pass arguments and still give this message. + self.start = self.options['status']['Value'] + self.port = self.options['port']['Value'] if self.start == "status": if self.enabled: register_sessions(get_output_lines(self.chisel_proc.stderr)) - print(helpers.color("[*] Chisel server is enabled and listening on port %s" % self.port)) + self.main_menu.plugin_socketio_message(self.info[0]['Name'], "[*] Chisel server is enabled and " + "listening on port %s" % self.port) if not self.socks_connections: - print(helpers.color("[*] No connected Chisel clients!")) + self.main_menu.plugin_socketio_message(self.info[0]['Name'], "[*] No connected Chisel clients!") else: - print(" Session ID\tConnection Time\t\tConnection") - print(" ----------\t---------------\t\t----------") + self.main_menu.plugin_socketio_message(self.info[0]['Name'], + " Session ID\tConnection Time\t\tConnection" + + "\n ----------\t---------------\t\t----------") for session in self.connection_times.keys(): - print(" %s \t%s \t%s" % ( - session, self.connection_times[session], self.socks_connections[session])) - print() - + self.main_menu.plugin_socketio_message(self.info[0]['Name'], " %s \t%s \t%s" % ( + session, self.connection_times[session], self.socks_connections[session]) + "\n") else: - print(helpers.color("[*] Chisel server is disabled")) + self.main_menu.plugin_socketio_message(self.info[0]['Name'], "[!] Chisel server is disabled") elif self.start == "stop": if self.enabled: self.chisel_proc.kill() self.socks_connections = {} self.connection_times = {} - print(helpers.color("[*] Stopped Chisel server")) + self.main_menu.plugin_socketio_message(self.info[0]['Name'], "[!] Stopped Chisel server") else: - print(helpers.color("[!] Chisel server is already stopped")) + self.main_menu.plugin_socketio_message(self.info[0]['Name'], "[!] Chisel server is already stopped") elif self.start == "start": if not self.enabled: - try: - self.port = args.split(" ")[1] - except: - self.port = self.options['port']['Value'] - + self.port = self.options['port']['Value'] if platform.system() == "Darwin": self.binary = "chiselserver_mac" @@ -157,15 +155,18 @@ def register_sessions(output_lines): self.binary = "chiselserver_linux" else: - print(helpers.color("[!] Chisel server unsupported platform: %s" % platform.system())) + self.main_menu.plugin_socketio_message(self.info[0]['Name'], "[!] Chisel server unsupported " + "platform: %s" % platform.system()) return self.fullPath = self.installPath + "/data/misc/" + self.binary if not os.path.exists(self.fullPath): - print(helpers.color("[!] Chisel server binary does not exist: %s" % self.fullPath)) + self.main_menu.plugin_socketio_message(self.info[0]['Name'], "[!] Chisel server binary does not " + "exist: %s" % self.fullPath) return elif not os.access(self.fullPath, os.X_OK): - print(helpers.color("[*] Chisel server binary does not have execute permission -- Setting it now")) + self.main_menu.plugin_socketio_message(self.info[0]['Name'], "[*] Chisel server binary does not have" + " execute permission -- Setting it now") mode = os.stat(self.fullPath).st_mode mode += 0o100 # Octal 100 os.chmod(self.fullPath, mode) @@ -173,12 +174,12 @@ def register_sessions(output_lines): chisel_cmd = [self.fullPath, "server", "--reverse", "--port", self.port] self.chisel_proc = subprocess.Popen(chisel_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, bufsize=1, universal_newlines=True) - print(helpers.color("[+] Chisel server started and listening on http://0.0.0.0:%s" % self.port)) + self.main_menu.plugin_socketio_message(self.info[0]['Name'], "[+] Chisel server started and listening on http://0.0.0.0:%s" % self.port) else: - print(helpers.color("[!] Chisel server is already started")) + self.main_menu.plugin_socketio_message(self.info[0]['Name'], "[!] Chisel server is already started") else: - print(helpers.color("[!] Usage: chiselserver [port]")) + self.main_menu.plugin_socketio_message(self.info[0]['Name'], "[!] Usage: chiselserver [port]") def shutdown(self): """