2020-11-27: added Microsoft.Windows.SystemCompatible sideloading & Windows Side-By-Side manifest abuse & KnownDLLs abuse
2020-08-14: added NtCreateProcess section reuse & TLB abuse
2020-04-10: added some less known techniques
This post is not about a single injection. It is about a class on its own.
At the moment I know of only two instances of code injection/execution that fit this category perfectly, and I am going to describe them below, but I bet there is more…
First of all, why ‘plata o plomo’? It’s obvious. In today’s world every security research needs a cheezy name ;), right?. Secondly, the ‘plata o plomo’ fits the cases perfectly – it’s ‘either silver, or lead’. And when it comes to code injection/execution – it’s definitely a lead. Or Ulead.
Okay. What about the actual ‘code injection/execution’ bit?
This Endgame post presents a very comprehensive overview of what was out there back when it was written in 2017. It’s a great starter for anyone interested in this topic. However, many things have changed since it was posted + the article omitted a number of interesting techniques anyway.
The below is a summary of all existing code injection tricks that I know/could think of (ping me if I missed anything):
- Abusing popular NT / Win APIs and built-in Windows mechanisms:
- windows hooks
- windows event hooks
- asynchronous loading of printer DLLs (note: the link leads to only one of many APIs abused for this purpose, but there are many others: AddMonitor,AddPrinterDriver,AddPrintProcessor, AddPrintProvidor)
- remote threads (again, many variations exist)
- thread state manipulation (win, and NT API variations)
- debugging functions (win, and NT API variations)
- Asynchronous Procedure Calls (APC) (win, and NT API variations)
- process hollowing
- surgical memory patching (e.g. of ntdll!NtClose)
- Shim injection
- Note: techniques listed above are so common that I don’t need to describe them in detail; they have been used and abused for many years; you may find a lot of info about them by clicking the links, and googling around
- GUI manipulation (less a code injection trick, and more an evasion trick, but including here since it may make some sandboxes/EDRs blind to e.g. processes launched asynchronously via a keystroke sequence sent to Windows Explorer, hot keys, etc.)
- Viral infections/Targeted patching of binaries (old-school in general, but still present in very targeted attacks; I have seen subtle file modifications to ATM and IIS Plug-in binaries — exe/dll that aimed at loading additional malicious components when the main file is loaded)
- Old, and novelty persistence mechanisms (many can be used to load code not only persistently, but also stealthily, and as a one-off, or for long-term persistence purposes, or for a quick, temporary lateral movement, e.g. dotlocal trick)
- Windows shatter attacks (e.g. original shatter attack using WM_TIMER, propagate and its 64-bit and clipboard variants, wordwarping, hyphentension, autocourgette, Streamception , oleum, treepoline, listplanting) – theoretically, it should be in the ‘Abusing popular NT / Win APIs and built-in Windows mechanisms’ section, but it’s so fertile in available code execution tricks that imho it deserves its own bullet point
- Lolbins, Side-loading and phantom DLLs
- Path companion
- Process Doppelgänging [PDF warning]
- ALPC injection
- Conhost injection
- Spooler injection
- Service Control Handler injection
- KernelCallbackTable injection (used by FinFisher / FinSpy)
- Shim re-use (Shimbad)
- TLB abuse [PDF]
- Windows Side-By-Side manifest abuse [PDF warning]
- KnownDLLs DLL abuse/redirection [PDF warning, same PDF as last point]
- Microsoft.Windows.SystemCompatible sideloading
- NtCreateProcess section re-use
- and… finally… any sort of vulnerabilities e.g.
- wrong ACL – e.g. software installing services that point to user-overwritable .exes, or use unprotected Registry keys, or rely on HKCU keys that can be manipulated, etc. –> result being often at least escalation of privileges
- good ol’ path interception e.g. c:\Program Files vs. c:\program.exe
- Process Injection via ETW registration entries
Notably, the last few links on the list above are leading to modexp.wordpress.com blog. After reading it for a while, and talking to author on a couple of occasions, and finally eyeballing the github repo associated with posts and older work of the author, I can only bow to this programmer’s coding, and manual code crafting skills! This blog is really high on my list and I highly recommend it!
Anyway… back to the topic of this post:
- What if I told you… that there are developers our there that make the whole game of code injection extremely easy? No trickery, no code trampolines, no obscure undocumented structures, not even forgotten, legacy code paths, windows shattering, let alone ROP, gadgets to be relied upon. None whatsoever needed.
- What if I told you that you can just provide an address of the code you want to execute in a nice, user-friendly way ?
- What if this code actually executed according to your wishes ? In User or Kernel mode.
- What if I told you the programs facilitating this are signed as well?
In other words: what if code execution/injection was there ‘by design’?
Yes… it’s a mind blowing idea. And yes, as I stated before in my Law Of A Threat Hunter (LOATH):
For every two distant technologies there exist a developer that will bring them together.
So… if you can find such program / driver you get a clean shot at a golden opportunity – a signed process or DLL offering a controlled code execution, and then most likely an AV/EDR bypass. And as I mentioned earlier – there exist at least 2 such applications/kernel drivers that I am aware of that fit this description perfectly, and I bet there are more.
Cuz… if it is signed, then it’s good. Right?
I first heard of Capcom driver from the zerosum0x0 blog (yet another great blog to follow!). The post I linked to introduces a tool called puppetstrings that tries to exploit the vulnerability in a aforementioned capcom driver. The vulnerability is actually supersilly – when you send a special IOCTL request to the capcom driver, it will temporarily disable Supervisor Mode Execution Protection Enable (SNEP) mode, call a callback procedure controlled by the user (in a user address space), then return and restore SNEP state…
How crazy is that? I mean: HOW CRAZY IS THAT ?
When I read about it and the whole concept of ‘Bring Your Own Vulnerability’ (BYOV) for the first time I actually really liked the idea and thought it could be expanded to Bring Your Own Functionality (BYOF). I speculated that there are other applications/drivers that are written in a sloppy way, all for good reasons though – and they may not even need any vulnerability at all! And I finally found my first.
In fairness, I have been actually toying around with the concept of reusigned binaries for a while. Lolbins are easy wins, low-hanging fruits, but there is tones of other legitimate software out there that gives clever users more than the developers meant to. We can re-use signed binaries to give us keylogging capability, kill a process, wipe a drive, spawn a new process if we need it, and modify Registry, install Services, and so on and so forth. Not only it is an interesting area for research – I actually believe that this is an inevitable future of many pentesting or red team engagements, let alone nation attacks. And some of the existing attacks already show that a possession of signed drivers/software that can be used for BYOV/BYOF can be leveraged to bring a lot of havoc – e.g. signed EldoS RawDisk drivers were used by Shamoon to wipe out the orgs’ media.
Welcome the ‘Plata o plomo’ contestant number 2.
Ulead Burn.Now 4.5 is an old app from year 2007 that was used to burn ISOs on CDs/DVDs. Nowadays this feature is not really needed – the whole cloud buzz makes cloud so popular and offers far more space & flexibility that the old (and dying) media burning industry can’t really compare. As far as I can tell this Ulead app is no longer updated, but the beauty of good old is that it is out there.
Now, for the juicy part. Apart from doing what it was meant to, the application (or at least this particular version) includes a very interesting feature (most likely for testing purposes):
- If you set a specific environment variable to a certain decimal value the app would retrieve it during run-time, convert it into an address, and finally…. make a code jump to that address!
Yes. You hear that right. OMGWTFBBQ. You can literally tell the app to execute your shellcode from a specific location in memory!
Let’s start with a name of that Environment variable:
In the below demo I set it to 195936478 (0xBADC0DE). and then run the application under Olly to demonstrate when the main program jumps to the 0xBADC0DE location:
You may be concerned about required UI interaction. This is actually not an obstacle. If one was about to use it maliciously, one could engage basic GUI automation techniques to ‘click’ that OK button. It’s actually pretty trivial with available APIs (e.g. FindWindow, or enumeration via EnumChildWindows to find the required window, then sending WM_COMMAND/BN_CLICKED, WM_LBUTTONDOWN, etc messages to the button window).
Also, the name of the environment variable is present in a number of components of this application, including a number of DLLs. As such, there is a high possibility that one could simply instrument these DLLs to execute the shellcode e.g. via a customized DLL loader (provided we injected a shellcode beforehand).
A quick grep for GLOBAL_HOOK_ENVIRONMENT_STRING inside the installation directory (c:\Program Files\Ulead Systems\Ulead Burn.Now 4.5 SE) shows the following list of files that include a reference to it:
All of them are signed. So it’s almost certain that _some_ of these could be loaded outside of the main program, and then instructed to execute the shellcode.
Coming back to where this post started – when it comes to ‘Plata o plomo’ and code injection – it’s always the lead. Developers make and will make stupid mistakes, they write and will write code that is often meant to be only used internally, but sometimes it will make it out to the releases available to general public, and into signed packages.
The lesson learned is that what is green on VirusTotal is never green from a blue teamer’s perspective. We need a better process (and a long way) to declare things ‘truly green’ for that matter. For a long time now we know that the authenticode signatures are just an ersatz of security and while always useful (better to have them than not to), we should no longer rely on them blindly.
Future attacks will engage signed binaries more. There is no doubt. We need a dedicated team of analysts in every security companies to start looking at vulnerabilities present in these, and also ‘built-in’ features that make the ‘green’ VT stuff vulnerable to abuse. Again, I am more than certain there is a lot of this stuff out there. Only a few weeks ago @Oddvarmoe published his findings about the 7z binary he found that is signed by Nvidia. Any such ‘signed popular tool’ instance is interesting from at last two angles:
- It is signed+ ‘perceived as good in general’, so may (and most likely will) sneak in through EDR/AV filters
- if it is old version enough, it may include many interesting vulnerabilities – – some may allow to execute shellcode or do some other funny stuff
As such… the era of Lolbins, BYOV, BYOF will catch many companies off-guard.