Malware Essentials

  • The implane/agent of most C2 frameworks are written as Windows DLLs.
  • Because DLLs are normally ran from disk which we dont want, we pair it with a loader to load it from memory
  • The C2 framework outputs this DLL + loader combination as shellcode (.bin file)
  • In order to run, shellcode must be injected into memory and then a new thread is created to execute it
  • ready-to-run payloads are made available by frameworks such as .exe, .dll, and .ps1 files

PE file structure

Portable Executable (PE) files carry information about a program necessary for loading it into memory. Both .exe and .dll files are PEs

DOS header

The DOS header is a fixed 64-byte strcture called IMAGE_DOS_HEADER that exists at the start of every PE file. Two members of this header to know are:

  • e_magic : First member and is a 2-byte WORD. The vaue is always 4D 5A or MZ. Its a signature that marks the beginning of the PE file
  • e_lfanew : Last member and is a 4-byte LONG. Contains an offset to the PE signature at the start of NT headers. Always located at an offset of 3C (60 in decimal) from the start of the PE file

DOS stub

The DOS stub is only used when the PE file is executed under MS-DOS, which prints the message This program cannot be run in DOS mode. This stub doesn't have an official pre-defined size, so the modern Windows loader uses the offset in e_lfanew to skip over this stub and go directly to the NT headers (described below).

NT Headers

There are 2 definitions of NT Headers. One for 32-bit PEs IMAGE_NT_HEADERS and 64-bit PEs IMAGE_NT_HEADERS64

  • PE signature : 4-byte DWORD that always has a fixed value of 50 in order to veridy the start of the NT header has been correctly located
  • File header : structure called IMAGE_FILE_HEADER that has 7 members. Some include:
    • machine : a 2-byte WORD that indicates the CPU architecture the PE is compiled for
    • NumberOfSections : a WORD that holds the number of sections the PE has
    • SizeOfOptionalHeader : a 2-byte WORD that holds the size of the optional header
    • Characteristics : a 2-byte flag that describes attributes of the PE
  • Optional header : structure that can either be IMAGE_OPTIONAL_HEADER32 or IMAGE_OPTIONAL_HEADER64depending on the PE architecture. Some key members include:
    • magic : value that determines whether the image is PE32 or PE32+ (64 bit)
    • AddressOfEntryPoint: the address fo the PEs entry point relative to the image base when loaded into memory
    • ImageBase : the preffered base address for the PE image to be loaded into
    • NumberOfRvaAndSizes : the size of the DataDirectory array
    • DataDirectory : an array of IMAGE_DATA_DIRECTORY structures

Data directories

IMAGE_DATA_DIRECTORY struct has 2 members: VirtualAddress which points to the start of a data directory struct, and Size which is the size of that data directory. The directories contain info needed by the loader

Sections

Contains the actual data and executable of the program. Includes:

  • .text : the executable code of the program
  • .data : intialized data
  • .bss : unitialized data
  • .rdata : read-only data
  • .rsrc : resources used by the program such as icons

Each section is appended to a header that describes it. Each header contains:

  • Name : limited to 8-bytes
  • VirtualSize : size of the section when loaded into memory
  • VirtualAddress : the memory address of the section when loaded into memory
  • SizeOfRawData : the size of the section as it is stored on disk
  • Characteristics : set of flags that describe the charactertistics (R, RX, RW)