The security world has been abuzz over a new code injection technique called "atom bombing" (see Injection Attack Description and Information Security Stack Exchange Question). Simply stated, an attacker can use atom tables to store executable code.
A concern is that the global atom table feature exists across all versions of Windows, and is a deliberate feature, not a bug. It is not clear how to mitigate the threat through changes to Windows.
Just what are Windows atom tables used for? If Microsoft simply said "that's it, no more atom tables", what would be the impact?
TL;DR: I personally don't think Microsoft is going to make any changes to the global atom table because it is only a minor security issue.
An atom table lets you associate a string with a 16-bit number. You give Windows your string and it gives you back a number. You can then retrieve the string again just by knowing the assigned number.
Every normal process has its own local atom table but it is usually empty and is not a security issue.
There are multiple "global" atom tables that are shared by all processes in the same window station. 1 of them is documented and it is called the global atom table. MSDN is also nice enough to tell us that RegisterClipboardFormat
and RegisterClass
also use their own atom tables internally in their current implementation. Other functions like SetProp
also use atoms but we are only interested in the atom table used by the exploit and atoms are added to that table with the GlobalAddAtom
function.
The main purpose of this atom table is to act as a simple storage location so that different processes can communicate with each other in a protocol called DDE. When a process wants to send a message to a window in a different process you cannot send more than 8 bytes (2 parameters, 4 bytes each) and this is not enough space to transfer a filesystem path or a URL.
To work around this limitation the application stores the string/path/URL in the public global atom table by calling GlobalAddAtom
. GlobalAddAtom
returns a number that the application can send to the other process. When the other process receives the DDE message it just passes the number to the GlobalGetAtomName
function to retrieve the string.
How is any of this a security issue? It turns out that this overhyped (IMHO) exploit uses the global atom table to do exactly what the table was designed to do; transfer a string from one process to another.
To inject code into another process you would normally call OpenProcess
to get a handle to the desired process, VirtalAllocEx
to allocate some memory in this process, WriteProcessMemory
to fill this newly allocated memory with your code and finally CreateRemoteThread
to start executing this code.
The exploit basically calls GlobalGetAtomName
in a complicated way (NtQueueApcThread) to avoid using WriteProcessMemory
. It is more impressive how it builds a ROP chain and executes it with NtQueueApcThread
but that is not really related to the atom table, the atom table was just a unusual/clever way to transfer memory.
The exploit does not allow evil code to elevate or otherwise get privileges the source process does not already have because NtQueueApcThread
cannot be used on any random process, you still need the appropriate privileges to access the desired target process. NtQueueApcThread
might have caught some anti-virus companies off guard when the exploit came out but as a standalone piece of code that has to be executed by someone in the first place it cannot do much damage on its own, it has to be combined with other code to be scary.
Can Microsoft remove the atom tables? No, not really, the other tables are too important.
Can they remove the global atom table? No, not really, it is a documented API and has been for more than 20 years and Microsoft does not like to break compatibility.
They could however neuter the global atom table a little. They could make it less global by dividing it into multiple compartments based on the integrity level of the calling process. This would not change the exploit in question since it cannot access processes with a higher integrity level in the first place.
If we pretend that Microsoft changed the global atom table so that it acts as a per-process table, what would happen?
Microsoft started to move away from DDE in Windows XP but got a lot more serious about it in Vista/7. On this Windows 8.1 machine Internet Explorer still uses DDE for the "Open in same window" command but that is not the default verb for a .html file. Search the registry for ddeexec
to find all the applications that use DDE to handle its file associations. On the bright side, file association DDE is only used when a instance of the application is already open. Worst case scenario; close the application before double-clicking a new file.
DDE can also be used to do other things but it is hard to say which applications and/or features would break and how broken they become.
The global atom table can be used for things other than DDE but it is hard to say how common it is to do so.
If the global atom table was restricted to only sharing its strings to processes with the same filename then a lot of these issues would go away because it is often used to just communicate with other instances of the same application.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With