skipped 11 lines 12 12 self.targets = targets 13 13 self.report_file = os.path.join(self.options.output_directory,'%s_result.html' % date.today().strftime("%d-%m-%Y")) 14 14 15 - def add_to_resultpage(self, datas): 15 + def add_to_resultpage(self, datas, report_file = " " ): 16 16 try: 17 + if report_file=="": 18 + report_file=self.report_file 17 19 datas = datas.encode('ascii', 'ignore') 18 - f = open(self . report_file, 'ab') 20 + f = open(report_file, 'ab') 19 21 f.write(datas) 20 22 f.close() 21 23 return True skipped 2 lines 24 26 self.logging.debug(ex) 25 27 return False 26 28 27 - def generate_report(self,type='', user='', target=''): 29 + def generate_report(self,type='', user='', target='',report_content=['credz','cookies','files','connected_user','hash_reuse','audited_scope','masterkeys'],credz_content=['wifi', 'taskscheduler', 'credential-blob', 'browser', 'sysadmin','SAM', 'LSA', 'DCC2'],report_file=""): 28 30 29 31 try: 30 32 my_path = os.path.dirname(os.path.realpath(__file__)) skipped 8 lines 39 41 self.logging.debug(f" Exception {bcolors.WARNING} in running Report {bcolors.ENDC}") 40 42 self.logging.debug(ex) 41 43 42 - self.logging.info("[+] Generating report") 44 + self.logging.info(f "[+] Generating report : { report_file } ") 43 45 if self.conn == None : 44 46 self.logging.debug(f"[+] db ERROR - {self.options.output_directory}") 45 47 return -1 46 48 47 49 try: 48 - if os.path.exists(os.path.join(self.options.output_directory,'%s_result.html' % date.today().strftime("%d-%m-%Y"))): 49 - if os . path .exists ( os.path.join(self.options.output_directory,'%s_result_old .html' % date.today().strftime("%d-%m-%Y"))) : 50 - os.remove(os.path.join(self.options.output_directory,'%s_result_old.html' % date.today().strftime("%d-%m-%Y"))) 51 - os.rename(os.path.join(self.options.output_directory,'%s_result.html' % date.today().strftime("%d-%m-%Y")), os.path.join(self.options.output_directory,'%s_result_old.html' % date.today().strftime("%d-%m-%Y"))) 52 - os.remove(os.path.join(os.path.join(self.options.output_directory,'%s_result.html' % date.today().strftime("%d-%m-%Y")))) 53 - self.report_file = os.path.join(self.options.output_directory,'%s_result.html' % date.today().strftime("%d-%m-%Y")) 50 + if report_file=="": 51 + self .report_file = os.path.join(self.options.output_directory,'%s_result .html' % date.today().strftime("%d-%m-%Y")) 52 + else: 53 + self.report_file=os.path.join(self.options.output_directory,report_file) 54 + if os.path.exists(self.report_file): 55 + if os.path.exists(self.report_file+"_old"): 56 + os.remove(self.report_file+"_old") 57 + os.rename(self.report_file, self.report_file+"_old") 58 + os.remove(self.report_file) 59 + 54 60 if not os.path.exists(os.path.join(self.options.output_directory,'res')): 55 61 os.mkdir(os.path.join(self.options.output_directory,'res')) 56 62 except Exception as ex: skipped 6 lines 63 69 myfile,myfilename=myfiles 64 70 if os.path.exists(myfile) and not os.path.exists(os.path.join(os.path.join(self.options.output_directory,'res'), myfilename)): 65 71 shutil.copy2(myfile, os.path.join(os.path.join(self.options.output_directory,'res'), myfilename)) 66 - else: 67 - self.logging.debug(f"{os.path.exists(myfile)} - {os.path.exists(os.path.join(os.path.join(self.options.output_directory,'res'), myfilename))}") 68 - 69 72 except Exception as ex: 70 73 self.logging.debug(f" Exception {bcolors.WARNING} in RES copy {bcolors.ENDC}") 71 74 self.logging.debug(ex) skipped 76 lines 148 151 """ 149 152 self.add_to_resultpage(data) 150 153 151 - results = self.get_credz() 154 + if 'credz' in report_content : 155 + results = self.get_credz() 156 + #popolute credz report filtering : 157 + if 'browser' in credz_content: 158 + credz_content.append('browser-internet_explorer') 159 + credz_content.append('browser-firefox') 160 + credz_content.append('browser-chrome') 161 + if 'sysadmin' in credz_content: 162 + credz_content.append('VNC') 163 + credz_content.append('MRemoteNG') 164 + #credz_content.append('VNC') 152 165 153 - data = """<table class="statistics"><TR> 154 - <Th><a class="firstletter">U</a><a>sername</A></Th> 155 - <Th><a class="firstletter">P</a><a>assword</A></Th> 156 - <Th><a class="firstletter">T</a><a>arget</A></Th> 157 - <Th><a class="firstletter">T</a><a>ype</A></Th> 158 - <Th><a class="firstletter">P</a><a>illaged_from_computerid</A></Th> 159 - <Th><a class="firstletter">P</a><a>illaged_from_userid</A></Th></TR>\n""" 166 + data = """<table class="statistics"><TR> 167 + <Th><a class="firstletter">U</a><a>sername</A></Th> 168 + <Th><a class="firstletter">P</a><a>assword</A></Th> 169 + <Th><a class="firstletter">T</a><a>arget</A></Th> 170 + <Th><a class="firstletter">T</a><a>ype</A></Th> 171 + <Th><a class="firstletter">P</a><a>illaged_from_computerid</A></Th> 172 + <Th><a class="firstletter">P</a><a>illaged_from_userid</A></Th></TR>\n""" 160 173 161 - #<a href="#" id="toggle" onClick="toggle_it('tr1');toggle_it('tr2')"> 162 - current_type='' 163 - for index,cred in enumerate(results): 164 - cred_id, file_path, username, password, target, type, pillaged_from_computerid, pillaged_from_userid = cred 165 - if type != current_type: 166 - current_type=type 167 - current_type_count=self.get_credz_count(current_type,'AND username NOT IN ("NL$KM_history") AND target NOT IN ("WindowsLive:target=virtualapp/didlogical","Adobe App Info","Adobe App Prefetched Info","Adobe User Info","Adobe User OS Info","MicrosoftOffice16_Data:ADAL","LegacyGeneric:target=msteams_adalsso/adal_contex")')[0][0] 168 - data += f"""<TR id={current_type}><TD colspan="6" class="toggle_menu" onClick="toggle_it('{current_type}')"><A>{current_type} ({current_type_count})</A></TD></TR>""" 174 + #<a href="#" id="toggle" onClick="toggle_it('tr1');toggle_it('tr2')"> 175 + current_type='' 176 + for index,cred in enumerate(results): 177 + cred_id, file_path, username, password, target, type, pillaged_from_computerid, pillaged_from_userid = cred 178 + #filtering data to be included in the report 179 + if type not in credz_content: 180 + continue 181 + if type != current_type: 182 + current_type=type 183 + current_type_count=self.get_credz_count(current_type,'AND username NOT IN ("NL$KM_history") AND target NOT IN ("WindowsLive:target=virtualapp/didlogical","Adobe App Info","Adobe App Prefetched Info","Adobe User Info","Adobe User OS Info","MicrosoftOffice16_Data:ADAL","LegacyGeneric:target=msteams_adalsso/adal_contex")')[0][0] 184 + data += f"""<TR id={current_type}><TD colspan="6" class="toggle_menu" onClick="toggle_it('{current_type}')"><A>{current_type} ({current_type_count})</A></TD></TR>""" 169 185 170 186 171 - #Skip infos of 172 - # WindowsLive:target=virtualapp/didlogical 173 - untreated_targets =["WindowsLive:target=virtualapp/didlogical","Adobe App Info","Adobe App Prefetched Info","Adobe User Info","Adobe User OS Info","MicrosoftOffice16_Data:ADAL","LegacyGeneric:target=msteams_adalsso/adal_contex"] 174 - untreated_users = ["NL$KM_history"] 187 + #Skip infos of 188 + # WindowsLive:target=virtualapp/didlogical 189 + untreated_targets =["WindowsLive:target=virtualapp/didlogical","Adobe App Info","Adobe App Prefetched Info","Adobe User Info","Adobe User OS Info","MicrosoftOffice16_Data:ADAL","LegacyGeneric:target=msteams_adalsso/adal_contex"] 190 + untreated_users = ["NL$KM_history"] 175 191 176 - blacklist_bypass=False 177 - for untreated in untreated_targets: 178 - if untreated in target: 179 - blacklist_bypass=True 180 - for untreated in untreated_users: 181 - if untreated in username: 182 - blacklist_bypass=True 183 - if blacklist_bypass: 184 - continue 192 + blacklist_bypass=False 193 + for untreated in untreated_targets: 194 + if untreated in target: 195 + blacklist_bypass=True 196 + for untreated in untreated_users: 197 + if untreated in username: 198 + blacklist_bypass=True 199 + if blacklist_bypass: 200 + continue 185 201 186 - #Get computer infos 187 - res=self.get_computer_infos(pillaged_from_computerid) 188 - for index_, res2 in enumerate(res): 189 - ip, hostname=res2 190 - computer_info=f"{ip} | {hostname}" 191 - #pillaged_from_userid 192 - if pillaged_from_userid != None: 193 - res=self.get_user_infos(pillaged_from_userid) 194 - for index_, pillaged_username in enumerate(res): 195 - pillaged_from_userid=pillaged_username[0] 196 - else: 197 - pillaged_from_userid=str(pillaged_from_userid) 202 + #Get computer infos 203 + res=self.get_computer_infos(pillaged_from_computerid) 204 + for index_, res2 in enumerate(res): 205 + ip, hostname=res2 206 + computer_info=f"{ip} | {hostname}" 207 + #pillaged_from_userid 208 + if pillaged_from_userid != None: 209 + res=self.get_user_infos(pillaged_from_userid) 210 + for index_, pillaged_username in enumerate(res): 211 + pillaged_from_userid=pillaged_username[0] 212 + else: 213 + pillaged_from_userid=str(pillaged_from_userid) 198 214 199 - if index % 2 == 0: 200 - data += f"""<TR class=tableau_resultat_row0 {current_type}=1>""" 201 - else: 202 - data += f"""<TR class=tableau_resultat_row1 {current_type}=1>""" 215 + if index % 2 == 0: 216 + data += f"""<TR class=tableau_resultat_row0 {current_type}=1>""" 217 + else: 218 + data += f"""<TR class=tableau_resultat_row1 {current_type}=1>""" 203 219 204 - if 'admin' in username.lower() : #Pour mettre des results en valeur 205 - special_style = '''class="cracked"''' 206 - else: 207 - special_style = "" 220 + if 'admin' in username.lower() : #Pour mettre des results en valeur 221 + special_style = '''class="cracked"''' 222 + else: 223 + special_style = "" 208 224 209 225 210 226 211 - ###Print block 212 - #Recup des username dans le target #/# a update dans myseatbelt.py pour faire une fonction dump_CREDENTIAL_XXXXX clean 213 - if "LegacyGeneric:target=MicrosoftOffice1" in target: 214 - username = f'''{target.split(':')[-1]}''' 215 - #Les pass LSA sont souvent en Hexa 216 - #if "LSA" in type: 217 - try: 218 - hex_passw='' 219 - hex_passw=binascii.unhexlify(password).replace(b'>',b'') 220 - except Exception as ex: 221 - #print(ex) 222 - pass 227 + ###Print block 228 + #Recup des username dans le target #/# a update dans myseatbelt.py pour faire une fonction dump_CREDENTIAL_XXXXX clean 229 + if "LegacyGeneric:target=MicrosoftOffice1" in target: 230 + username = f'''{target.split(':')[-1]}''' 231 + #Les pass LSA sont souvent en Hexa 232 + #if "LSA" in type: 233 + try: 234 + hex_passw='' 235 + hex_passw=binascii.unhexlify(password).replace(b'>',b'') 236 + except Exception as ex: 237 + #print(ex) 238 + pass 223 239 224 240 225 - for info in [username]: 226 - data += f"""<TD {special_style} ><A title="{info}"> {str(info)[:48]} </A></TD>""" 227 - for info in [password]: 228 - data += f"""<TD {special_style} ><A title="{hex_passw}"> {str(info)[:48]} </A></TD>""" 241 + for info in [username]: 242 + data += f"""<TD {special_style} ><A title="{info}"> {str(info)[:48]} </A></TD>""" 243 + for info in [password]: 244 + data += f"""<TD {special_style} ><A title="{hex_passw}"> {str(info)[:48]} </A></TD>""" 229 245 230 - #check if info contains a URL 231 - if 'http:' in target or 'https:' in target: 232 - info2 = target[target.index('http'):] 233 - special_ref = f'''href="{info2}" target="_blank" title="{target}"''' 234 - elif 'ftp:' in target: 235 - info2 = target[target.index('ftp'):] 236 - special_ref = f'''href="{info2}" target="_blank" title="{target}"''' 237 - elif "Domain:target=" in target: 238 - info2=f'''rdp://full%20address=s:{target[target.index('Domain:target=')+len('Domain:target='):]}:3389&username=s:{username}&audiomode=i:2&disable%20themes=i:1''' 239 - special_ref = f'''href="{info2}" title="{target}"''' 240 - elif "LegacyGeneric:target=MicrosoftOffice1" in target: 241 - target=f'''{target[target.index('LegacyGeneric:target=')+len('LegacyGeneric:target='):]}''' 242 - special_ref = f'''href="https://login.microsoftonline.com/" target="_blank" title="OfficeLogin"''' 243 - else: 244 - special_ref = f'''title="{target}"''' 245 - data += f"""<TD {special_style} ><A {special_ref}> {str(target)[:48]} </A></TD>""" 246 + #check if info contains a URL 247 + if 'http:' in target or 'https:' in target: 248 + info2 = target[target.index('http'):] 249 + special_ref = f'''href="{info2}" target="_blank" title="{target}"''' 250 + elif 'ftp:' in target: 251 + info2 = target[target.index('ftp'):] 252 + special_ref = f'''href="{info2}" target="_blank" title="{target}"''' 253 + elif "Domain:target=" in target: 254 + info2=f'''rdp://full%20address=s:{target[target.index('Domain:target=')+len('Domain:target='):]}:3389&username=s:{username}&audiomode=i:2&disable%20themes=i:1''' 255 + special_ref = f'''href="{info2}" title="{target}"''' 256 + elif "LegacyGeneric:target=MicrosoftOffice1" in target: 257 + target=f'''{target[target.index('LegacyGeneric:target=')+len('LegacyGeneric:target='):]}''' 258 + special_ref = f'''href="https://login.microsoftonline.com/" target="_blank" title="OfficeLogin"''' 259 + else: 260 + special_ref = f'''title="{target}"''' 261 + data += f"""<TD {special_style} ><A {special_ref}> {str(target)[:48]} </A></TD>""" 246 262 247 - for info in [type, computer_info, pillaged_from_userid]: 248 - data += f"""<TD {special_style} ><A title="{info}"> {str(info)[:48]} </A></TD>""" 249 - data+="""</TR>\n""" 263 + for info in [type, computer_info, pillaged_from_userid]: 264 + data += f"""<TD {special_style} ><A title="{info}"> {str(info)[:48]} </A></TD>""" 265 + data+="""</TR>\n""" 250 266 251 - data += """</TABLE><BR>""" 252 - self.add_to_resultpage(data) 253 - ### 267 + data += """</TABLE><BR>""" 268 + self.add_to_resultpage(data) 269 + ### 254 270 255 271 256 272 ##### List cookies 257 - results = self.get_cookies() 273 + if 'cookies' in report_content: 274 + results = self.get_cookies() 258 275 259 - data = """<table class="statistics"><TR> 260 - <Th><a class="firstletter">N</a><a>ame</A></Th> 261 - <Th><a class="firstletter">V</a><a>alue</A></Th> 262 - <Th><a class="firstletter">U</a><a>ntil</A></Th> 263 - <Th><a class="firstletter">T</a><a>arget</A></Th> 264 - <Th><a class="firstletter">T</a><a>ype</A></Th> 265 - <Th><a class="firstletter">P</a><a>illaged_from_computerid</A></Th> 266 - <Th><a class="firstletter">P</a><a>illaged_from_userid</A></Th></TR>\n""" 276 + data = """<table class="statistics"><TR> 277 + <Th><a class="firstletter">N</a><a>ame</A></Th> 278 + <Th><a class="firstletter">V</a><a>alue</A></Th> 279 + <Th><a class="firstletter">U</a><a>ntil</A></Th> 280 + <Th><a class="firstletter">T</a><a>arget</A></Th> 281 + <Th><a class="firstletter">T</a><a>ype</A></Th> 282 + <Th><a class="firstletter">P</a><a>illaged_from_computerid</A></Th> 283 + <Th><a class="firstletter">P</a><a>illaged_from_userid</A></Th></TR>\n""" 267 284 268 - # <a href="#" id="toggle" onClick="toggle_it('tr1');toggle_it('tr2')"> 269 - current_type = 'cookies' 270 - data += f"""<TR id=cookies><TD colspan="7" class="toggle_menu" onClick="toggle_it('cookies')"><A>Cookies ({len(results)})</A></TD></TR>""" 271 - for index, cred in enumerate(results): 272 - name,value,expires_utc,target,type,pillaged_from_computerid,pillaged_from_userid = cred 273 - # Skip infos of 274 - # Get computer infos 275 - res = self.get_computer_infos(pillaged_from_computerid) 276 - for index_, res2 in enumerate(res): 277 - ip, hostname = res2 278 - computer_info = f"{ip} | {hostname}" 279 - # pillaged_from_userid 280 - if pillaged_from_userid != None: 281 - res = self.get_user_infos(pillaged_from_userid) 282 - for index_, pillaged_username in enumerate(res): 283 - pillaged_from_userid = pillaged_username[0] 284 - else: 285 - pillaged_from_userid = str(pillaged_from_userid) 285 + # <a href="#" id="toggle" onClick="toggle_it('tr1');toggle_it('tr2')"> 286 + current_type = 'cookies' 287 + data += f"""<TR id=cookies><TD colspan="7" class="toggle_menu" onClick="toggle_it('cookies')"><A>Cookies ({len(results)})</A></TD></TR>""" 288 + for index, cred in enumerate(results): 289 + name,value,expires_utc,target,type,pillaged_from_computerid,pillaged_from_userid = cred 290 + # Skip infos of 291 + # Get computer infos 292 + res = self.get_computer_infos(pillaged_from_computerid) 293 + for index_, res2 in enumerate(res): 294 + ip, hostname = res2 295 + computer_info = f"{ip} | {hostname}" 296 + # pillaged_from_userid 297 + if pillaged_from_userid != None: 298 + res = self.get_user_infos(pillaged_from_userid) 299 + for index_, pillaged_username in enumerate(res): 300 + pillaged_from_userid = pillaged_username[0] 301 + else: 302 + pillaged_from_userid = str(pillaged_from_userid) 286 303 287 - if index % 2 == 0: 288 - data += f"""<TR class=tableau_resultat_row0 {current_type}=1>""" 289 - else: 290 - data += f"""<TR class=tableau_resultat_row1 {current_type}=1>""" 304 + if index % 2 == 0: 305 + data += f"""<TR class=tableau_resultat_row0 {current_type}=1>""" 306 + else: 307 + data += f"""<TR class=tableau_resultat_row1 {current_type}=1>""" 291 308 292 - special_style = "" 309 + special_style = "" 293 310 294 - ###Print block 295 - for info in [name,value]: 296 - data += f"""<TD {special_style} ><A title="{info}"> {str(info)[:48]} </A></TD>""" 297 - for info in [expires_utc]: #Formule a change si on intègre des cookies venant d'autre chose que chrome 298 - try: 299 - if type == "browser-chrome" : 300 - data += f"""<TD {special_style} ><A title="{info}"> {(datetime(1601, 1, 1) + timedelta(microseconds=info)).strftime('%b %d %Y %H:%M:%S')} </A></TD>""" 301 - else: 302 - data += f"""<TD {special_style} ><A title="{info}"> {(datetime.fromtimestamp(info)).strftime('%b %d %Y %H:%M:%S')} </A></TD>""" 303 - except: 304 - data += f"""<TD {special_style} ><A title="{info}"> {info} </A></TD>""" 311 + ###Print block 312 + for info in [name,value]: 313 + data += f"""<TD {special_style} ><A title="{info}"> {str(info)[:48]} </A></TD>""" 314 + for info in [expires_utc]: #Formule a change si on intègre des cookies venant d'autre chose que chrome 315 + try: 316 + if type == "browser-chrome" : 317 + data += f"""<TD {special_style} ><A title="{info}"> {(datetime(1601, 1, 1) + timedelta(microseconds=info)).strftime('%b %d %Y %H:%M:%S')} </A></TD>""" 318 + else: 319 + data += f"""<TD {special_style} ><A title="{info}"> {(datetime.fromtimestamp(info)).strftime('%b %d %Y %H:%M:%S')} </A></TD>""" 320 + except: 321 + data += f"""<TD {special_style} ><A title="{info}"> {info} </A></TD>""" 305 322 306 - # check if info contains a URL 307 - if 'http:' in target or 'https:' in target: 308 - info2 = target[target.index('http'):] 309 - special_ref = f'''href="{info2}" target="_blank" title="{target}"''' 310 - elif 'ftp:' in target: 311 - info2 = target[target.index('ftp'):] 312 - special_ref = f'''href="{info2}" target="_blank" title="{target}"''' 313 - elif "Domain:target=" in target: 314 - info2 = f'''rdp://full%20address=s:{target[target.index('Domain:target=') + len('Domain:target='):]}:3389&username=s:{username}&audiomode=i:2&disable%20themes=i:1''' 315 - special_ref = f'''href="{info2}" title="{target}"''' 316 - elif "LegacyGeneric:target=MicrosoftOffice1" in target: 317 - target = f'''{target[target.index('LegacyGeneric:target=') + len('LegacyGeneric:target='):]}''' 318 - special_ref = f'''href="https://login.microsoftonline.com/" target="_blank" title="OfficeLogin"''' 319 - else: 320 - special_ref = f'''title="{target}"''' 321 - data += f"""<TD {special_style} ><A {special_ref}> {str(target)[:48]} </A></TD>""" 323 + # check if info contains a URL 324 + if 'http:' in target or 'https:' in target: 325 + info2 = target[target.index('http'):] 326 + special_ref = f'''href="{info2}" target="_blank" title="{target}"''' 327 + elif 'ftp:' in target: 328 + info2 = target[target.index('ftp'):] 329 + special_ref = f'''href="{info2}" target="_blank" title="{target}"''' 330 + elif "Domain:target=" in target: 331 + info2 = f'''rdp://full%20address=s:{target[target.index('Domain:target=') + len('Domain:target='):]}:3389&username=s:{username}&audiomode=i:2&disable%20themes=i:1''' 332 + special_ref = f'''href="{info2}" title="{target}"''' 333 + elif "LegacyGeneric:target=MicrosoftOffice1" in target: 334 + target = f'''{target[target.index('LegacyGeneric:target=') + len('LegacyGeneric:target='):]}''' 335 + special_ref = f'''href="https://login.microsoftonline.com/" target="_blank" title="OfficeLogin"''' 336 + else: 337 + special_ref = f'''title="{target}"''' 338 + data += f"""<TD {special_style} ><A {special_ref}> {str(target)[:48]} </A></TD>""" 322 339 323 - for info in [type, computer_info, pillaged_from_userid]: 324 - data += f"""<TD {special_style} ><A title="{info}"> {str(info)[:48]} </A></TD>""" 325 - data += """</TR>\n""" 340 + for info in [type, computer_info, pillaged_from_userid]: 341 + data += f"""<TD {special_style} ><A title="{info}"> {str(info)[:48]} </A></TD>""" 342 + data += """</TR>\n""" 326 343 327 - data += """</TABLE><BR>""" 328 - self.add_to_resultpage(data) 344 + data += """</TABLE><BR>""" 345 + self.add_to_resultpage(data) 346 + 329 347 ##### List gathered files 330 - results = self.get_file() 348 + if 'files' in report_content: 349 + results = self.get_file() 331 350 332 - data = """<table class="statistics" id="Files"><TR><Th><a class="firstletter">F</a><a>ilename</A></Th> 333 - <Th><a class="firstletter">T</a><a>ype</A></Th> 334 - <Th><a class="firstletter">U</a><a>ser</A></Th> 335 - <Th><a class="firstletter">I</a><a>p</A></Th></TR>\n""" 336 - for index, myfile in enumerate(results): 337 - try: 338 - file_path, filename, extension, pillaged_from_computerid,pillaged_from_userid = myfile 339 - res = self.get_computer_infos(pillaged_from_computerid) 340 - for index, res2 in enumerate(res): 341 - ip, hostname = res2 342 - computer_info = f"{ip} | {hostname}" 343 - res = self.get_user_infos(pillaged_from_userid) 344 - for index, res2 in enumerate(res): 345 - username = res2[0] 346 - special_ref = f'''href="file://{file_path}" target="_blank" title="{filename}"''' 347 - data += f"""<TR><TD><A {special_ref}> {filename} </A></TD><TD> {extension} </TD><TD> {username} </TD><TD> {computer_info} </TD></TR>\n""" 348 - except Exception as ex: 349 - self.logging.debug(f" Exception {bcolors.WARNING} in getting File for {file_path} {bcolors.ENDC}") 350 - self.logging.debug(ex) 351 - return False 352 - data += """</TABLE><BR>""" 353 - self.add_to_resultpage(data) 351 + data = """<table class="statistics" id="Files"><TR><Th><a class="firstletter">F</a><a>ilename</A></Th> 352 + <Th><a class="firstletter">T</a><a>ype</A></Th> 353 + <Th><a class="firstletter">U</a><a>ser</A></Th> 354 + <Th><a class="firstletter">I</a><a>p</A></Th></TR>\n""" 355 + for index, myfile in enumerate(results): 356 + try: 357 + file_path, filename, extension, pillaged_from_computerid,pillaged_from_userid = myfile 358 + res = self.get_computer_infos(pillaged_from_computerid) 359 + for index, res2 in enumerate(res): 360 + ip, hostname = res2 361 + computer_info = f"{ip} | {hostname}" 362 + res = self.get_user_infos(pillaged_from_userid) 363 + for index, res2 in enumerate(res): 364 + username = res2[0] 365 + special_ref = f'''href="file://{file_path}" target="_blank" title="{filename}"''' 366 + data += f"""<TR><TD><A {special_ref}> {filename} </A></TD><TD> {extension} </TD><TD> {username} </TD><TD> {computer_info} </TD></TR>\n""" 367 + except Exception as ex: 368 + self.logging.debug(f" Exception {bcolors.WARNING} in getting File for {file_path} {bcolors.ENDC}") 369 + self.logging.debug(ex) 370 + return False 371 + data += """</TABLE><BR>""" 372 + self.add_to_resultpage(data) 354 373 355 374 ##### Identify user / IP relations 356 375 # Confirm audited scope : 357 - results = self.get_connected_user() 376 + if 'connected_user' in report_content: 377 + results = self.get_connected_user() 358 378 359 - data = """<table class="statistics" id="Connected-users"><TR><Th><a class="firstletter">U</a><a>sername</A></Th> 360 - <Th><a class="firstletter">I</a><a>P</A></Th></TR>\n""" 379 + data = """<table class="statistics" id="Connected-users"><TR><Th><a class="firstletter">U</a><a>sername</A></Th> 380 + <Th><a class="firstletter">I</a><a>P</A></Th></TR>\n""" 361 381 362 - for index, cred in enumerate(results): 363 - try: 364 - ip, username = cred 365 - data += """<TR><TD> %s </TD><TD> %s </TD></TR>\n""" % (username,ip) 366 - except Exception as ex: 367 - self.logging.debug(f" Exception {bcolors.WARNING} in Identify user / IP relations for {cred} {bcolors.ENDC}") 368 - self.logging.debug(ex) 369 - return False 370 - data += """</TABLE><BR>""" 371 - self.add_to_resultpage(data) 382 + for index, cred in enumerate(results): 383 + try: 384 + ip, username = cred 385 + data += """<TR><TD> %s </TD><TD> %s </TD></TR>\n""" % (username,ip) 386 + except Exception as ex: 387 + self.logging.debug(f" Exception {bcolors.WARNING} in Identify user / IP relations for {cred} {bcolors.ENDC}") 388 + self.logging.debug(ex) 389 + return False 390 + data += """</TABLE><BR>""" 391 + self.add_to_resultpage(data) 372 392 373 393 374 394 ##### Identify Local hash reuse 375 - results = self.get_credz_sam() 376 - data = """<table class="statistics" id="Local_account_reuse"><TR><Th><a class="firstletter">L</a><a>ocal account reuse : </Th></TR>\n""" 377 - for index, cred in enumerate(results): 378 - username, password, type, pillaged_from_computerid = cred 379 - res = self.get_computer_infos(pillaged_from_computerid) 380 - for index, res2 in enumerate(res): 381 - ip, hostname = res2 382 - computer_info = f"{ip} | {hostname}" 383 - data += """<TR><TD> %s </TD><TD> %s </TD><TD> %s </TD><TD> %s </TD></TR>\n""" % (username, password, type, computer_info) 384 - data += """</TABLE><BR>""" 385 - self.add_to_resultpage(data) 395 + if 'hash_reuse' in report_content: 396 + results = self.get_credz_sam() 397 + data = """<table class="statistics" id="Local_account_reuse"><TR><Th><a class="firstletter">L</a><a>ocal account reuse : </Th></TR>\n""" 398 + for index, cred in enumerate(results): 399 + username, password, type, pillaged_from_computerid = cred 400 + res = self.get_computer_infos(pillaged_from_computerid) 401 + for index, res2 in enumerate(res): 402 + ip, hostname = res2 403 + computer_info = f"{ip} | {hostname}" 404 + data += """<TR><TD> %s </TD><TD> %s </TD><TD> %s </TD><TD> %s </TD></TR>\n""" % (username, password, type, computer_info) 405 + data += """</TABLE><BR>""" 406 + self.add_to_resultpage(data) 386 407 387 408 388 409 # Confirm audited scope : 389 - results = self.get_computers() 390 - data = """<table class="statistics" id="Scope_Audited"><TR><Th><a class="firstletter">S</a><a>cope Audited : </Th></TR>\n""" 391 - data + = """<TR><Th><a class="firstletter">I </a><a>p </A ></Th > 392 - <Th><a class="firstletter">H </a><a>ostname </A></Th> 393 - <Th><a class="firstletter">D </a><a>omain </A></Th> 394 - <Th><a class="firstletter">O </a><a>S </A></Th> 395 - <Th><a class="firstletter">S </a><a>mb signing enabled </A></Th> 396 - <Th><a class="firstletter">S</a><a>mb v1 </A></Th> 397 - <Th><a class="firstletter">I </a><a>s Admin </A></Th> 398 - <Th><a class="firstletter">C </a><a>onnectivity </A></Th> 399 - </TR>\n""" 410 + if 'audited_scope' in report_content: 411 + results = self.get_computers() 412 + data = """<table class = " statistics " id = " Scope_Audited " > < TR><Th><a class="firstletter">S </a><a>cope Audited : </Th ></TR >\ n " " " 413 + data + = " " " < TR > <Th><a class="firstletter">I </a><a>p </A></Th> 414 + <Th><a class="firstletter">H </a><a>ostname </A></Th> 415 + <Th><a class="firstletter">D </a><a>omain </A></Th> 416 + <Th><a class="firstletter">O </a><a>S </A></Th> 417 + <Th><a class="firstletter">S</a><a>mb signing enabled </A></Th> 418 + <Th><a class="firstletter">S </a><a>mb v1 </A></Th> 419 + <Th><a class="firstletter">I </a><a>s Admin </A></Th> 420 + <Th><a class="firstletter">C</a><a>onnectivity</A></Th> 421 + </TR>\n""" 400 422 401 - for index, cred in enumerate(results): 402 - ip, hostname, domain, my_os, smb_signing_enabled,smbv1_enabled,is_admin,connectivity = cred 403 - data+="<TR>" 404 - for info in [ip, hostname, domain, my_os]: 405 - data += f"""<TD> {info} </TD>""" 406 - if smb_signing_enabled: 407 - data+="<TD> Ok </TD>" 408 - else: 409 - data += """<TD><a class="firstletter"> NOT required </A></TD>""" 410 - if smbv1_enabled: 411 - data+="<TD> Yes </TD>" 412 - else: 413 - data += "<TD> No </TD>" 414 - if is_admin: 415 - data+="""<TD> Admin </A></TD>""" 416 - else: 417 - data += """<TD><a class="firstletter"> No </A></TD>""" 418 - for info in [connectivity]: 419 - data += f"""<TD> {info} </TD>""" 420 - data+="</TR>\n" 421 - data += """</TABLE><BR>\n""" 422 - self.add_to_resultpage(data) 423 + for index, cred in enumerate(results): 424 + ip, hostname, domain, my_os, smb_signing_enabled,smbv1_enabled,is_admin,connectivity = cred 425 + data+="<TR>" 426 + for info in [ip, hostname, domain, my_os]: 427 + data += f"""<TD> {info} </TD>""" 428 + if smb_signing_enabled: 429 + data+="<TD> Ok </TD>" 430 + else: 431 + data += """<TD><a class="firstletter"> NOT required </A></TD>""" 432 + if smbv1_enabled: 433 + data+="<TD> Yes </TD>" 434 + else: 435 + data += "<TD> No </TD>" 436 + if is_admin: 437 + data+="""<TD> Admin </A></TD>""" 438 + else: 439 + data += """<TD><a class="firstletter"> No </A></TD>""" 440 + for info in [connectivity]: 441 + data += f"""<TD> {info} </TD>""" 442 + data+="</TR>\n" 443 + data += """</TABLE><BR>\n""" 444 + self.add_to_resultpage(data) 423 445 424 446 #Etat des masterkeyz 425 - if self.options.debug : 447 + if self.options.debug and ' masterkeys ' in report_content : 426 448 results=self.get_masterkeys() 427 449 data = """<table class="statistics" id="Scope_Audited"><TR><Th><a class="firstletter">M</a><a>asterkeys : </Th></TR>\n""" 428 450 data += """<TR><Th><a class="firstletter">G</a><a>uid</A></Th> skipped 1304 lines