Recently, the enSilo Research Team documented a new twist on process injection for Windows systems they dubbed “AtomBombing.” Process injection is a technique often leveraged by attackers to execute code in the context of another process.
Many of the articles written about this technique have portrayed AtomBombing as a vulnerability, an exploit, and a threat to all users. After investigating this technique, it becomes clear that these exaggerations are not true. Additionally, Carbon Black’s approach to the problem via behavioral prevention in Cb Defense, detects on the technique as used in the PoC.
AtomBombing introduces a variation on other, known injection techniques, but does not provide an attacker with any more leverage than previously existed.
Looking at the deep dive and proof of concept code, there are some familiar concepts being used. Queuing APCs (Asynchronous Procedure Calls) to another process is an injection technique that has been in use for many years (see Conficker). SetContextThread, OpenProcess, and OpenThread are common in malicious programs as well.
The use of Windows Atom tables to make the shellcode accessible in the target process is a novel concept and worth exploring. It’s important to recognize this technique itself cannot elevate privileges. It is purely a means of injecting code into another process that the malicious process has the security permissions to do so. While the shellcode storage aspect is unique and would prove useful in certain scenarios such as minimal stack space for exploiting a buffer overflow, using NtQueueApcThread brings this back in line with known injection techniques.
Atoms are used by applications for storing strings and integers in memory. They can be “local,” in which case the stored items are only accessible by the process that creates them. They can also be “global,” where any process connected to the same window station can access them.
The relevant APIs used for this technique are GlobalAddAtom() and GlobalGetAtomName() – the ‘global’ flavors of the Atom APIs. Strings stored as atoms are not capable of being executed as code since atoms are not directly accessible. The data in them has to be copied into a memory buffer in the target process somehow.
The author uses a technique known as Return Oriented Programming (ROP) to allocate executable memory in the target process, copying in the non-executable shellcode which was stored in an atom, and then executes it.
Proof of Concept
Below is a breakdown of the steps involved for this injection mechanism, as demonstrated in the PoC code:
- Open a target process
- Find an alertable thread and open a handle to it
- Essentially find a thread that can have an APC queued to it
- Find a codecave in the target process
- This is RW space to store shellcode temporarily
- The author used space just after the data section (.data) of kernelbase.dll
- Generate a ROP chain consisting of a call to ZwAllocateVirtualMemory, and then a call to memcpy, and then a ret instruction
Here is where the new behavior occurs in order to inject into the target process. This is done multiple times for each set of data that needs to be injected:
- Create a new atom using GlobalAddAtom with the data as the atom name
- Suspend the target thread
- Use NtQueueApcThread API to essentially call GlobalGetAtomName(), which will copy the atom name data into the code cave found above
- Resume execution of the thread
Once all the pieces have been injected into the target process, the PoC code gains execution using the ROP chain:
- The thread context of the target thread is changed to execute the ROP chain
- The ROP chain allocates RWX memory (ZwAllocateVirtualMemory) and copies the shellcode to the newly allocated memory using memcpy
- Shellcode is executed
AtomBombing vs. Cb Defense’s “Streaming Prevention”
Utilizing Streaming Prevention, Cb Defense detected this technique as code injection for more than one year prior to the release of the PoC.
This allows Cb Defense to not only evaluate every event, but also the relationships of events across an entire attack sequence. It applies TTP (tools, tactics and procedures) tags and associated risk scores to every event, and keeps a running real-time risk score of the sequence to trigger allow/deny decisions.
Streaming Prevention monitors every running process for the use of potentially malicious behaviors and has the ability to either prevent specific actions or terminate an offending process altogether. This method of prevention is crucial in the protection of unknown malware, malicious scripts, malicious documents, and malicious use of native operating system tools.
Cb Defense monitors many APIs that are used to perform various malicious actions. The API’s used to inject code into another process allow Cb Defense to detect and monitor the future actions of the injected process, building a reputation along the way.
Because AtomBombing uses one of the APIs commonly used to inject code, Cb Defense can monitor the actions of the potentially infected process. Based on the policy set for the system, the historical data of the injection can be used to protect the system. Since this technique has been documented, we will be improving the detection, alerting and prevention capabilities of the product.
In short, Cb Defense customers were already detecting (and alerting on) this technique before the release of the PoC last week.
Overall, this ends up being a very small, but useful variation on a known process injection tactic. Regardless of where the shellcode is stored, gaining execution using the NtQueueApcThread call as utilized in the PoC will result in detection of the injection technique.
Products such as Cb Defense clearly show the process is currently being detected as injection by an unknown application. The mechanism for storing the shellcode is novel and may fly under the radar of some AV products, but the other necessary components of the injection will stand out.
While there are some innovative aspects to this new technique, it is important to cut through media hype and understand that there’s not really all that much new to see here and put this new variation on an old technique into context.