{"id":13738884,"url":"https://github.com/williballenthin/EVTXtract","last_synced_at":"2025-05-08T18:31:06.042Z","repository":{"id":11022671,"uuid":"13352424","full_name":"williballenthin/EVTXtract","owner":"williballenthin","description":"EVTXtract recovers and reconstructs fragments of EVTX log files from raw binary data, including unallocated space and memory images.","archived":false,"fork":false,"pushed_at":"2025-03-12T12:22:48.000Z","size":136,"stargazers_count":192,"open_issues_count":4,"forks_count":24,"subscribers_count":18,"default_branch":"master","last_synced_at":"2025-05-04T05:02:11.560Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/williballenthin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.TXT","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2013-10-05T20:59:26.000Z","updated_at":"2025-05-01T03:04:08.000Z","dependencies_parsed_at":"2025-03-26T09:08:41.328Z","dependency_job_id":"fc0756d3-90ec-4ca2-bba4-2490aa11b7f7","html_url":"https://github.com/williballenthin/EVTXtract","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/williballenthin%2FEVTXtract","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/williballenthin%2FEVTXtract/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/williballenthin%2FEVTXtract/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/williballenthin%2FEVTXtract/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/williballenthin","download_url":"https://codeload.github.com/williballenthin/EVTXtract/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253127003,"owners_count":21858172,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-03T04:00:19.063Z","updated_at":"2025-05-08T18:31:05.704Z","avatar_url":"https://github.com/williballenthin.png","language":"Python","funding_links":[],"categories":["File Carving","Tool"],"sub_categories":["Other Resources","Memory Acquisition"],"readme":"\nPurpose\n-------\nEVTXtract recovers and reconstructs fragments of EVTX log files from raw binary data, including unallocated space and memory images.\n\nQuick Run\n---------\n\nInstall EVTXtract via `pip`:\n\n    pip install evtxtract\n\nNow the tool is ready to go!\n\n    C:/Python27/Scripts/evtxtract.exe   Z:/evidence/1/image.dd   \u003e   Z:/work/1/evtx.xml\n\n\nQuicker Run\n-----------\n\nDownload standalone executable nightly builds of EVTXtract here:\n\n  - [Linux](https://s3.amazonaws.com/build-artifacts.floss.flare.fireeye.com/travis/linux/dist/evtxtract)\n  - [MacOS](https://s3.amazonaws.com/build-artifacts.floss.flare.fireeye.com/travis/osx/dist/evtxtract)\n\nThen you can do:\n\n    ./evtxtract    /path/to/evidence    \u003e   /path/to/output.xml\n\n\nBackground\n----------\n\nEVTX records are XML fragments encoded using a Microsoft-specific binary XML representation.\nDespite the convenient format, it is not easy to recover EVTX event log records from a corrupted file or unallocated space.\nThis is because the complete representation of a record often depends on other records found nearby.\nThe event log service recognizes similarities among records and refactors commonalities into \"templates\".\nA template is a fixed structure with placeholders that reserve space for variable content.\nThe on-disk event log record structure is a reference to a template, and a list of substitutions (the variable content the replaces a placeholder in a template).\nTo decode a record into XML, the event log service resolves the template and replaces its placeholders with the entries of the substitution array.\nTherefore, template corruption renders many records unrecoverable within the local 64KB \"chunk\".\nHowever, the substitution array for the remaining records may still be intact.\nIf so, it may be possible to produce XML fragments that match the original records if the damaged template can be reconstructed.\nFor many common events, such as process creation or account logon, empirical testing demonstrates the relevant templates remain mostly constant.\nIn these cases, recovering event log records boils down to identifying appropriate templates found in other EVTX chunks.\n\n\nAlgorithm\n---------\n\n1. Scan for chunk signatures (\"ElfChnk\")\n   - check header for sane values (0x80 \u003c= size \u003c= 0x200)\n   - verify checksums (header, data)\n2. Extract records from valid chunks found in (1)\n3. Extract templates from valid chunks found in (1)\n4. Scan for record signatures\n   - check header for sane values\n   - extract timestamp\n   - attempt to parse substitutions\n   - attempt to decode substitutions into EID, other fields\n5. Reconstruct records by reusing old templates with recovered substitutions\n\n\nUsage\n-----\n\nThe EVTXtract is a pure Python script.\nThis means it easily runs on Windows, Linux, and MacOS.\nSimply invoke the script, providing the path to a binary image, and EVTXtract writes its results to the standard out stream.\nThe binary file can be any data: a raw image, memory dump, etc.\n\nExample command line:\n\n    C:/Python27/Scripts/evtxtract.exe   Z:/evidence/1/image.dd   \u003e   Z:/work/1/evtx.xml\n\nBelow are some example results from the above command.\nIt shows two records: a complete and incomplete record.\nThe first record is completely reconstructed,\n  and is formatted just like it would be in event viewer.\nHowever, EVTXtract was unable to complete reconstruct the second record,\n since some critical template data was missing.\nSo, its been formatted with as much data as was recovered.\nEVTXtract uses a schema that allows you to continue processing despite incomplete data.\n\n    \u003cEvent xmlns=\"http://schemas.microsoft.com/win/2004/08/events/event\"\u003e\n        \u003cSystem\u003e\n            \u003cProvider Name=\"Microsoft-Windows-PrintService\" Guid=\"{747ef6fd-e535-4d16-b510-42c90f6873a1}\"\u003e\u003c/Provider\u003e\n            \u003cEventID Qualifiers=\"\"\u003e823\u003c/EventID\u003e\n            \u003cVersion\u003e0\u003c/Version\u003e\n            \u003cLevel\u003e4\u003c/Level\u003e\n            \u003cTask\u003e49\u003c/Task\u003e\n            \u003cOpcode\u003e11\u003c/Opcode\u003e\n            \u003cKeywords\u003e0x80000000000200\u003c/Keywords\u003e\n            \u003cTimeCreated SystemTime=\"2013-03-23 02:05:57.848455\"\u003e\u003c/TimeCreated\u003e\n            \u003cEventRecordID\u003e1\u003c/EventRecordID\u003e\n            \u003cCorrelation ActivityID=\"\" RelatedActivityID=\"\"\u003e\u003c/Correlation\u003e\n            \u003cExecution ProcessID=\"1204\" ThreadID=\"1208\"\u003e\u003c/Execution\u003e\n            \u003cChannel\u003eMicrosoft-Windows-PrintService/Admin\u003c/Channel\u003e\n            \u003cComputer\u003eJOSHUA\u003c/Computer\u003e\n            \u003cSecurity UserID=\"S-1-5-21-3454551831-629247693-1078506759-1000\"\u003e\u003c/Security\u003e\n        \u003c/System\u003e\n        \u003cUserData\u003e\n            \u003cChangingDefaultPrinter xmlns:auto-ns3=\"http://schemas.microsoft.com/win/2004/08/events\" xmlns=\"http://manifests.microsoft.com/win/2005/08/windows/printing/spooler/core/events\"\u003e\n                \u003cDefaultPrinterSelectedBySpooler\u003e1\u003c/DefaultPrinterSelectedBySpooler\u003e\n                \u003cOldDefaultPrinter\u003e\u003c/OldDefaultPrinter\u003e\n                \u003cNewDefaultPrinter\u003eMicrosoft XPS Document Writer,winspool,Ne00:\u003c/NewDefaultPrinter\u003e\n                \u003cStatus\u003e0x000000\u003c/Status\u003e\n                \u003cModule\u003espoolsv.exe\u003c/Module\u003e\n            \u003c/ChangingDefaultPrinter\u003e\n        \u003c/UserData\u003e\n    \u003c/Event\u003e\n\n    ...\n\n    \u003cRecord\u003e\n    \u003cOffset\u003e0x317198\u003c/Offset\u003e\n    \u003cEventID\u003e1531\u003c/EventID\u003e\n    \u003cSubstitutions\u003e\n      \u003cSubstitution index=\"0\"\u003e\n        \u003cType\u003e4\u003c/Type\u003e\n        \u003cValue\u003e4\u003c/Value\u003e\n      \u003c/Substitution\u003e\n      \u003cSubstitution index=\"1\"\u003e\n        \u003cType\u003e4\u003c/Type\u003e\n        \u003cValue\u003e0\u003c/Value\u003e\n      \u003c/Substitution\u003e\n      \u003cSubstitution index=\"2\"\u003e\n        \u003cType\u003e6\u003c/Type\u003e\n        \u003cValue\u003e0\u003c/Value\u003e\n      \u003c/Substitution\u003e\n      \u003cSubstitution index=\"3\"\u003e\n        \u003cType\u003e6\u003c/Type\u003e\n        \u003cValue\u003e1531\u003c/Value\u003e\n      \u003c/Substitution\u003e\n      \u003cSubstitution index=\"4\"\u003e\n        \u003cType\u003e0\u003c/Type\u003e\n        \u003cValue\u003e\u003c/Value\u003e\n      \u003c/Substitution\u003e\n      \u003cSubstitution index=\"5\"\u003e\n        \u003cType\u003e21\u003c/Type\u003e\n        \u003cValue\u003e0x8000000000000000\u003c/Value\u003e\n      \u003c/Substitution\u003e\n      \u003cSubstitution index=\"6\"\u003e\n        \u003cType\u003e17\u003c/Type\u003e\n        \u003cValue\u003e2013-03-23 02:02:35.679552\u003c/Value\u003e\n      \u003c/Substitution\u003e\n      \u003cSubstitution index=\"7\"\u003e\n        \u003cType\u003e0\u003c/Type\u003e\n        \u003cValue\u003e\u003c/Value\u003e\n      \u003c/Substitution\u003e\n      \u003cSubstitution index=\"8\"\u003e\n        \u003cType\u003e8\u003c/Type\u003e\n        \u003cValue\u003e928\u003c/Value\u003e\n      \u003c/Substitution\u003e\n      \u003cSubstitution index=\"9\"\u003e\n        \u003cType\u003e8\u003c/Type\u003e\n        \u003cValue\u003e1040\u003c/Value\u003e\n      \u003c/Substitution\u003e\n      \u003cSubstitution index=\"10\"\u003e\n        \u003cType\u003e10\u003c/Type\u003e\n        \u003cValue\u003e132\u003c/Value\u003e\n      \u003c/Substitution\u003e\n      \u003cSubstitution index=\"11\"\u003e\n        \u003cType\u003e4\u003c/Type\u003e\n        \u003cValue\u003e0\u003c/Value\u003e\n      \u003c/Substitution\u003e\n      \u003cSubstitution index=\"12\"\u003e\n        \u003cType\u003e19\u003c/Type\u003e\n        \u003cValue\u003eS-1-5-18\u003c/Value\u003e\n      \u003c/Substitution\u003e\n      \u003cSubstitution index=\"13\"\u003e\n        \u003cType\u003e0\u003c/Type\u003e\n        \u003cValue\u003e\u003c/Value\u003e\n      \u003c/Substitution\u003e\n      \u003cSubstitution index=\"14\"\u003e\n        \u003cType\u003e1\u003c/Type\u003e\n        \u003cValue\u003eMicrosoft-Windows-User Profiles Service\u003c/Value\u003e\n      \u003c/Substitution\u003e\n      \u003cSubstitution index=\"15\"\u003e\n        \u003cType\u003e15\u003c/Type\u003e\n        \u003cValue\u003e0001010f-010c-77e3-bf2f-3ef300001200\u003c/Value\u003e\n      \u003c/Substitution\u003e\n      \u003cSubstitution index=\"16\"\u003e\n        \u003cType\u003e1\u003c/Type\u003e\n        \u003cValue\u003eApplication\u003c/Value\u003e\n      \u003c/Substitution\u003e\n    \u003c/Substitutions\u003e\n    \u003c/Record\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwilliballenthin%2FEVTXtract","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwilliballenthin%2FEVTXtract","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwilliballenthin%2FEVTXtract/lists"}