From 9d947c89601756a8b6411c6bd89cd4a26c356ea1 Mon Sep 17 00:00:00 2001 From: Joachim Metz Date: Sat, 15 May 2021 18:30:31 +0200 Subject: [PATCH] Changed winevtx parser to not parse XML string #3595 (#3596) --- .github/workflows/test_tox.yml | 8 ++- config/dpkg/control | 2 +- dependencies.ini | 2 +- plaso/dependencies.py | 4 +- plaso/parsers/winevtx.py | 99 +++++++--------------------------- requirements.txt | 2 +- setup.cfg | 2 +- 7 files changed, 31 insertions(+), 88 deletions(-) diff --git a/.github/workflows/test_tox.yml b/.github/workflows/test_tox.yml index b9a9fb1747..ad6b767267 100644 --- a/.github/workflows/test_tox.yml +++ b/.github/workflows/test_tox.yml @@ -1,6 +1,12 @@ # Run tox tests on Ubuntu Docker images using GIFT PPA name: test_tox -on: [push, pull_request] +on: + pull_request: + branches: + - main + push: + branches: + - main jobs: build: runs-on: ubuntu-latest diff --git a/config/dpkg/control b/config/dpkg/control index c1e60e6a05..05302ebf01 100644 --- a/config/dpkg/control +++ b/config/dpkg/control @@ -17,7 +17,7 @@ Description: Data files for plaso (log2timeline) Package: python3-plaso Architecture: all -Depends: plaso-data (>= ${binary:Version}), libbde-python3 (>= 20140531), libcreg-python3 (>= 20200725), libesedb-python3 (>= 20150409), libevt-python3 (>= 20191104), libevtx-python3 (>= 20141112), libewf-python3 (>= 20131210), libfsapfs-python3 (>= 20201107), libfsext-python3 (>= 20200819), libfshfs-python3 (>= 20201103), libfsntfs-python3 (>= 20200805), libfsxfs-python3 (>= 20201114), libfvde-python3 (>= 20160719), libfwnt-python3 (>= 20180117), libfwsi-python3 (>= 20150606), liblnk-python3 (>= 20150830), libluksde-python3 (>= 20200101), libmodi-python3 (>= 20210405), libmsiecf-python3 (>= 20150314), libolecf-python3 (>= 20151223), libqcow-python3 (>= 20131204), libregf-python3 (>= 20201002), libscca-python3 (>= 20190605), libsigscan-python3 (>= 20190629), libsmdev-python3 (>= 20140529), libsmraw-python3 (>= 20140612), libvhdi-python3 (>= 20131210), libvmdk-python3 (>= 20140421), libvsgpt-python3 (>= 20210115), libvshadow-python3 (>= 20160109), libvslvm-python3 (>= 20160109), python3-artifacts (>= 20190305), python3-bencode, python3-certifi (>= 2016.9.26), python3-cffi-backend (>= 1.9.1), python3-chardet (>= 2.0.1), python3-cryptography (>= 2.0.2), python3-dateutil (>= 1.5), python3-defusedxml (>= 0.5.0), python3-dfdatetime (>= 20210509), python3-dfvfs (>= 20210501), python3-dfwinreg (>= 20201002), python3-dtfabric (>= 20200621), python3-elasticsearch (>= 7.0), python3-future (>= 0.16.0), python3-idna (>= 2.5), python3-lz4 (>= 0.10.0), python3-pefile (>= 2018.8.8), python3-psutil (>= 5.4.3), python3-pyparsing (>= 2.3.0), python3-pytsk3 (>= 20160721), python3-redis (>= 3.4), python3-requests (>= 2.18.0), python3-six (>= 1.1.0), python3-tz, python3-urllib3 (>= 1.21.1), python3-xlsxwriter (>= 0.9.3), python3-yaml (>= 3.10), python3-yara (>= 3.4.0), python3-zmq (>= 2.1.11), ${python3:Depends}, ${misc:Depends} +Depends: plaso-data (>= ${binary:Version}), libbde-python3 (>= 20140531), libcreg-python3 (>= 20200725), libesedb-python3 (>= 20150409), libevt-python3 (>= 20191104), libevtx-python3 (>= 20210424), libewf-python3 (>= 20131210), libfsapfs-python3 (>= 20201107), libfsext-python3 (>= 20200819), libfshfs-python3 (>= 20201103), libfsntfs-python3 (>= 20200805), libfsxfs-python3 (>= 20201114), libfvde-python3 (>= 20160719), libfwnt-python3 (>= 20180117), libfwsi-python3 (>= 20150606), liblnk-python3 (>= 20150830), libluksde-python3 (>= 20200101), libmodi-python3 (>= 20210405), libmsiecf-python3 (>= 20150314), libolecf-python3 (>= 20151223), libqcow-python3 (>= 20131204), libregf-python3 (>= 20201002), libscca-python3 (>= 20190605), libsigscan-python3 (>= 20190629), libsmdev-python3 (>= 20140529), libsmraw-python3 (>= 20140612), libvhdi-python3 (>= 20131210), libvmdk-python3 (>= 20140421), libvsgpt-python3 (>= 20210115), libvshadow-python3 (>= 20160109), libvslvm-python3 (>= 20160109), python3-artifacts (>= 20190305), python3-bencode, python3-certifi (>= 2016.9.26), python3-cffi-backend (>= 1.9.1), python3-chardet (>= 2.0.1), python3-cryptography (>= 2.0.2), python3-dateutil (>= 1.5), python3-defusedxml (>= 0.5.0), python3-dfdatetime (>= 20210509), python3-dfvfs (>= 20210501), python3-dfwinreg (>= 20201002), python3-dtfabric (>= 20200621), python3-elasticsearch (>= 7.0), python3-future (>= 0.16.0), python3-idna (>= 2.5), python3-lz4 (>= 0.10.0), python3-pefile (>= 2018.8.8), python3-psutil (>= 5.4.3), python3-pyparsing (>= 2.3.0), python3-pytsk3 (>= 20160721), python3-redis (>= 3.4), python3-requests (>= 2.18.0), python3-six (>= 1.1.0), python3-tz, python3-urllib3 (>= 1.21.1), python3-xlsxwriter (>= 0.9.3), python3-yaml (>= 3.10), python3-yara (>= 3.4.0), python3-zmq (>= 2.1.11), ${python3:Depends}, ${misc:Depends} Description: Python 3 module of plaso (log2timeline) Plaso (log2timeline) is a framework to create super timelines. Its purpose is to extract timestamps from various files found on typical diff --git a/dependencies.ini b/dependencies.ini index 0114dc37ae..53d303fd21 100644 --- a/dependencies.ini +++ b/dependencies.ini @@ -149,7 +149,7 @@ version_property: get_version() [pyevtx] dpkg_name: libevtx-python3 l2tbinaries_name: libevtx -minimum_version: 20141112 +minimum_version: 20210424 pypi_name: libevtx-python rpm_name: libevtx-python3 version_property: get_version() diff --git a/plaso/dependencies.py b/plaso/dependencies.py index b6e2c508a3..d18e6c0e97 100644 --- a/plaso/dependencies.py +++ b/plaso/dependencies.py @@ -31,13 +31,13 @@ 'future': ('__version__', '0.16.0', None, True), 'idna': ('__version__', '2.5', None, True), 'lz4': ('__version__', '0.10.0', None, True), - 'pefile': ('__version__', '2018.8.8', None, True), + 'pefile': ('__version__', '2018.8.8', '2021.5.13', True), 'psutil': ('__version__', '5.4.3', None, True), 'pybde': ('get_version()', '20140531', None, True), 'pycreg': ('get_version()', '20200725', None, True), 'pyesedb': ('get_version()', '20150409', None, True), 'pyevt': ('get_version()', '20191104', None, True), - 'pyevtx': ('get_version()', '20141112', None, True), + 'pyevtx': ('get_version()', '20210424', None, True), 'pyewf': ('get_version()', '20131210', None, True), 'pyfsapfs': ('get_version()', '20201107', None, True), 'pyfsext': ('get_version()', '20200819', None, True), diff --git a/plaso/parsers/winevtx.py b/plaso/parsers/winevtx.py index 0f3f12e3b1..31ec65294d 100644 --- a/plaso/parsers/winevtx.py +++ b/plaso/parsers/winevtx.py @@ -1,14 +1,10 @@ # -*- coding: utf-8 -*- """Parser for Windows XML EventLog (EVTX) files.""" -from xml.parsers import expat - import pyevtx -from defusedxml import ElementTree from dfdatetime import filetime as dfdatetime_filetime from dfdatetime import semantic_time as dfdatetime_semantic_time -from dfdatetime import time_elements as dfdatetime_time_elements from plaso.containers import events from plaso.containers import time_events @@ -59,59 +55,6 @@ class WinEvtxParser(interface.FileObjectParser): NAME = 'winevtx' DATA_FORMAT = 'Windows XML EventLog (EVTX) file' - def _GetCreationTimeFromXMLString( - self, parser_mediator, record_index, xml_string, recovered=False): - """Retrieves the creation time from the XML string. - - Args: - parser_mediator (ParserMediator): mediates interactions between parsers - and other components, such as storage and dfvfs. - record_index (int): event record index. - xml_string (str): event XML string. - recovered (Optional[bool]): True if the record was recovered. - - Returns: - str: creation date and time formatted as ISO 8601 or None if not - available. - """ - try: - xml_root = ElementTree.fromstring(xml_string) - except (LookupError, ElementTree.ParseError, expat.ExpatError) as exception: - warning_message = ( - 'unable to parse XML string of event record: {0:d} with error: ' - '{1!s}').format(record_index, exception) - if recovered: - parser_mediator.ProduceRecoveryWarning(warning_message) - else: - parser_mediator.ProduceExtractionWarning(warning_message) - return None - - system_xml_element = xml_root.find( - '{http://schemas.microsoft.com/win/2004/08/events/event}System') - if system_xml_element is None: - warning_message = ( - 'missing System XML element in event record: {0:d}').format( - record_index) - if recovered: - parser_mediator.ProduceRecoveryWarning(warning_message) - else: - parser_mediator.ProduceExtractionWarning(warning_message) - return None - - time_created_xml_element = system_xml_element.find( - '{http://schemas.microsoft.com/win/2004/08/events/event}TimeCreated') - if time_created_xml_element is None: - warning_message = ( - 'missing TimeCreated XML element in event record: {0:d}').format( - record_index) - if recovered: - parser_mediator.ProduceRecoveryWarning(warning_message) - else: - parser_mediator.ProduceExtractionWarning(warning_message) - return None - - return time_created_xml_element.get('SystemTime') - def _GetEventDataFromRecord( self, parser_mediator, record_index, evtx_record, recovered=False): """Extract data from a Windows XML EventLog (EVTX) record. @@ -225,29 +168,23 @@ def _ParseRecord( date_time, definitions.TIME_DESCRIPTION_WRITTEN) parser_mediator.ProduceEventWithEventData(event, event_data) - creation_time_string = self._GetCreationTimeFromXMLString( - parser_mediator, record_index, event_data.xml_string, - recovered=recovered) - if creation_time_string: - date_time = dfdatetime_time_elements.TimeElementsInMicroseconds() + try: + creation_time = evtx_record.get_creation_time_as_integer() + except OverflowError as exception: + warning_message = ( + 'unable to read creation time from event record: {0:d} ' + 'with error: {1!s}').format(record_index, exception) + if recovered: + parser_mediator.ProduceRecoveryWarning(warning_message) + else: + parser_mediator.ProduceExtractionWarning(warning_message) - try: - date_time.CopyFromStringISO8601(creation_time_string) - except ValueError as exception: - warning_message = ( - 'unsupported creation time: {0:s} with error: {1!s}.').format( - creation_time_string, exception) - if recovered: - parser_mediator.ProduceRecoveryWarning(warning_message) - else: - parser_mediator.ProduceExtractionWarning(warning_message) - - date_time = None - - if date_time: - event = time_events.DateTimeValuesEvent( - date_time, definitions.TIME_DESCRIPTION_CREATION) - parser_mediator.ProduceEventWithEventData(event, event_data) + creation_time = None + + if creation_time: + event = time_events.DateTimeValuesEvent( + date_time, definitions.TIME_DESCRIPTION_CREATION) + parser_mediator.ProduceEventWithEventData(event, event_data) def _ParseRecords(self, parser_mediator, evtx_file): """Parses Windows XML EventLog (EVTX) records. @@ -270,7 +207,7 @@ def _ParseRecords(self, parser_mediator, evtx_file): evtx_record = evtx_file.get_record(record_index) self._ParseRecord(parser_mediator, record_index, evtx_record) - except (IOError, ElementTree.ParseError) as exception: + except IOError as exception: parser_mediator.ProduceExtractionWarning( 'unable to parse event record: {0:d} with error: {1!s}'.format( record_index, exception)) @@ -284,7 +221,7 @@ def _ParseRecords(self, parser_mediator, evtx_file): self._ParseRecord( parser_mediator, record_index, evtx_record, recovered=True) - except (IOError, ElementTree.ParseError) as exception: + except IOError as exception: parser_mediator.ProduceRecoveryWarning(( 'unable to parse recovered event record: {0:d} with error: ' '{1!s}').format(record_index, exception)) diff --git a/requirements.txt b/requirements.txt index 566934284d..895851d43a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -19,7 +19,7 @@ libbde-python >= 20140531 libcreg-python >= 20200725 libesedb-python >= 20150409 libevt-python >= 20191104 -libevtx-python >= 20141112 +libevtx-python >= 20210424 libewf-python >= 20131210 libfsapfs-python >= 20201107 libfsext-python >= 20200819 diff --git a/setup.cfg b/setup.cfg index 2d4a20cbd4..0062902838 100644 --- a/setup.cfg +++ b/setup.cfg @@ -21,7 +21,7 @@ requires = libbde-python3 >= 20140531 libcreg-python3 >= 20200725 libesedb-python3 >= 20150409 libevt-python3 >= 20191104 - libevtx-python3 >= 20141112 + libevtx-python3 >= 20210424 libewf-python3 >= 20131210 libfsapfs-python3 >= 20201107 libfsext-python3 >= 20200819