There are three primary components that constitute
- Creation of a version info resource
- Creation of a self-signed certificate chain
- Assembly of a .NET EXE or DLL on the fly
Version info resource creation
Version info comprises a binary resource that is embedded within a PE file. It is an optional component that is useful for indicating file properties that are independent of the PE file format, including original filename, file version, and description. These fields may also be used as the basis for application control enforcement as is the case with Windows Defender Application Control (WDAC).
Typically, in order to generate a version info resource, an IDE like Visual Studio or a developer tool like Resource Compiler,
rc.exe, is required. We didn’t want to have a dependency on developer tools that are unlikely to be installed, however. Additionally, there is no built-in .NET class that can build PE resources on the fly. These constraints resulted in the decision to build the binary bit by bit, manually. Fortunately, with the help of a hex editor and good documentation, building the binary resource was accomplished without any hurdles that couldn’t be cleared.
Self-signed certificate generation
New-ATHPortableExecutableRunner creates and replicates the fields of existing code signatures by using the certificate property cloning features of the
New-SelfSignedCertificate cmdlet. By default, the certificate chain that
New-ATHPortableExecutableRunner uses to sign the new executable will not result in a valid signature because self-signed certificates are not trusted as root certificates. Non-privileged users can, however, add certificates to their user-specific root chain, which can trick EDR solutions into reporting that it is a valid, trusted certificate chain.
New-ATHPortableExecutableRunner does not automate trusting the created certificate chain, as that is out of scope of the MITRE ATTACK® technique it aims to replicate: T1204.002: User Execution: Malicious File.
New-ATHPortableExecutableRunner is used to clone existing signature properties, the following fields are cloned:
- Subject name: Issuing certificate
- Serial number: Issuing certificate
- Certificate creation datetime: Issuing certificate
- Certificate expiration datetime: Issuing certificate
- Subject name: Leaf certificate
- Serial number: Leaf certificate
- Certificate creation datetime: Leaf certificate
- Certificate expiration datetime: Leaf certificate
.NET EXE and DLL assembly
New-ATHPortableExecutableRunner with hopes that it could easily build either an EXE or a DLL with a specified export function. PowerShell makes it easy to build an EXE or a DLL on the fly with a cmdlet like Add-Type, but unfortunately there is no built-in method of specifying an export function. It is possible, however, to specify a .NET method as an unmanaged export function in intermediate language (IL) bytecode using the .export directive.
In order to get unmanaged export functions working,
New-ATHPortableExecutableRunner embeds pre-assembled .NET bytecode where it is updated based on the specified export function name and ordinal. Then, it drops the generated IL code to disk, along with the generated resource (
.res) file, and generates the desired executable using the built-in IL assembler utility,
Hopefully, now you have a better understanding of the extent to which an adversary has control over the PE metadata logged by many EDR solutions. We encourage you to approach using PE metadata as a basis for trust with additional skepticism. Robust, durable detections focus more on behavior and do not have an overreliance upon PE metadata. Where
New-ATHPortableExecutableRunner replicates the “look” of an executable, it cannot, by default, replicate the “feel,” i.e., the behavior of an executable. However, since it allows for a user to supply custom PowerShell scriptblock code, behaviors can be replicated when PowerShell code is developed to do so.