@@ -28,70 +28,78 @@ def on_admin_login(self, context, connection):
2828 remote_ops .enableRegistry ()
2929
3030 for sid_directory in connection .conn .listPath ("C$" , "$Recycle.Bin\\ *" ):
31- if sid_directory .get_longname () and sid_directory .get_longname () not in self .false_positive :
31+ try :
32+ if sid_directory .get_longname () and sid_directory .get_longname () not in self .false_positive :
3233
33- # Extracts the username from the SID
34- reg_handle = rrp .hOpenLocalMachine (remote_ops ._RemoteOperations__rrp )["phKey" ]
35- key_handle = rrp .hBaseRegOpenKey (remote_ops ._RemoteOperations__rrp , reg_handle , f"SOFTWARE\\ Microsoft\\ Windows NT\\ CurrentVersion\\ ProfileList\\ { sid_directory .get_longname ()} " )["phkResult" ]
36- username = profileimagepath = None
37- try :
38- _ , profileimagepath = rrp .hBaseRegQueryValue (remote_ops ._RemoteOperations__rrp , key_handle , "ProfileImagePath\x00 " )
39- # Get username and remove embedded null byte
40- username = profileimagepath .split ("\\ " )[- 1 ].replace ("\x00 " , "" )
41- except rrp .DCERPCSessionError as e :
42- context .log .debug (f"Couldn't get username from SID { e } on host { connection .host } " )
34+ # Extracts the username from the SID
35+ reg_handle = rrp .hOpenLocalMachine (remote_ops ._RemoteOperations__rrp )["phKey" ]
36+ key_handle = rrp .hBaseRegOpenKey (remote_ops ._RemoteOperations__rrp , reg_handle , f"SOFTWARE\\ Microsoft\\ Windows NT\\ CurrentVersion\\ ProfileList\\ { sid_directory .get_longname ()} " )["phkResult" ]
37+ username = profileimagepath = None
38+ try :
39+ _ , profileimagepath = rrp .hBaseRegQueryValue (remote_ops ._RemoteOperations__rrp , key_handle , "ProfileImagePath\x00 " )
40+ # Get username and remove embedded null byte
41+ username = profileimagepath .split ("\\ " )[- 1 ].replace ("\x00 " , "" )
42+ except rrp .DCERPCSessionError as e :
43+ context .log .debug (f"Couldn't get username from SID { e } on host { connection .host } " )
4344
44- # Lists for any file or directory in the recycle bin
45- spider_folder = f"$Recycle.Bin\\ { sid_directory .get_longname ()} \\ "
46- paths = connection .spider (
47- "C$" ,
48- folder = spider_folder ,
49- regex = [r"(.*)" ],
50- no_print_results = True
51- )
45+ # Lists for any file or directory in the recycle bin
46+ spider_folder = f"$Recycle.Bin\\ { sid_directory .get_longname ()} \\ "
47+ paths = connection .spider (
48+ "C$" ,
49+ folder = spider_folder ,
50+ regex = [r"(.*)" ],
51+ no_print_results = True
52+ )
5253
53- false_positiv = ("." , ".." , "desktop.ini" )
54- filtered_file_paths = [path for path in paths if not path .endswith (false_positiv )]
55- if filtered_file_paths :
56- if username is not None :
57- context .log .highlight (f"CONTENT FOUND { sid_directory .get_longname ()} ({ username } )" )
58- else :
59- context .log .highlight (f"CONTENT FOUND { sid_directory .get_longname ()} " )
54+ false_positiv = ("." , ".." , "desktop.ini" )
55+ filtered_file_paths = [path for path in paths if not path .endswith (false_positiv )]
56+ if filtered_file_paths :
57+ if username is not None :
58+ context .log .highlight (f"CONTENT FOUND { sid_directory .get_longname ()} ({ username } )" )
59+ else :
60+ context .log .highlight (f"CONTENT FOUND { sid_directory .get_longname ()} " )
6061
61- for path in filtered_file_paths :
62- # Returned path look like:
63- # $Recycle.Bin\S-1-5-21-4140170355-2927207985-2497279808-500\/$I87021Q.txt
64- # Or
65- # $Recycle.Bin\S-1-5-21-4140170355-2927207985-2497279808-500\/$R87021Q.txt
66- # $I files are metadata while $R are actual files so we split the path from the SID
67- # And check that the filename contains $R only to prevent downloading useless stuff
62+ for path in filtered_file_paths :
63+ # Returned path look like:
64+ # $Recycle.Bin\S-1-5-21-4140170355-2927207985-2497279808-500\/$I87021Q.txt
65+ # Or
66+ # $Recycle.Bin\S-1-5-21-4140170355-2927207985-2497279808-500\/$R87021Q.txt
67+ # $I files are metadata while $R are actual files so we split the path from the SID
68+ # And check that the filename contains $R only to prevent downloading useless stuff
6869
69- if "$R" in path .split (sid_directory .get_longname ())[1 ] and not path .endswith (false_positiv ):
70- try :
71- buf = BytesIO ()
72- connection .conn .getFile ("C$" , path , buf .write )
73- context .log .highlight (f"\t { path } " )
74- found += 1
75- buf .seek (0 )
76- file_path = path .split ("$" )[- 1 ].replace ("/" , "_" )
77- if username : # noqa: SIM108
78- filename = f"{ connection .host } _{ username } _recyclebin_{ file_path } "
79- else :
80- filename = f"{ connection .host } _{ sid_directory .get_longname ()} _recyclebin_{ file_path } "
81- export_path = join (NXC_PATH , "modules" , "recyclebin" )
82- path = abspath (join (export_path , filename ))
83- makedirs (export_path , exist_ok = True )
70+ if "$R" in path .split (sid_directory .get_longname ())[1 ] and not path .endswith (false_positiv ):
8471 try :
85- with open (path , "w+" ) as file :
86- file .write (buf .read ().decode ("utf-8" , errors = "ignore" ))
72+ buf = BytesIO ()
73+ connection .conn .getFile ("C$" , path , buf .write )
74+ context .log .highlight (f"\t { path } " )
75+ found += 1
76+ buf .seek (0 )
77+ file_path = path .split ("$" )[- 1 ].replace ("/" , "_" )
78+ if username : # noqa: SIM108
79+ filename = f"{ connection .host } _{ username } _recyclebin_{ file_path } "
80+ else :
81+ filename = f"{ connection .host } _{ sid_directory .get_longname ()} _recyclebin_{ file_path } "
82+ export_path = join (NXC_PATH , "modules" , "recyclebin" )
83+ path = abspath (join (export_path , filename ))
84+ makedirs (export_path , exist_ok = True )
85+ try :
86+ with open (path , "w+" ) as file :
87+ file .write (buf .read ().decode ("utf-8" , errors = "ignore" ))
88+ except Exception as e :
89+ context .log .fail (f"Failed to write recyclebin file to { filename } : { e } " )
8790 except Exception as e :
88- context .log .fail (f"Failed to write recyclebin file to { filename } : { e } " )
89- except Exception as e :
90- # Probably trying to getFile a directory which won't work
91- context .log .debug (f"Couldn't open { path } because of { e } " )
91+ # Probably trying to getFile a directory which won't work
92+ context .log .debug (f"Couldn't open { path } because of { e } " )
93+ except DCERPCSessionError as e :
94+ if "ERROR_FILE_NOT_FOUND" in str (e ):
95+ continue
96+ else :
97+ context .log .fail (f"Error opening { sid_directory .get_longname ()} on host { connection .host } because of { e } " )
98+ continue
9299 if found > 0 :
93100 context .log .highlight (f"Recycle bin's content downloaded to { export_path } " )
94101 except DCERPCSessionError as e :
102+ context .log .exception (e )
95103 context .log .fail (f"Error connecting to RemoteRegistry { e } on host { connection .host } " )
96104 finally :
97105 remote_ops .finish ()
0 commit comments