Implant targeting can be a useful tool in your arsenal; instead of developing weaponized malcode that will execute on arbitrary systems, we can take precautions to protect the confidentiality of our payloads while ensuring deployment occurs only on targeted (intended) assets.
Why should we, as red teams, care that our payloads are executed on targeted systems? While there are arguably many reasons, the most obvious is to ensure that they do not end up being executed on unintended targets. This ensures that we don’t accidentally violate rules of engagement due to errors made on behalf of the red team or circumstances out of our control. The second, and perhaps less obvious reason, is that not only can we leverage these checks to verify we are about to deploy in our target environment, but we can actually implement these checks in such a manner that they become mandatory pre-requisites to successful payload deployment.
A simple implementation of this concept would be to create a number of functions that check for various environmental conditions that we expect to be present on the target. If any of these checks fail, our implant can exit gracefully or perform some arbitrary action without exhibiting malicious behaviour. As an added bonus, we could perhaps have the implant wipe itself from disk before it exits.
A more effective implementation may be to leverage environmental conditions as inputs to hashing functions and crypto systems. Thus, only the expected target-specific output of these inputs would yield successful payload execution.
This kind of functionality requires the development of two mechanisms:
- A payload preparation, encryption, and implant generation tool
- An implant that collects system conditions, uses them to derive cryptographic material, and then decrypts the payloads and executes.
In practice, many red teams rely on commercial or open source post-exploitation tool sets. A robust and widely-utilized commercial solution is Cobalt Strike. While modern red teams will put forth an effort to execute in-memory only, there are situations where writing an implant to disk may be unavoidable; niche lateral movement and persistence techniques come immediately to mind.
While Cobalt Strike’s staged Beacon implant provides a number of disk-based obfuscation / encryption mechanisms, the default functionaly leverages an XOR additive cipher with pseudo-randomly generated 4-byte keys. This basic cryptosystem is effective, however there are some noteworthy drawbacks in relation to our use case:
- The XOR key is embedded in the output. Embedded the key in the output does not force the target asset to derive it, nor does it present significant deterrent to reverse engineering efforts.
- XOR encryption is only implemented for staged payloads. While staged payloads can be used, the initial staging is unauthenticated, unencrypted, and may trigger perimeter controls. Valuable information on this topic can be found at What is a stageless payload artifact (Raphael Mudge).
Note: While the above noted drawbacks are true for ‘out-of-the-box’ deployments, Beacon outputs can be customized using Cobalt Strike’s Artifact Kit (Strategic Cyber LLC).
To get around these limitations, we can wrap a stageless beacon in a custom written loader that will collect various target conditions and leverage hashed output of the same as key material input for decryption of an already encrypted payload.
The key takeaway from this approach is that we do not store the decryption key within the implant or our loader. Instead, only the combined information of target conditions will generate the correct key material to decrypt the payload. We gain two notable benefits from this approach:
- Our payload becomes extremely difficult to reverse engineer without specific and detailed knowledge of the target
- Our payload will not deploy on unintended targets. If we choose appropriate conditions, this can include modern and traditional sandboxes.
The diagrams in the following sections illustrate example process flow for loader generation and utilization.
Loader Generation Process
Loader Utilization Process
Useful Conditions for Targeting & AV / Sandbox Evasion
- Domain Membership
- Check the domain membership of the target
- Domain FQDN
- Check the domain FQDN and ensure that it matches the target
- This can be effective against perimeter sandboxing solutions as it is unlikely that sandbox VMs are members of the target domain
- File & Folder Presence
- Check for the presence of target-specific directories and files
- Optionally, perform a hash of the file to ensure the data exists and conforms to expectations
- Host name
- In situations where the specific target host name is known
- May be more useful for lateral movement
- Number of CPUs / Cores
- Check the number of CPUs and cores in use by the target
- Running Processes
- Check for specific processes that the target should / should not be running
- Installed Services
- Check for installed services specific to target
- Environment Variables
- Check for the presence or lack of target-specific environment variables
- Check that the RAM size is appropriate to your target
- Disk Size
- Check that the disk size is appropriate to your target
- Check the system uptime.
- Targets are likely to have an uptime of a day or more, while sandboxes may report drastically shorter uptime
- Registry Keys
- Check for the presence or lack of target-specific registry keys
- Temporary Files
- Check for the presence of temporary files
- A ‘real’ system likely has files present in these directories
- MMX / SSE Support
- Some virtualization engines used by sandboxing solutions do not support MMX and SEE instruction sets
The above examples are certainly not exhaustive, rather, they are provided to establish some baseline for further development. We can expect that evolution of defensive controls will result in sandboxes that are increasingly more capable of condition deception. For this reason, it is perhaps good practice to curate a repository of conditions that are less known or bespoke to your target. Detail concerning implementation of some of the aforementioned condition checks can be found at Enumerating Anti-Sandboxing Techniques (Hans Lakhan) and Detecting MMX & SSE (Stefano Tommesani),
Considerations & Limitations
- While the payload is encrypted and will vary with unique shellcode and key combinations, the decryption functionality within the implant will be static. This presents an opportunity for signature based detection. The standard plethora of malcode-leveraged obfuscation methods may be helpful in introducing some entropy to these decryption stubs. Some useful resources on these topics include Polymorphic Encryption Algorithms (Bartosz Wójcik) and Obfuscator-LLVM Project (HEIG-VD). Obfuscation techniques can be applied to the entirety of the source, increasing difficulty in reverse engineering target condition checks as well as the decryption stub.
- Consider utilizing the wincrypto API for key derivation and decryption instead of writing custom implementations. This API is leveraged by many benign / legitimate binaries, thus making it less likely to trigger host-based defensive controls as well as allowing for a more compact decryption stub.
The concepts we have explored here are a brief glance at the entrance of a very deep rabbit hole. The reader is encouraged to start with these ideas and see where time and iterative refinement take them.