From 461639e5dc60f0fd680b1f20363b5056eb8cc584 Mon Sep 17 00:00:00 2001 From: covertivy Date: Mon, 14 Apr 2025 15:43:41 +0300 Subject: [PATCH 1/4] Updated pyproject to use newest versions of dploot & impacket. --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 712dec0..f590242 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,8 +27,8 @@ dpp = 'donpapi.entry:main' [tool.poetry.dependencies] python = "^3.9" -impacket = "^0.11.0" -dploot = "^2.7.3" +impacket = "^0.12.0" +dploot = "^3.1.2" rich = "^13.7.0" sqlalchemy = "^2.0.25" termcolor = "^2.4.0" From 4d27c68006b21aaf90f17076804c5d21a51424a8 Mon Sep 17 00:00:00 2001 From: covertivy Date: Mon, 14 Apr 2025 15:47:44 +0300 Subject: [PATCH 2/4] Moved false positives to a const. Added false positive cli argument. Fixed typo in variable name 'false_positivee'. Actually sending the false positive list to DonPAPICore class. --- donpapi/core.py | 1 + donpapi/entry.py | 25 +++++++++---------------- donpapi/lib/consts.py | 15 +++++++++++++++ 3 files changed, 25 insertions(+), 16 deletions(-) create mode 100644 donpapi/lib/consts.py diff --git a/donpapi/core.py b/donpapi/core.py index 08a17b0..4d54cee 100644 --- a/donpapi/core.py +++ b/donpapi/core.py @@ -254,6 +254,7 @@ def get_masterkeys(self): passwords=self.plaintexts, nthashes=self.nthashes, dpapiSystem=self.dpapi_systemkey, + false_positive=self.false_positive, ) masterkeys += masterkeys_triage.triage_masterkeys() if self.remoteops_allowed and self.lsa_dump is not None: diff --git a/donpapi/entry.py b/donpapi/entry.py index 6176842..783020a 100644 --- a/donpapi/entry.py +++ b/donpapi/entry.py @@ -35,6 +35,7 @@ from donpapi.lib.first_run import first_run, init_output_dir from donpapi.lib.utils import create_recover_file, load_recover_file, parse_credentials_files, parse_targets, update_recover_file from donpapi.lib.logger import donpapi_logger, donpapi_console +from donpapi.lib.consts import FALSE_POSITIVES from pkgutil import iter_modules from importlib import import_module @@ -197,6 +198,7 @@ def main(): collect_subparser.add_argument("--keep-collecting", type=int, action="store", metavar="seconds", help="Rerun the attack against all targets after X seconds, X being the value") collect_subparser.add_argument("--threads", default=50, type=int, metavar="Number of threads", help="Number of threads (default: 50)") collect_subparser.add_argument('--no-config', action="store_true", help="Do not load donpapi config file (~/.donpapi/donpapi.conf)") + collect_subparser.add_argument("--false-positive", default=FALSE_POSITIVES, action="extend", nargs="+", help=f"Specify a list of \"false positive\" usernames to avoid collecting them (will extend the existing list: {FALSE_POSITIVES}).") group_authent = collect_subparser.add_argument_group("authentication") @@ -231,19 +233,7 @@ def main(): set_main_logger(donpapi_logger) - - # Stores the list of false positives usernames: - false_positivee = [ - ".", - "..", - "desktop.ini", - "Public", - "Default", - "Default User", - "All Users", - ".NET v4.5", - ".NET v4.5 Classic" - ] + # Stores the maximum filesize max_filesize = 5000000 @@ -251,9 +241,9 @@ def main(): if len(sys.argv)==1: parser.print_help() sys.exit(1) - + options = parser.parse_args() - + # Init Logger if options.v == 1: donpapi_logger.logger.setLevel(logging.INFO) @@ -292,6 +282,9 @@ def main(): options = argparse.Namespace(**options_recovered) current_target_recovered = target_recovered + # Remove duplicates from false positive list. + false_positive = list(set(options.false_positive)) + # Handle account if options.domain is None: options.domain = '' @@ -376,7 +369,7 @@ def main(): nthashes, masterkeys, donpapi_config, - false_positivee, + false_positive, max_filesize, output_dir ) diff --git a/donpapi/lib/consts.py b/donpapi/lib/consts.py new file mode 100644 index 0000000..8ccfb45 --- /dev/null +++ b/donpapi/lib/consts.py @@ -0,0 +1,15 @@ +"""consts.py +File containing constant values that are used in the DonPAPI project. +""" + +FALSE_POSITIVES = [ + ".", + "..", + "desktop.ini", + "Public", + "Default", + "Default User", + "All Users", + ".NET v4.5", + ".NET v4.5 Classic" +] From 0c3523263559868747ea6f062b8fbc940cb63016 Mon Sep 17 00:00:00 2001 From: covertivy Date: Mon, 14 Apr 2025 15:49:17 +0300 Subject: [PATCH 3/4] Implemented propagation of false positives to all triage classes. --- donpapi/collectors/Certificates.py | 2 +- donpapi/collectors/Chromium.py | 2 +- donpapi/collectors/CredMan.py | 2 +- donpapi/collectors/MobaXTerm.py | 2 +- donpapi/collectors/RDCMan.py | 2 +- donpapi/collectors/Vaults.py | 2 +- donpapi/collectors/Wifi.py | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/donpapi/collectors/Certificates.py b/donpapi/collectors/Certificates.py index 9d19084..bc926f4 100644 --- a/donpapi/collectors/Certificates.py +++ b/donpapi/collectors/Certificates.py @@ -22,7 +22,7 @@ def __init__(self, target: Target, conn: DPLootSMBConnection, masterkeys: list, def run(self) -> None: self.logger.display(f"Dumping User{' and Machine' if self.context.remoteops_allowed else ''} Certificates") - certificates_triage = CertificatesTriage(target=self.target, conn=self.conn, masterkeys=self.masterkeys) + certificates_triage = CertificatesTriage(target=self.target, conn=self.conn, masterkeys=self.masterkeys, false_positive=self.false_positive) certificates = certificates_triage.triage_certificates() for certificate in certificates: cert_username = certificate.username.rstrip("\x00") diff --git a/donpapi/collectors/Chromium.py b/donpapi/collectors/Chromium.py index a906cc5..9be38f0 100644 --- a/donpapi/collectors/Chromium.py +++ b/donpapi/collectors/Chromium.py @@ -20,7 +20,7 @@ def __init__(self, target: Target, conn: DPLootSMBConnection, masterkeys: list, def run(self): self.logger.display("Dumping User Chromium Browsers") - browser_triage = BrowserTriage(target=self.target, conn=self.conn, masterkeys=self.masterkeys) + browser_triage = BrowserTriage(target=self.target, conn=self.conn, masterkeys=self.masterkeys, false_positive=self.false_positive) browser_credentials, cookies = browser_triage.triage_browsers(gather_cookies=True) for credential in browser_credentials: if isinstance(credential, LoginData): diff --git a/donpapi/collectors/CredMan.py b/donpapi/collectors/CredMan.py index 07b8736..3579d20 100644 --- a/donpapi/collectors/CredMan.py +++ b/donpapi/collectors/CredMan.py @@ -20,7 +20,7 @@ def __init__(self, target: Target, conn: DPLootSMBConnection, masterkeys: list, def run(self): self.logger.display(f"Dumping User{' and Machine' if self.context.remoteops_allowed else ''} Credential Manager") - credentials_triage = CredentialsTriage(target=self.target, conn=self.conn, masterkeys=self.masterkeys) + credentials_triage = CredentialsTriage(target=self.target, conn=self.conn, masterkeys=self.masterkeys, false_positive=self.false_positive) credentials = credentials_triage.triage_credentials() for credential in credentials: self.logger.secret(f"[{credential.winuser}] {credential.target} - {credential.username}:{credential.password}", self.tag) diff --git a/donpapi/collectors/MobaXTerm.py b/donpapi/collectors/MobaXTerm.py index 29328fa..69622fb 100644 --- a/donpapi/collectors/MobaXTerm.py +++ b/donpapi/collectors/MobaXTerm.py @@ -21,7 +21,7 @@ def __init__(self, target: Target, conn: DPLootSMBConnection, masterkeys: list, def run(self): if self.context.remoteops_allowed: self.logger.display("Dumping MobaXterm credentials") - mobaxterm_triage = MobaXtermTriage(target=self.target, conn=self.conn, masterkeys=self.masterkeys) + mobaxterm_triage = MobaXtermTriage(target=self.target, conn=self.conn, masterkeys=self.masterkeys, false_positive=self.false_positive) try: _, credentials = mobaxterm_triage.triage_mobaxterm() for credential in credentials: diff --git a/donpapi/collectors/RDCMan.py b/donpapi/collectors/RDCMan.py index 944cdf1..28f2171 100644 --- a/donpapi/collectors/RDCMan.py +++ b/donpapi/collectors/RDCMan.py @@ -20,7 +20,7 @@ def __init__(self, target: Target, conn: DPLootSMBConnection, masterkeys: list, def run(self): self.logger.display("Dumping User's RDCManager") - rdg_triage = RDGTriage(target=self.target, conn=self.conn, masterkeys=self.masterkeys) + rdg_triage = RDGTriage(target=self.target, conn=self.conn, masterkeys=self.masterkeys, false_positive=self.false_positive) rdcman_files, rdgfiles = rdg_triage.triage_rdcman() for rdcman_file in rdcman_files: if rdcman_file is None: diff --git a/donpapi/collectors/Vaults.py b/donpapi/collectors/Vaults.py index 80ff17b..602ee53 100644 --- a/donpapi/collectors/Vaults.py +++ b/donpapi/collectors/Vaults.py @@ -20,7 +20,7 @@ def __init__(self, target: Target, conn: DPLootSMBConnection, masterkeys: list, def run(self): self.logger.display(f"Dumping User{' and Machine' if self.context.remoteops_allowed else ''} Vaults") - vaults_triage = VaultsTriage(target=self.target, conn=self.conn, masterkeys=self.masterkeys) + vaults_triage = VaultsTriage(target=self.target, conn=self.conn, masterkeys=self.masterkeys, false_positive=self.false_positive) vaults = vaults_triage.triage_vaults() for vault in vaults: diff --git a/donpapi/collectors/Wifi.py b/donpapi/collectors/Wifi.py index b02cea3..aa00f76 100644 --- a/donpapi/collectors/Wifi.py +++ b/donpapi/collectors/Wifi.py @@ -23,7 +23,7 @@ def run(self): if self.context.remoteops_allowed: self.logger.display("Dumping Wifi profiles") try: - wifi_triage = WifiTriage(target=self.target, conn=self.conn, masterkeys=self.masterkeys) + wifi_triage = WifiTriage(target=self.target, conn=self.conn, masterkeys=self.masterkeys, false_positive=self.false_positive) wifi_creds = wifi_triage.triage_wifi() except Exception as e: self.logger.debug(f"Error while looting wifi: {e}") From b0a8544167d2a0d024f52749125373766196af0b Mon Sep 17 00:00:00 2001 From: covertivy Date: Mon, 14 Apr 2025 16:02:43 +0300 Subject: [PATCH 4/4] fix merge conflicts. --- pyproject.toml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index db75cbe..99e6703 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,13 +26,8 @@ donpapi = 'donpapi.entry:main' dpp = 'donpapi.entry:main' [tool.poetry.dependencies] -<<<<<<< HEAD -python = "^3.9" -impacket = "^0.12.0" -======= python = "^3.10.0" impacket = ">=0.12.0" ->>>>>>> 61db37aaea1e1c9e9b6a02c640bf59f2a20840bc dploot = "^3.1.2" rich = "^13.7.0" sqlalchemy = "^2.0.25"