dissect.cobaltstrike.pe

This module contains helper functions for parsing PE files, mainly for extracting Beacon specific PE artifacts.

Attributes

logger

PE_DEF

pestruct

DOSHEADER_X64

DOSHEADER_X86

NT_SIGNATURE

OS2_SIGNATURE

IMAGE_DOS_SIGNATURE

Classes

LenientPE

Wrapper around dissect.executable.PE that is lenient towards invalid PE signatures.

Functions

find_mz_offset(→ Optional[int])

Find and return the start offset of a valid IMAGE_DOS_HEADER or None if it cannot be found.

find_compile_stamps(→ Tuple[Optional[int], Optional[int]])

Find and return a tuple with the PE compile and PE export timestamps.

find_magic_mz(→ Optional[bytes])

Find and returns the MZ header bytes or None if cannot be found

find_magic_pe(→ Optional[bytes])

Find and returns the PE header (magic_pe) bytes or None if cannot be found

find_stage_prepend_append(→ Tuple[Optional[bytes], ...)

Find and return the stage prepend and append bytes as a tuple.

find_architecture(→ Optional[str])

Find and return the PE image architecture, either "x86" or "x64" or None if not found.

Module Contents

dissect.cobaltstrike.pe.logger[source]
dissect.cobaltstrike.pe.PE_DEF = Multiline-String[source]
Show Value
"""
#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;
"""
dissect.cobaltstrike.pe.pestruct[source]
dissect.cobaltstrike.pe.DOSHEADER_X64[source]
dissect.cobaltstrike.pe.DOSHEADER_X86[source]
dissect.cobaltstrike.pe.NT_SIGNATURE[source]
dissect.cobaltstrike.pe.OS2_SIGNATURE[source]
dissect.cobaltstrike.pe.IMAGE_DOS_SIGNATURE[source]
class dissect.cobaltstrike.pe.LenientPE(fh: BinaryIO)[source]

Bases: dissect.executable.PE

Wrapper around dissect.executable.PE that is lenient towards invalid PE signatures.

This is accomplished by using an OverlayStream to patch the PE signature when it’s invalid.

It currently overlays the following fixes:

  • Invalid PE signature (not “PE")

  • Invalid MZ signature (not “MZ”)

dissect.cobaltstrike.pe.find_mz_offset(fh: BinaryIO, start_offset: int = 0, maxrange: int = 1024) int | None[source]

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

Parameters:
  • fh – file like object

  • start_offset – offset to start searching from, None indicates from current file position

  • 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

dissect.cobaltstrike.pe.find_compile_stamps(fh: BinaryIO, start_offset: int = 0, maxrange: int = 1024) Tuple[int | None, int | None][source]

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

Parameters:
  • fh – file like object

  • start_offset – offset to start searching from, None indicates from current file position

  • 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.

dissect.cobaltstrike.pe.find_magic_mz(fh: BinaryIO, start_offset: int = 0, maxrange: int = 1024) bytes | None[source]

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

Parameters:
  • fh – file like object

  • start_offset – offset to start searching from, None indicates from current file position

  • maxrange – how far to search for into the file object

Returns:

MZ header bytes or None if not found.

dissect.cobaltstrike.pe.find_magic_pe(fh: BinaryIO, start_offset: int = 0, maxrange: int = 1024) bytes | None[source]

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

Parameters:
  • fh – file like object

  • start_offset – offset to start searching from, None indicates from current file position

  • maxrange – how far to search for into the file object

Returns:

PE header bytes or None if not found.

dissect.cobaltstrike.pe.find_stage_prepend_append(fh: BinaryIO, start_offset: int = 0, maxrange: int = 1024) Tuple[bytes | None, bytes | None][source]

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

Parameters:
  • fh – file like object

  • start_offset – offset to start searching from, None indicates from current file position

  • 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.

dissect.cobaltstrike.pe.find_architecture(fh: BinaryIO, start_offset: int = 0, maxrange: int = 1024) str | None[source]

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

Parameters:
  • fh – file like object

  • start_offset – offset to start searching from, None indicates from current file position

  • maxrange – how far to search for into the file object

Returns:

"x86" or "x64", None if not found.