skipped 163 lines 164 164 cred_id, file_path, username, password, target, type, pillaged_from_computerid, pillaged_from_userid = cred 165 165 if type != current_type: 166 166 current_type=type 167 - current_type_count=self.get_credz_count(current_type)[0][0] 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 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>""" 169 169 170 170 skipped 80 lines 251 251 data += """</TABLE><BR>""" 252 252 self.add_to_resultpage(data) 253 253 ### 254 + 255 + 254 256 ##### List cookies 255 257 results = self.get_cookies() 256 258 skipped 2 lines 259 261 <Th><a class="firstletter">V</a><a>alue</A></Th> 260 262 <Th><a class="firstletter">U</a><a>ntil</A></Th> 261 263 <Th><a class="firstletter">T</a><a>arget</A></Th> 264 + <Th><a class="firstletter">T</a><a>ype</A></Th> 262 265 <Th><a class="firstletter">P</a><a>illaged_from_computerid</A></Th> 263 266 <Th><a class="firstletter">P</a><a>illaged_from_userid</A></Th></TR>\n""" 264 267 265 268 # <a href="#" id="toggle" onClick="toggle_it('tr1');toggle_it('tr2')"> 266 269 current_type = 'cookies' 267 - data += f"""<TR id=cookies><TD colspan="6 " class="toggle_menu" onClick="toggle_it('cookies')"><A>Cookies ({len(results)})</A></TD></TR>""" 270 + data += f"""<TR id=cookies><TD colspan="7 " class="toggle_menu" onClick="toggle_it('cookies')"><A>Cookies ({len(results)})</A></TD></TR>""" 268 271 for index, cred in enumerate(results): 269 272 name,value,expires_utc,target,type,pillaged_from_computerid,pillaged_from_userid = cred 270 273 # Skip infos of skipped 20 lines 291 294 ###Print block 292 295 for info in [name,value]: 293 296 data += f"""<TD {special_style} ><A title="{info}"> {str(info)[:48]} </A></TD>""" 294 - for info in [expires_utc]: 295 - data += f"""<TD {special_style} ><A title="{info}"> {(datetime(1601, 1, 1) + timedelta(microseconds=info)).strftime('%b %d %Y %H:%M:%S')} </A></TD>""" 297 + for info in [expires_utc]: #Formule a change si on intègre des cookies venant d'autre chose que chrome 298 + if type == "browser-chrome" : 299 + data += f"""<TD {special_style} ><A title="{info}"> {(datetime(1601, 1, 1) + timedelta(microseconds=info)).strftime('%b %d %Y %H:%M:%S')} </A></TD>""" 300 + else: 301 + data += f"""<TD {special_style} ><A title="{info}"> {(datetime.fromtimestamp(info)).strftime('%b %d %Y %H:%M:%S')} </A></TD>""" 296 302 297 303 # check if info contains a URL 298 304 if 'http:' in target or 'https:' in target: skipped 230 lines 529 535 self.logging.debug(ex) 530 536 self.logging.debug(f"Export Done!") 531 537 532 - def get_credz_count(self,current_type): 538 + def export_credz(self,distinct=True): 539 + user_credz=self.get_credz(distinct=True) 540 + filename = os.path.join(self.options.output_directory, 'raw_credz') 541 + self.logging.info(f"Exporting {len(user_credz)} credz to {self.options.output_directory}") 542 + if os.path.exists(filename): 543 + os.remove(filename) 544 + for index, cred in enumerate(user_credz): 545 + username, password = cred 546 + try: 547 + f=open(filename,'ab') 548 + f.write(f"{username}:{password}\n".encode('utf-8')) 549 + f.close() 550 + except Exception as ex: 551 + self.logging.error(f"Exception in export raw credz to {filename}") 552 + self.logging.debug(ex) 553 + self.logging.debug(f"Export Done!") 554 + 555 + def export_cookies(self): 556 + user_credz=self.get_cookies() 557 + filename = os.path.join(self.options.output_directory, 'raw_cookies') 558 + self.logging.info(f"Exporting {len(user_credz)} cookies to {self.options.output_directory}") 559 + if os.path.exists(filename): 560 + os.remove(filename) 561 + for index, cred in enumerate(user_credz): 562 + name, value, expires_utc, target, type, pillaged_from_computerid, pillaged_from_userid = cred 563 + try: 564 + f=open(filename,'ab') 565 + f.write(f"{target}:{name}:{value}\n".encode('utf-8')) 566 + f.close() 567 + except Exception as ex: 568 + self.logging.error(f"Exception in export raw credz to {filename}") 569 + self.logging.debug(ex) 570 + self.logging.debug(f"Export Done!") 571 + 572 + def get_credz_count(self,current_type,extra_conditions=''): 533 573 with self.conn: 534 574 cur = self.conn.cursor() 535 - cur.execute(f"SELECT count(id) FROM credz WHERE LOWER(type)=LOWER('{current_type}')") 575 + cur.execute(f"SELECT count(id) FROM credz WHERE LOWER(type)=LOWER('{current_type}') { extra_conditions } ") 536 576 results = cur.fetchall() 537 577 return results 538 578 539 - def get_credz(self, filterTerm=None, credz_type=None): 579 + def get_credz(self, filterTerm=None, credz_type=None, distinct = False ): 540 580 """ 541 581 Return credentials from the database. 542 582 """ skipped 7 lines 550 590 with self.conn: 551 591 cur = self.conn.cursor() 552 592 cur.execute("SELECT * FROM users WHERE LOWER(username) LIKE LOWER(?)", ['%{}%'.format(filterTerm)]) 553 - 593 + elif distinct : 594 + with self.conn: 595 + cur = self.conn.cursor() 596 + cur.execute("SELECT DISTINCT username,password FROM credz WHERE LOWER(type) NOT IN ('sam','lsa','dcc2') AND password NOT IN ('')") 554 597 # otherwise return all credentials 555 598 else: 556 599 with self.conn: skipped 83 lines 640 683 cur.execute(f"SELECT name,value,expires_utc,target,type,pillaged_from_computerid,pillaged_from_userid FROM cookies ORDER BY pillaged_from_computerid ASC, expires_utc DESC ") 641 684 results = cur.fetchall() 642 685 return results 686 + 643 687 class database: 644 688 645 689 def __init__(self, conn,logger): skipped 1019 lines