@@ -14,14 +14,14 @@ class NXCModule:
1414 supported_protocols = ["smb" ]
1515 opsec_safe = True
1616 multiple_hosts = True
17- false_positive = ["." , ".." , "desktop.ini" , "Public" , "Default" , "Default User" , "All Users" , ".NET v4.5" , ".NET v4.5 Classic" ]
18- FILE_PATH_REGEX = r"^[A-Za-z]:\\(?:[^<>:\"/\\|?*]+\\)*[^<>:\"/\\|?*]+\.[\w]{1,5}$"
1917
2018 def __init__ (self , context = None ):
2119 self .context = context
20+ self .false_positive = ["." , ".." , "desktop.ini" , "Public" , "Default" , "Default User" , "All Users" , ".NET v4.5" , ".NET v4.5 Classic" ]
21+ self .FILE_PATH_REGEX = r"^[A-Za-z]:\\(?:[^<>:\"/\\|?*]+\\)*[^<>:\"/\\|?*]+\.[\w]{1,5}$"
2222
2323 def options (self , context , module_options ):
24- """"""
24+ """No options available. """
2525
2626 def extract_strings (self , data , min_length = 4 ):
2727 """Extract printable strings from binary data, similar to the strings command."""
@@ -100,61 +100,62 @@ def on_admin_login(self, context, connection):
100100 found = 0
101101 context .log .display ("Searching for Notepad cache..." )
102102 for directory in connection .conn .listPath ("C$" , "Users\\ *" ):
103- if directory .get_longname () not in self .false_positive and directory .is_directory ():
103+ if directory .get_longname () in self .false_positive or not directory .is_directory ():
104+ continue
104105
105- # Path for Windows Notepad tab state files
106- notepad_dir = f"Users\\ { directory .get_longname ()} \\ AppData\\ Local\\ Packages\\ Microsoft.WindowsNotepad_8wekyb3d8bbwe\\ LocalState\\ TabState\\ "
106+ # Path for Windows Notepad tab state files
107+ notepad_dir = f"Users\\ { directory .get_longname ()} \\ AppData\\ Local\\ Packages\\ Microsoft.WindowsNotepad_8wekyb3d8bbwe\\ LocalState\\ TabState\\ "
108+ try :
109+ if not connection .conn .listPath ("C$" , f"{ notepad_dir } \\ *" ):
110+ continue
107111 try :
108- if not connection .conn .listPath ("C$" , f"{ notepad_dir } \\ *" ):
109- continue
110- try :
111- for file in connection .conn .listPath ("C$" , f"{ notepad_dir } \\ *" ):
112- if file .get_longname () not in self .false_positive and file .get_longname ().endswith (".bin" ):
113- file_path = f"{ notepad_dir } { file .get_longname ()} "
114-
115- # Read the binary file
116- meaningful_strings = self .read_and_decode_file (connection , context , file_path , directory .get_longname ())
117-
118- if meaningful_strings :
119- found += 1
120- context .log .highlight (f"C:\\ { file_path } " )
121-
122- # Output content
123- content_lines = []
124-
125- # First loop to handle meaningful strings
126- for _ , string in meaningful_strings :
127- if bool (re .match (self .FILE_PATH_REGEX , string )): # Only needed if checking locally
128- # Read the file into a buffer
129- meaningful_strings = self .read_and_decode_file (connection , context , string [2 :], directory .get_longname ())
130-
131- # Second loop to handle content inside the file
132- for _ , string in meaningful_strings :
133- context .log .highlight (f"\t { string } " )
134- content_lines .append (string ) # Store the string value only
135- else :
112+ for file in connection .conn .listPath ("C$" , f"{ notepad_dir } \\ *" ):
113+ if file .get_longname () not in self .false_positive and file .get_longname ().endswith (".bin" ):
114+ file_path = f"{ notepad_dir } { file .get_longname ()} "
115+
116+ # Read the binary file
117+ meaningful_strings = self .read_and_decode_file (connection , context , file_path , directory .get_longname ())
118+
119+ if meaningful_strings :
120+ found += 1
121+ context .log .highlight (f"C:\\ { file_path } " )
122+
123+ # Output content
124+ content_lines = []
125+
126+ # First loop to handle meaningful strings
127+ for _ , string in meaningful_strings :
128+ if bool (re .match (self .FILE_PATH_REGEX , string )): # Only needed if checking locally
129+ # Read the file into a buffer
130+ meaningful_strings = self .read_and_decode_file (connection , context , string [2 :], directory .get_longname ())
131+
132+ # Second loop to handle content inside the file
133+ for _ , string in meaningful_strings :
136134 context .log .highlight (f"\t { string } " )
137135 content_lines .append (string ) # Store the string value only
136+ else :
137+ context .log .highlight (f"\t { string } " )
138+ content_lines .append (string ) # Store the string value only
139+
140+ # Save to file
141+ filename = f"{ connection .host } _{ directory .get_longname ()} _notepad_tabstate_{ found } .txt"
142+ export_path = join (NXC_PATH , "modules" , "notepad" )
143+ path = abspath (join (export_path , filename ))
144+ makedirs (export_path , exist_ok = True )
145+
146+ try :
147+ with open (path , "w+" ) as output_file :
148+ output_file .write (f"Source: C:\\ { file_path } \n \n " )
149+ output_file .write ("\n " .join (content_lines )) # Write strings line by line
150+ context .log .highlight (f"Notepad tab state content written to: { path } " )
151+ except Exception as e :
152+ context .log .fail (f"Failed to write Notepad tab state to { filename } : { e } " )
138153
139- # Save to file
140- filename = f"{ connection .host } _{ directory .get_longname ()} _notepad_tabstate_{ found } .txt"
141- export_path = join (NXC_PATH , "modules" , "notepad" )
142- path = abspath (join (export_path , filename ))
143- makedirs (export_path , exist_ok = True )
144-
145- try :
146- with open (path , "w+" ) as output_file :
147- output_file .write (f"Source: C:\\ { file_path } \n \n " )
148- output_file .write ("\n " .join (content_lines )) # Write strings line by line
149- context .log .highlight (f"Notepad tab state content written to: { path } " )
150- except Exception as e :
151- context .log .fail (f"Failed to write Notepad tab state to { filename } : { e } " )
152-
153- except Exception as e :
154- context .log .fail (f"Failed on connection and reading bin files: { e } " )
155- context .log .debug (f"Failed: { e } " )
156154 except Exception as e :
157- context .log .fail (f"{ directory .get_longname ()} User has no any notepad cache file" )
158- context .log .debug (f"Failed for user { directory .get_longname ()} : { e } " )
155+ context .log .fail (f"Failed on connection and reading bin files: { e } " )
156+ context .log .debug (f"Failed: { e } " )
157+ except Exception as e :
158+ context .log .fail (f"{ directory .get_longname ()} User has no any notepad cache file" )
159+ context .log .debug (f"Failed for user { directory .get_longname ()} : { e } " )
159160 if found == 0 :
160161 context .log .info ("No Notepad tab state files with meaningful content found" )
0 commit comments