The recent discovery of vulnerabilities in antivirus software by enSilo sparked curiosity among the Morphisec Labs team. After a long deep dive and to our surprise, our research found that the vulnerability wasn’t an unintentional flaw in the code, it was a feature! Here is how it works.
First of all, we wondered how such a major vulnerability existed in these security products. And, how come a similar vulnerability appears over and over again in different security products from different companies?
Naturally, each product is based on its own different source code and thus have different bugs, but the phenomenon that was identified was at odds with that. So in our lab we tested these vulnerable products and several others, such as DLP, Application Privilege Management, and Anti-Keyloggers. We identified that the same read/write/execute (RWX) vulnerability shows its face in all of these different product categories, mostly in endpoint security products but also in other types of products.
As we exposed the same type of vulnerability in some very popular endpoint software products, we have taken the immediate measure to notify the respective vendors with the specific details and doing that we hope that we somewhat helped them to create a fix. We are happy to report here that one provider reacted very fast and already released a new version, that overcomes this vulnerability.
A CAPABILITY, YET A FEATURE
The more we found that the same vulnerability exists in different products, even though they don’t originate from the same vendor, the more curious we got about the nature of the vulnerability. This led to our realization that it was actually a feature, and not a vulnerability. It is a “capability”, hence we coin it a “feature”, that required by a broad category of endpoint products and security products, as well as any product that requires deep integration with the way the operating system works. To be more specific, it is built into products that need to integrate with running applications for reasons varying from protecting the application to monitoring behavior and performance.
The endpoint security products we investigated require that part of their code runs inside the memory space of the host running the applications. Technically, there are different approaches to get into the memory space of a host application such as Kernel drivers injection (IAT patch, APC, etc.), user mode injection (createRemoteThread, APC, etc.), registry AppInit injection, IntroProc32 injection and others.
WHEN CODE INJECTS GET DANGEROUS
Most of the vulnerable products we identified used the technique of code injection into the process from a kernel driver. There are good reasons to prefer this kernel driver approach, mainly control and simplicity: one can use a single physical memory address to inject code across multiple processes which are mapped to the same address from their virtual user space. In addition, you can also inject early enough when the process is created, and Microsoft lets you use their callback APIs like psCreateProcessNotify routines in a very convenient way. This approach is considered legitimate as long as the injected application and the kernel driver are digitally signed. Today this is the preferred method for getting one’s code to run inside host applications. There are common tools that provide this capability out of the box. But the same capability leads eventually to the same vulnerability.
The vulnerability itself is in the way the injection is implemented. The code / shellcode that is injected into the user process keeps its RWX (read, write, execute) privileges and in many cases, it is also injected into the same predictable address. This combination makes ASLR and DEP irrelevant and obviates the need of the attacker to use ROP or stack pivoting.
But why keep all the RWX permissions? The answer is flexibility and compatibility. Keeping these permissions allows counting the number of injections, enables reinjection and reuse of part of the shellcode, and permits validating the integrity of injected code. It even allows to dynamically unload the injected code. This memory space first and foremost is used to execute shellcode that eventually loads the library dll into the process (using ldrLoadDll, LoadLibrayEx and more).
OPEN DOORS FOR HACKERS
How can an attacker exploit this "feature" to compromise the endpoint? It’s very simple – it can be done via any application running on the endpoint that is “protected” by the security product. It does not matter that the makers of applications such as Adobe Flash, Silverlight, Microsoft IE and Office are hard at work trying to mitigate their vulnerabilities. Once these host applications are being "infected" by an endpoint security product using this injection technique, they become vulnerable. Once an application is vulnerable, a simple buffer/integer/stack-overflow, use-after-free or type confusion vulnerability will allow the attack to hijack the application flow and the shellcode can be written to and executed from the predictable memory address. That's all, game over for the endpoint. It is a vulnerability in a security product that replicates and infects every application running on the endpoint, infecting it with this vulnerability. Because it is a trusted application (legitimately acquired and willingly implemented by the end customer), in effect it can become a Trojan, a back door for other attacks.
SO WHAT CAN ENTERPRISES DO?
Unfortunately stopping the use of Flash / Java / Silverlight will not help this time as the vulnerability exists in every so-called “protected” application. Stopping the usage of these kind of vulnerable security products is also not advised as it will create other uncontrolled risks. The only thing to do is to make sure your vendors are aware of this plague as soon as possible and make sure their products are not compromising your endpoints.
Another alternative is to use new generation of prevention security products that overcome these issues. A new generation of security products in the category of Moving Target Defense (MTD) is being developed. Morphisec’s Endpoint Protectors are immune to such vulnerabilities. In the case of Morphisec, the core proposition is that it randomizes addresses in the memory space of any and all host applications, including those introduced by the vulnerability, thus protecting the endpoint from zero days or unpatched vulnerabilities, including those introduced by other well-intentioned security products.