def RdpAnalysis(self): RdpAllEvent = 0 RowCount = 0 Rdppath = "C:\Windows\System32\winevt\Logs\Microsoft-Windows-TerminalServices-RemoteConnectionManager%4Operational.evtx" with evtx.Evtx(Rdppath) as log: for _ in log.records(): RdpAllEvent += 1 soup = BeautifulSoup(_.xml(), "lxml") System_ = soup.find("system") EventId = int(System_.find("eventid").text) if EventId == 1149: RowCount += 1 self.tableWidgetRdp.setRowCount(RowCount) self.tableWidgetRdp.setColumnCount(4) with evtx.Evtx(Rdppath) as log: EventCounter = 0 for x in range(1, RdpAllEvent + 1): try: CurrentProg = "%d" % int((x / RdpAllEvent) * 100) print(CurrentProg) self.progress.setValue(int(CurrentProg)) getone = log.get_record(x) soup = BeautifulSoup(getone.xml(), "lxml") System_ = soup.find("system") EventId = int(System_.find("eventid").text) UserData = soup.find("userdata") if EventId == 1149: TimeCreated = System_.find("timecreated").get( "systemtime") CondenseTime = str(transtime( TimeCreated.split('.')[0])) UserName = UserData.find("param1").text UserPcName = UserData.find("param2").text AccessIP = UserData.find("param3").text RdpTempList = [ CondenseTime, UserName, UserPcName, AccessIP ] for floop, sloop in zip(range(0, len(RdpTempList)), RdpTempList): self.tableWidgetRdp.setColumnWidth(floop, 200) self.tableWidgetRdp.setItem( EventCounter, floop, QTableWidgetItem(sloop)) EventCounter += 1 except UnicodeDecodeError: pass self.tableWidgetRdp.show() print("[+] RDP Analysis Done !")
def getUSBlog(evtxfile): os.mkdir('result') result = open('./result/usb_eventlog.csv', 'w') result.write('EventID,Time,Event,Product,SerialNum,lifetime\n') vendor, product, revision, serialNum, lifetime = "", "", "", "", "" with evtx.Evtx(evtxfile) as log: for record in log.records(): preRecord = record.xml() preTime = getEvtTime(preRecord) break count = 0 print("\n\n[+] Processing...\n") with evtx.Evtx(evtxfile) as log: for record in log.records(): xmlstr = record.xml() evtid = int(getEvtID(xmlstr)) evtTime = getEvtTime(xmlstr) if preTime == evtTime: count += 1 else: if count == 25 and preTime != evtTime: state = "Mounted" result.write( str(evtid) + "," + evtTime + "," + state + "," + product + "," + serialNum + "," + lifetime + "\n") elif count == 8 and preTime != evtTime: state = "Unmounted" result.write( str(evtid) + "," + evtTime + "," + state + "," + product + "," + serialNum + "," + lifetime + "\n") count = 1 offset = xmlstr.find("DISK&") if offset > 0: tmpOffset = xmlstr.find("lifetime") - 3 tmp = xmlstr[offset:tmpOffset] startOffset = tmp.find("VEN_") + 4 endOffset = tmp.find("&PROD") vendor = tmp[startOffset:endOffset] startOffset = tmp.find("PROD_") + 5 endOffset = tmp.find("&REV") product = tmp[startOffset:endOffset] startOffset = tmp.find("#") + 1 endOffset = startOffset + tmp[startOffset:].find("&") serialNum = tmp[startOffset:endOffset] offset = xmlstr.find("lifetime") if offset > 0: tmpOffset = xmlstr.find("xmlns:auto") tmp = xmlstr[offset:tmpOffset] startOffset = tmp.find("=\"{") + 2 endOffset = tmp.find("}") + 1 lifetime = tmp[startOffset:endOffset] preRecord = record.xml() preTime = getEvtTime(preRecord) result.close() print("\n[+] Completed!\n")
def main(inputfile, output): print(inputfile, output) outputfile = open(output, "w") outputfile.write("Date & Time,Event,User name,IP Address,Computer") Event_Desc = { '21': 'Session Connected', '22': 'Shell Notification Started', '24': 'Session Disconnected', '25': 'Session Reconnected' } with evtx.Evtx(inputfile) as log: for record in log.records(): root = ET.fromstring(record.xml()) if root[0][1].text in ['21', '24', '25']: if root[1][0][2].text != 'LOCAL': outputfile.write("\n") dt = parse(root[0][7].attrib['SystemTime']).strftime( '%Y-%m-%d %H:%M:%S %Z%z') eventd = Event_Desc[str(root[0][1].text)] outputfile.write(dt + "," + eventd + "," + root[1][0][0].text + "," + root[1][0][2].text + "," + root[0][12].text) print('-' * 5 + "Entry " + '-' * 5) print('Date/Time - ', dt) print('Event - ', eventd) print('User name - ', root[1][0][0].text) print('IP Address - ', root[1][0][2].text) print('Computer - ', root[0][12].text)
def dump(_path): with evtx.Evtx(_path) as log: print(e_views.XML_HEADER) print("<Events>") for record in log.records(): print(record.xml()) print("</Events>")
def Magic(): import argparse ps_scripts_ran = [] parser = argparse.ArgumentParser() parser.add_argument("evtx", type=str) args = parser.parse_args() with evtx.Evtx(args.evtx) as log: for each in log.records(): elm = each.lxml() R_ID = (elm.xpath("//event:EventID", namespaces={"event": schema})[0].text) Sour = (elm.xpath("//event:Channel", namespaces={"event": schema})[0].text) ctime = (elm.xpath("//event:TimeCreated", namespaces={"event": schema})[0].get("SystemTime")) User = (elm.xpath("//event:Security", namespaces={"event": schema})[0].get("UserID")) path = (elm.xpath( "//EventData:Data[@Name='ScriptBlockText']/text()", namespaces={"EventData": schema})) exists = False for item in ps_scripts_ran: if item[4] == path: exists = True if not exists: ps_scripts_ran.append([ R_ID, Sour, str(ctime).replace(" ", " T") + "Z", User, path ]) return ps_scripts_ran
def main(): if (len(sys.argv) != 2): print("\033[31m[-]\033[0m Invalid number of arguments!") print(" \033[33mpython3 malicious-pwsh.py <file.evtx>\033[0m") exit(1) print("\033[32mConverting " + sys.argv[1] + " to XML... \033[0m") # Partial code from evtx_dump.py with evtx.Evtx(sys.argv[1]) as log: xmlevents = "<Events>" for record in log.records(): xmlevents += (record.xml()) xmlevents += "</Events>" print("\033[32mRunning freq.py... \033[0m") dictevents = xmltodict.parse(xmlevents) for event in dictevents['Events']['Event']: if event['System']['EventID']['#text'] == "4103": eventdata = (event['EventData']['Data'][0]['#text']) score = subprocess.check_output("./freq.py -m \"" + eventdata + "\" english_mixedcase.freq", shell=True) if (float(score) < 5.0): print("\033[31m[-]\033[0m Likely obfuscated PowerShell!") print(" Freq.py score: \033[31m" + score.decode("utf-8") + "\033[0m") if len(eventdata) > 300: eventdata = eventdata[0:299] + "..." print(eventdata + "\n")
def process_file(file_location): results_list = [] with evtx.Evtx(file_location) as log: for record in log.records(): results_list.append(dict(xmltodict.parse(record.xml()))) return results_list
def main(): if len(sys.argv) != 2: usage() elif sys.argv[1] == 'h': # If too many arguments or 'h' is used call usage usage() args = sys.argv[1] winlog = open('win_eventlog.xml', 'w') # Prepair output file x = 'Script ran on: ' + ctime() winlog.write(x) x = '\n' winlog.write(x) try: with evtx.Evtx(args) as log: # Convert file and output results print(e_views.XML_HEADER) winlog.write(e_views.XML_HEADER) print("<Events>") winlog.write("<Events>") for record in log.records(): print(record.xml() + '\n') winlog.write(record.xml() + '\n') print("</Events>") winlog.write("</Events>") except: print 'Error!!!' usage() winlog.close()
def EventlogTotal(real_file_path, filename): result = [] eventlog_count = 0 with evtx.Evtx(filename) as log: for i, rec in enumerate(log.records()): try: xml_str = rec.xml() except: continue if xml_str != '': root = XML.fromstring(xml_str) # Event Tag assert len(XML._namespaces(root)) == 2 event_total_information = Eventlog_Total_Information() result.append(event_total_information) result[eventlog_count].event_id = root[0][1].text if 'TimeCreated' in root[0][5].tag: result[eventlog_count].time_created = root[0][5].get( 'SystemTime').replace(' ', 'T') + 'Z' else: result[eventlog_count].time_created = root[0][7].get( 'SystemTime').replace(' ', 'T') + 'Z' result[eventlog_count].user_sid = root[0][-1].get('UserID') result[eventlog_count].source = real_file_path result[eventlog_count].data = html.unescape(xml_str) eventlog_count = eventlog_count + 1 return result
def test_continue_parsing_after_corrupt_ascii(data_path): ''' regression test demonstrating issue 37. Args: data_path (str): the file system path of the test directory. ''' attempted = 0 completed = 0 failed = 0 with evtx.Evtx(os.path.join(data_path, 'dns_log_malformed.evtx')) as log: for chunk in log.chunks(): for record in chunk.records(): try: attempted += 1 assert record.xml() is not None completed += 1 except UnicodeDecodeError: failed += 1 # this small log file has exactly five records. assert attempted == 5 # the first record is valid. assert completed == 1 # however the remaining four have corrupted ASCII strings, # which we are unable to decode. assert failed == 4
def iter_evtx2xml(evtx_file): """ Generator function to read events from evtx file and convert to xml :param evtx_file: file path string :return: generator to xml string representation of evtx event """ global error_counter, event_counter error_counter = 0 event_counter = 0 try: with evtx.Evtx(evtx_file) as log: # process each log entry and return xml representation for record in log.records(): event_counter += 1 try: yield record.xml() except Exception as err: error_counter += 1 # logger.error("Failed to convert EVTX to XML for %s. Error count: %d" % (evtx_file, error_counter)) except Exception as err: raise if error_counter: CONSOLE( "[cyan][evtx2json][/cyan] Failed to read {} events.".format(error_counter) )
def on_click(self): textboxValue = self.textbox.text() whiteList = [4663,4656,4658,4660,4657,5039,4670,4608,4624] with evtx.Evtx(textboxValue) as log: record = log.get_record(self.counter) soup = BeautifulSoup(record.xml(),"html.parser") system_ = soup.find("system") # EventId Filter EventId = int(system_.find("eventid").text) print(EventId) for wlist in whiteList: if wlist == EventId: UrlPath = "https://docs.microsoft.com/ko-kr/windows/security/threat-protection/auditing/event-" + str( EventId) r = requests.get(UrlPath) html = r.content.decode() soup = BeautifulSoup(html, "html.parser") EventExplain = soup.find("main", {"id": "main"}) EventTitle = EventExplain.find("h1").text if "404" in EventTitle: pass else: self.textbox2.setText(str(wlist)+"\n"+EventTitle) else: pass self.counter = self.counter+1
def search(opts): with evtx.Evtx(opts.file.strip()) as log: for chunk in log.chunks(): for record in chunk.records(): xml = record.xml() pattern = opts.pattern.strip() if (pattern in xml): print(xml)
def evtxDumpFunc(evtxPath, xmlPath): # Function to convert an input .evtx file into an xml file # with open(xmlPath, 'w') as xmlFile: with evtx.Evtx(evtxPath) as log: xmlFile.write(e_views.XML_HEADER) xmlFile.write("<Events>") for record in log.records(): xmlFile.write(record.xml()) xmlFile.write("</Events>")
def evtx_parse(): file = 'Microsoft-Windows-DriverFrameworks-UserMode%4Operational.evtx' with evtx.Evtx(file) as log: id = 0 for record in log.records(): #print(dir(record)) with open(output_path + str(id) + '_record.xml', 'w') as fd: fd.write(record.xml()) id += 1
def corelation(): with evtx.Evtx(config['file']['path']) as rec: new = list(rec.records()) # print(len(new)) ind = 0 while (len(new) > ind): abx = convert_xml_to_json(new[ind].xml()) ind += 1 yield abx
def test_issue_43(data_path): ''' regression test demonstrating issue 43. Args: data_path (str): the file system path of the test directory. ''' with evtx.Evtx(os.path.join(data_path, 'issue_43.evtx')) as log: bad_rec = get_record_by_num(log, 508) _ = bad_rec.xml()
def main(): import argparse parser = argparse.ArgumentParser(description="Dump EVTX file into XML.") parser.add_argument("evtx", type=str, help="Path to the Windows EVTX file") args = parser.parse_args() with evtx.Evtx(args.evtx) as log: for record in log.records(): print(record.xml())
def test_DeleteRecordStep(src_evtx_001, filter_single_record_without_res_template): wf = Workflow() step = DeleteRecordStep(filter_single_record_without_res_template) wf.add_step(step) wf.run(src_evtx_001[0], src_evtx_001[1]) with evtx.Evtx(src_evtx_001[1]) as output: fh = output.get_file_header() # check header assert fh.verify() is True
def parse_evtx(opts): with open(save_directory + os.sep + os.path.split(opts.file)[1] + '.json', 'w')as outfile: #outfile.write(codecs.BOM_UTF8) with evtx.Evtx(opts.file.strip()) as log: for chunk in log.chunks(): for record in chunk.records(): xml = record.xml() xmlstr = xmltodict.parse(xml, encoding='utf-8') json.dump(xmlstr, outfile, skipkeys=True, ensure_ascii=False, separators=(',', ':'), encoding='utf-8', sort_keys=True) outfile.write('\n')
def get_events(input_file, parse_xml=False): """ Opens a Windows Event Log and returns XML information from the event record. """ with evtx.Evtx(input_file) as event_log: for record in event_log.records(): if parse_xml: yield record.lxml() else: yield record.xml()
def main(f): try: with evtx.Evtx(f) as log: for record in log.records(): event = record.lxml() if event[0].find("{http://schemas.microsoft.com/win/2004/08/events/event}EventID").text == "4104": add_to_LOGS(event[0],event[1]) output_LOGS() except IOError: print("IOError. Check permissions and path to the file actually exists.") print(usage())
def main(): import argparse parser = argparse.ArgumentParser( description="Print the structure of an EVTX record's template.") parser.add_argument("evtx", type=str, help="Path to the Windows EVTX file") parser.add_argument("record", type=int, help="Record number") args = parser.parse_args() with evtx.Evtx(args.evtx) as log: r = log.get_record(args.record) print(e_views.evtx_template_readable_view(r.root()))
def get_events(input_file, parse_xml=False): # https://chapinb.com/python-forensics-handbook/ch03_event_logs.html#iterate-over-record-xml-data-evtx with evtx.Evtx(input_file) as event_log: for record in event_log.records(): if parse_xml: evtxXML = record.lxml() yield evtxXML else: evtxXML = record.xml() yield evtxXML
def evtx_xml(evtxf): print(" + EVTX -> XML") thistr = '' with evtx.Evtx(evtxf) as log: thistr = e_views.XML_HEADER thistr = thistr + '<Events>' for record in tqdm(log.records()): thistr = thistr + record.xml() thistr = thistr + '</Events>' return thistr
def main(): import argparse parser = argparse.ArgumentParser( description="Dump the structure of an EVTX file.") parser.add_argument("evtx", type=str, help="Path to the Windows EVTX event log file") args = parser.parse_args() with evtx.Evtx(args.evtx) as log: formatter = EvtxFormatter() for line in formatter.format_header(log.get_file_header()): print(line)
def convert_xml(out_path): import Evtx.Evtx as evtx import Evtx.Views as e_views for file in os.listdir(out_path): if file[-5:] == ".evtx": in_file = out_path + "\\" + file convert_file = out_path + "\\" + file[:-5] + ".xml" xml_logs = open(convert_file, "w") with evtx.Evtx(in_file) as evtx_logs: xml_logs.write(e_views.XML_HEADER) for record in evtx_logs.records(): xml_logs.write(record.xml()) xml_logs.close()
def Partition_evtx_parse(): try: os.mkdir(partition_output_path) except: pass file = 'Microsoft-Windows-Partition%4Diagnostic.evtx' with evtx.Evtx(file) as log: id = 0 for record in log.records(): #print(dir(record)) with open(partition_output_path + str(id) + '_record.xml', 'w') as fd: fd.write(record.xml()) id += 1
def run(self, dest_evtx, fast_check=True, record_id=None): """ Executes WorkflowStep. Begins with filtering the records and afterwards executes the step to all found records. :param dest_evtx: path to result evtx file :param fast_check: Fast check steps over some inefficient validating steps :param record_id: List of record ids. If provided, this list is used for execution and no filtering is done. :return: """ logger.info("Starting step {0}".format(self.__class__.__name__)) # search for records with evtx.Evtx(dest_evtx, readonly=False) as self._dest_evtx: if record_id is None: found_records = self.filter_records() else: found_records = [record_id] for record_id in found_records: # new initialization because of changes to mmap in last run with evtx.Evtx(dest_evtx, readonly=False) as self._dest_evtx: record = self._dest_evtx.get_record(record_id) nodes = self.get_elements(record) logger.info("Execute {1} for record {0}".format(record_id, self)) # executes steps based on manipulating concrete nodes if nodes is not None: for element, root in nodes: self.execute(record, element, root) self.repair_hash() # executes steps based on records else: self.execute(record) # validates the resultung evtx file with evtx.Evtx(dest_evtx, readonly=False) as self._dest_evtx: self.check(self._dest_evtx, fast_check)
def bulk_test_insertion(): if os.path.exists('saved_record'): oldL = load('saved_record') if os.path.exists('saved_list'): actions = load('saved_list') else: oldL = 0 actions = [] with evtx.Evtx(config['file']['path']) as rec: while True: new = list(rec.records()) newl = len(new) if newl > oldL: while newl > oldL: abx = convert_xml_to_json(new[oldL].xml()) id_event = abx['Event']['System']['TimeCreated'][ 'SystemTime'] sav_dict = conver_dict(abx) for data in abx['Event']['EventData']['Data']: if len(data) == 2 and "Name" in data and data[ 'Name'] == "Image": if 'C:\Windows\System32\wbem\WMIC.exe' == data['text'] \ or 'C:\Windows\System32\SppExtComObj.Exe' == data['text'] \ or "C:\\Users\\admin\AppData\Local\Programs\Python\Python37\pythonw.exe" == data[ 'text']: print("Noise") else: action = { '_index': config['elastic']['index'], '_type': config['elastic']['title'], '_id': id_event, '_source': sav_dict } actions.append(action) save(actions, 'saved_list') oldL += 1 save(oldL, 'saved_record') temp = len(actions) if temp == 50: print("Inserting the records") helpers.bulk(es, actions) actions = [] save(actions, 'saved_list') else: time.sleep(0.5) outfile.close()