Skip to content

Commit cbcdf3a

Browse files
authored
Merge pull request Pennyw0rth#599 from Pennyw0rth/regsecret
2 parents b520fdf + 1145cfe commit cbcdf3a

3 files changed

Lines changed: 50 additions & 25 deletions

File tree

nxc/protocols/smb.py

Lines changed: 46 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@
1313
LSASecrets,
1414
NTDSHashes,
1515
)
16+
from impacket.examples.regsecrets import (
17+
RemoteOperations as RegSecretsRemoteOperations,
18+
SAMHashes as RegSecretsSAMHashes,
19+
LSASecrets as RegSecretsLSASecrets
20+
)
1621
from impacket.nmb import NetBIOSError, NetBIOSTimeout
1722
from impacket.dcerpc.v5 import transport, lsat, lsad, scmr, rrp, srvs, wkst
1823
from impacket.dcerpc.v5.rpcrt import DCERPCException
@@ -1525,9 +1530,12 @@ def get_file(self):
15251530
for src, dest in self.args.get_file:
15261531
self.get_file_single(src, dest)
15271532

1528-
def enable_remoteops(self):
1533+
def enable_remoteops(self, regsecret=False):
15291534
try:
1530-
self.remote_ops = RemoteOperations(self.conn, self.kerberos, self.kdcHost)
1535+
if regsecret:
1536+
self.remote_ops = RegSecretsRemoteOperations(self.conn, self.kerberos, self.kdcHost)
1537+
else:
1538+
self.remote_ops = RemoteOperations(self.conn, self.kerberos, self.kdcHost)
15311539
self.remote_ops.enableRegistry()
15321540
if self.bootkey is None:
15331541
self.bootkey = self.remote_ops.getBootKey()
@@ -1537,7 +1545,7 @@ def enable_remoteops(self):
15371545
@requires_admin
15381546
def sam(self):
15391547
try:
1540-
self.enable_remoteops()
1548+
self.enable_remoteops(regsecret=(self.args.sam == "regdump"))
15411549
host_id = self.db.get_hosts(filter_term=self.host)[0][0]
15421550

15431551
def add_sam_hash(sam_hash, host_id):
@@ -1555,13 +1563,20 @@ def add_sam_hash(sam_hash, host_id):
15551563
add_sam_hash.sam_hashes = 0
15561564

15571565
if self.remote_ops and self.bootkey:
1558-
SAM_file_name = self.remote_ops.saveSAM()
1559-
SAM = SAMHashes(
1560-
SAM_file_name,
1561-
self.bootkey,
1562-
isRemote=True,
1563-
perSecretCallback=lambda secret: add_sam_hash(secret, host_id),
1564-
)
1566+
if self.args.sam == "regdump":
1567+
SAM = RegSecretsSAMHashes(
1568+
self.bootkey,
1569+
remoteOps=self.remote_ops,
1570+
perSecretCallback=lambda secret: add_sam_hash(secret, host_id),
1571+
)
1572+
else:
1573+
SAM_file_name = self.remote_ops.saveSAM()
1574+
SAM = SAMHashes(
1575+
SAM_file_name,
1576+
self.bootkey,
1577+
isRemote=True,
1578+
perSecretCallback=lambda secret: add_sam_hash(secret, host_id),
1579+
)
15651580

15661581
self.logger.display("Dumping SAM hashes")
15671582
SAM.dump()
@@ -1572,7 +1587,9 @@ def add_sam_hash(sam_hash, host_id):
15721587
self.remote_ops.finish()
15731588
except Exception as e:
15741589
self.logger.debug(f"Error calling remote_ops.finish(): {e}")
1575-
SAM.finish()
1590+
1591+
if self.args.sam == "secdump":
1592+
SAM.finish()
15761593
except SessionError as e:
15771594
if "STATUS_ACCESS_DENIED" in e.getErrorString():
15781595
self.logger.fail('Error "STATUS_ACCESS_DENIED" while dumping SAM. This is likely due to an endpoint protection.')
@@ -1789,7 +1806,7 @@ def firefox_callback(secret):
17891806
@requires_admin
17901807
def lsa(self):
17911808
try:
1792-
self.enable_remoteops()
1809+
self.enable_remoteops(regsecret=(self.args.lsa == "regdump"))
17931810

17941811
def add_lsa_secret(secret):
17951812
add_lsa_secret.secrets += 1
@@ -1808,14 +1825,21 @@ def add_lsa_secret(secret):
18081825
add_lsa_secret.secrets = 0
18091826

18101827
if self.remote_ops and self.bootkey:
1811-
SECURITYFileName = self.remote_ops.saveSECURITY()
1812-
LSA = LSASecrets(
1813-
SECURITYFileName,
1814-
self.bootkey,
1815-
self.remote_ops,
1816-
isRemote=True,
1817-
perSecretCallback=lambda secret_type, secret: add_lsa_secret(secret),
1818-
)
1828+
if self.args.lsa == "regdump":
1829+
LSA = RegSecretsLSASecrets(
1830+
self.bootkey,
1831+
self.remote_ops,
1832+
perSecretCallback=lambda secret_type, secret: add_lsa_secret(secret),
1833+
)
1834+
else:
1835+
SECURITYFileName = self.remote_ops.saveSECURITY()
1836+
LSA = LSASecrets(
1837+
SECURITYFileName,
1838+
self.bootkey,
1839+
self.remote_ops,
1840+
isRemote=True,
1841+
perSecretCallback=lambda secret_type, secret: add_lsa_secret(secret),
1842+
)
18191843
self.logger.success("Dumping LSA secrets")
18201844
LSA.dumpCachedHashes()
18211845
LSA.exportCached(self.output_filename)
@@ -1826,7 +1850,8 @@ def add_lsa_secret(secret):
18261850
self.remote_ops.finish()
18271851
except Exception as e:
18281852
self.logger.debug(f"Error calling remote_ops.finish(): {e}")
1829-
LSA.finish()
1853+
if self.args.lsa == "secdump":
1854+
LSA.finish()
18301855
except SessionError as e:
18311856
if "STATUS_ACCESS_DENIED" in e.getErrorString():
18321857
self.logger.fail('Error "STATUS_ACCESS_DENIED" while dumping LSA. This is likely due to an endpoint protection.')

nxc/protocols/smb/proto_args.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ def proto_args(parser, parents):
2525
self_delegate_arg.make_required = [delegate_arg]
2626

2727
cred_gathering_group = smb_parser.add_argument_group("Credential Gathering", "Options for gathering credentials")
28-
cred_gathering_group.add_argument("--sam", action="store_true", help="dump SAM hashes from target systems")
29-
cred_gathering_group.add_argument("--lsa", action="store_true", help="dump LSA secrets from target systems")
28+
cred_gathering_group.add_argument("--sam", choices={"regdump", "secdump"}, nargs="?", const="regdump", help="dump SAM hashes from target systems")
29+
cred_gathering_group.add_argument("--lsa", choices={"regdump", "secdump"}, nargs="?", const="regdump", help="dump LSA secrets from target systems")
3030
cred_gathering_group.add_argument("--ntds", choices={"vss", "drsuapi"}, nargs="?", const="drsuapi", help="dump the NTDS.dit from target DCs using the specifed method")
3131
cred_gathering_group.add_argument("--dpapi", choices={"cookies", "nosystem"}, nargs="*", help="dump DPAPI secrets from target systems, can dump cookies if you add 'cookies', will not dump SYSTEM dpapi if you add nosystem")
3232
cred_gathering_group.add_argument("--sccm", choices={"wmi", "disk"}, nargs="?", const="disk", help="dump SCCM secrets from target systems")

poetry.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)