dissect.cobaltstrike.pe

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

Module Contents

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.

Attributes

logger

PE_DEF

pestruct

DOSHEADER_X64

DOSHEADER_X86

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