dissect.cobaltstrike.pe ======================= .. py:module:: dissect.cobaltstrike.pe .. autoapi-nested-parse:: This module contains helper functions for parsing PE files, mainly for extracting Beacon specific PE artifacts. Attributes ---------- .. autoapisummary:: dissect.cobaltstrike.pe.logger dissect.cobaltstrike.pe.PE_DEF dissect.cobaltstrike.pe.pestruct dissect.cobaltstrike.pe.DOSHEADER_X64 dissect.cobaltstrike.pe.DOSHEADER_X86 Functions --------- .. autoapisummary:: dissect.cobaltstrike.pe.find_mz_offset dissect.cobaltstrike.pe.find_compile_stamps dissect.cobaltstrike.pe.find_magic_mz dissect.cobaltstrike.pe.find_magic_pe dissect.cobaltstrike.pe.find_stage_prepend_append dissect.cobaltstrike.pe.find_architecture Module Contents --------------- .. py:data:: logger .. py:data:: PE_DEF :value: Multiline-String .. raw:: html
Show Value .. code-block:: python """ #define IMAGE_FILE_MACHINE_AMD64 0x8664 #define IMAGE_FILE_MACHINE_I386 0x014c #define IMAGE_FILE_MACHINE_IA64 0x0200 #define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 #define IMAGE_SIZEOF_SHORT_NAME 8 #define IMAGE_DIRECTORY_ENTRY_EXPORT 0 #define IMAGE_DIRECTORY_ENTRY_IMPORT 1 #define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 typedef struct _IMAGE_DOS_HEADER { WORD e_magic; WORD e_cblp; WORD e_cp; WORD e_crlc; WORD e_cparhdr; WORD e_minalloc; WORD e_maxalloc; WORD e_ss; WORD e_sp; WORD e_csum; WORD e_ip; WORD e_cs; WORD e_lfarlc; WORD e_ovno; WORD e_res[4]; WORD e_oemid; WORD e_oeminfo; WORD e_res2[10]; LONG e_lfanew; } IMAGE_DOS_HEADER; typedef struct _IMAGE_FILE_HEADER { WORD Machine; WORD NumberOfSections; DWORD TimeDateStamp; DWORD PointerToSymbolTable; DWORD NumberOfSymbols; WORD SizeOfOptionalHeader; WORD Characteristics; } IMAGE_FILE_HEADER; typedef struct _IMAGE_DATA_DIRECTORY { ULONG VirtualAddress; ULONG Size; } IMAGE_DATA_DIRECTORY; typedef struct _IMAGE_OPTIONAL_HEADER { WORD Magic; BYTE MajorLinkerVersion; BYTE MinorLinkerVersion; DWORD SizeOfCode; DWORD SizeOfInitializedData; DWORD SizeOfUninitializedData; DWORD AddressOfEntryPoint; DWORD BaseOfCode; DWORD BaseOfData; DWORD ImageBase; DWORD SectionAlignment; DWORD FileAlignment; WORD MajorOperatingSystemVersion; WORD MinorOperatingSystemVersion; WORD MajorImageVersion; WORD MinorImageVersion; WORD MajorSubsystemVersion; WORD MinorSubsystemVersion; DWORD Win32VersionValue; DWORD SizeOfImage; DWORD SizeOfHeaders; DWORD CheckSum; WORD Subsystem; WORD DllCharacteristics; DWORD SizeOfStackReserve; DWORD SizeOfStackCommit; DWORD SizeOfHeapReserve; DWORD SizeOfHeapCommit; DWORD LoaderFlags; DWORD NumberOfRvaAndSizes; IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; } IMAGE_OPTIONAL_HEADER; typedef struct _IMAGE_OPTIONAL_HEADER64 { WORD Magic; BYTE MajorLinkerVersion; BYTE MinorLinkerVersion; DWORD SizeOfCode; DWORD SizeOfInitializedData; DWORD SizeOfUninitializedData; DWORD AddressOfEntryPoint; DWORD BaseOfCode; ULONGLONG ImageBase; DWORD SectionAlignment; DWORD FileAlignment; WORD MajorOperatingSystemVersion; WORD MinorOperatingSystemVersion; WORD MajorImageVersion; WORD MinorImageVersion; WORD MajorSubsystemVersion; WORD MinorSubsystemVersion; DWORD Win32VersionValue; DWORD SizeOfImage; DWORD SizeOfHeaders; DWORD CheckSum; WORD Subsystem; WORD DllCharacteristics; ULONGLONG SizeOfStackReserve; ULONGLONG SizeOfStackCommit; ULONGLONG SizeOfHeapReserve; ULONGLONG SizeOfHeapCommit; DWORD LoaderFlags; DWORD NumberOfRvaAndSizes; IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; } IMAGE_OPTIONAL_HEADER64; typedef struct _IMAGE_SECTION_HEADER { char Name[IMAGE_SIZEOF_SHORT_NAME]; ULONG VirtualSize; ULONG VirtualAddress; ULONG SizeOfRawData; ULONG PointerToRawData; ULONG PointerToRelocations; ULONG PointerToLinenumbers; USHORT NumberOfRelocations; USHORT NumberOfLinenumbers; ULONG Characteristics; } IMAGE_SECTION_HEADER; typedef struct _IMAGE_IMPORT_DESCRIPTOR { union { ULONG Characteristics; ULONG OriginalFirstThunk; } u; ULONG TimeDateStamp; ULONG ForwarderChain; ULONG Name; ULONG FirstThunk; } IMAGE_IMPORT_DESCRIPTOR; typedef struct _IMAGE_EXPORT_DIRECTORY { ULONG Characteristics; ULONG TimeDateStamp; USHORT MajorVersion; USHORT MinorVersion; ULONG Name; ULONG Base; ULONG NumberOfFunctions; ULONG NumberOfNames; ULONG AddressOfFunctions; // RVA from base of image ULONG AddressOfNames; // RVA from base of image ULONG AddressOfNameOrdinals; // RVA from base of image } IMAGE_EXPORT_DIRECTORY; """ .. raw:: html
.. py:data:: pestruct .. py:data:: DOSHEADER_X64 .. py:data:: DOSHEADER_X86 .. py:function:: find_mz_offset(fh: BinaryIO, start_offset: int = 0, maxrange: int = 1024) -> Optional[int] Find and return the start offset of a valid IMAGE_DOS_HEADER or ``None`` if it cannot be found. It uses `IMAGE_DOS_HEADER.e_lfanew` and `IMAGE_FILE_HEADER.Machine` as a constraint. Side effects: file handle position due to seeking :param fh: file like object :param start_offset: offset to start searching from, None indicates from current file position :param maxrange: how far to search for into the file object :returns: offset of the start of IMAGE_DOS_HEADER in the file object or ``None`` if it's not found .. py:function:: find_compile_stamps(fh: BinaryIO, start_offset: int = 0, maxrange: int = 1024) -> Tuple[Optional[int], Optional[int]] Find and return a tuple with the `PE compile` and `PE export` timestamps. If one or more `TimeDateStamps` are not found it will be returned as ``None`` in the tuple. Side effects: file handle position due to seeking :param fh: file like object :param start_offset: offset to start searching from, ``None`` indicates from current file position :param maxrange: how far to search for into the file object :returns: Tuple with ``(IMAGE_FILE_HEADER.TimeDateStamp, IMAGE_EXPORT_DIRECTORY.TimeDateStamp)``. Either tuple values can be ``None`` if it's not found. .. py:function:: find_magic_mz(fh: BinaryIO, start_offset: int = 0, maxrange: int = 1024) -> Optional[bytes] Find and returns the MZ header bytes or ``None`` if cannot be found Cobalt Strike allows changing the MZ magic header using `magic_mz_x86` or `magic_mz_x64` in the c2 profile. This function recovers these bytes. Side effects: file handle position due to seeking :param fh: file like object :param start_offset: offset to start searching from, None indicates from current file position :param maxrange: how far to search for into the file object :returns: MZ header bytes or ``None`` if not found. .. py:function:: find_magic_pe(fh: BinaryIO, start_offset: int = 0, maxrange: int = 1024) -> Optional[bytes] Find and returns the PE header (``magic_pe``) bytes or ``None`` if cannot be found Cobalt Strike allows changing the PE magic header using the ``magic_pe`` in the malleable c2 profile. This function tries to recovers these bytes. Side effects: file handle position due to seeking :param fh: file like object :param start_offset: offset to start searching from, None indicates from current file position :param maxrange: how far to search for into the file object :returns: PE header bytes or ``None`` if not found. .. py:function:: find_stage_prepend_append(fh: BinaryIO, start_offset: int = 0, maxrange: int = 1024) -> Tuple[Optional[bytes], Optional[bytes]] Find and return the stage prepend and append bytes as a tuple. Cobalt Strike allows prepending and appending extra bytes to the beacon using malleable c2 profile settings. This function tries to recover these bytes. Side effects: file handle position due to seeking :param fh: file like object :param start_offset: offset to start searching from, None indicates from current file position :param maxrange: how far to search for into the file object :returns: Tuple containing ``(prepend_bytes, append_bytes)``. Either tuple values can be ``None`` if it's not found. .. py:function:: find_architecture(fh: BinaryIO, start_offset: int = 0, maxrange: int = 1024) -> Optional[str] Find and return the PE image architecture, either ``"x86"`` or ``"x64"`` or ``None`` if not found. It uses `IMAGE_DOS_HEADER.e_lfanew` and `IMAGE_FILE_HEADER.Machine` as a constraint. Only `x86` and `x64` are considered, other machine architectures are ignored. Side effects: file handle position due to seeking :param fh: file like object :param start_offset: offset to start searching from, None indicates from current file position :param maxrange: how far to search for into the file object :returns: ``"x86"`` or ``"x64"``, ``None`` if not found.