The interaction between red and blue teams during and following exercises are the best opportunities for lessons learned and progressing our respective crafts. When the red team gets caught or can't get in, that's feedback forcing them to improve their trade craft. When the blue team misses something, the feedback from red after they present their plunder (i.e. control of your domain or access to critical data) forces them to adapt to more advanced techniques. This process is only possible in the red/blue relationship, as real adversaries typically don't give feedback.
A recent case of this cat and mouse game involves the modern trend of hiding in the volatile memory (sometimes called a "File-less Attack") which has been very successful in eluding anti-virus and hunters alike. Infocyte provides our customers with unique, advanced techniques for scalable volatile memory analysis, which makes the process for finding in-memory threats much easier and exponentially more effective at scale. But as with anything in security, human ingenuity will find a way. Below are three such techniques that red teams and real-world attackers recently released to hide better in memory.
In this two part post, we'll look at three of the latest techniques that have surfaced to thwart advanced memory scanning techniques, such as those used by Infocyte. In a follow-up post we'll talk about advances made by Infocyte to make scaled memory analysis more robust and difficult to counter.
1. Reduced Memory Protections
Of the stealthy (non OS registered) process injection techniques available to attackers:
- Reflective DLL Injection
- Process Hallowing
- Memory Module
- APC Injection
Almost all implementations allocate liberal permissions (RWX) on their memory pages. As a result, Infocyte and some in the DFIR community have utilized a very reliable technique of scanning process memory pages for modules loaded with improper memory protections. This technique has served us well for YEARS with few modifications, as memory analysis (i.e. using Volatility or Rekall) has historically not been scalable enough to find a hidden beachhead.
While some threat actors at the higher tiers caught on, we still see what many call "advanced" actors using this lazy method to allocate memory (even Equation Group's DoublePulsar and Russian rootkits like Uroburos make this mistake). We're calling it though; our observations mark 2017 as an official shift of attacker and red teamer trends to reduce permissions after allocation to make their malware "non-writable". This isn't a death blow to memory scanning by any means but it does increase the noise that defenders and memory analysis solutions like Infocyte have to work through as we expand the search and run into legitimate in-memory compiled processes like .NET and Java applications.
Impact to Defenders: Medium-Low.
Memory analysts and hunters will have to expand if they were using such assumptions to achieve scale. Expanding the search is trivial but managing falses takes effort. Infocyte is already using this expanded search but scoring had to be updated to negate earlier assumptions of attacker trade-craft.
2. Maleable PE
Earlier this year, the red teaming framework, Cobalt Strike, written and maintained by Raphael Mudge, received a few updates (Blog: "Cat, Meet Mouse") to help hide their implant when injected into a common windows process like explorer or lsass.
The new feature, called Maleable PE, enables red teams to arbitrarily manipulate the Portable Executable (PE) header of its’ implant (called “Beacon”) to avoid the implant from being categorized as an injected module. Two primary techniques in particular forced us to respond:
Prepended NOPs. By prepending No Operation (NOP) assembly instructions to the beginning of the PE file, Beacon now trips up older memory analysis frameworks that use static offsets for PE signatures. You see, normally, malware is injected into byte 0 of its newly allocated memory pages. By placing garbage in front of the PE header, any technique that attempts to pattern match the header using static offsets will fail.
String Replace. Another technique is used to replace certain strings that you typically find in PE headers (like "This program cannot be run in DOS mode") or zeroing out parts of the MZ and PE markers after they are no longer needed. This technique is more experimental as you can easily kill your PE's chance of ever executing if done incorrectly but like the NOP technique above, it can really trip up anyone relying on static PE signatures to identify process injection.
Impact to Defenders: PITA
The latest version (2.9) of Infocyte HUNT uses a new model we've been working on for confirming memory injected modules without relying on static offsets or PE signatures.
Written as a proof of concept by Josh Lospinoso, Gargoyle is a technique for hiding all of a program’s executable code in non-executable memory when it is inactive. At a pre-defined interval, gargoyle will wake up and temporarily mark itself executable to do some work. Basically, it takes advantage of the fact that live memory analysis has a cost and the once valid assumption was that a program must reside in executable memory meant an analyst could safely limit analysis there. Since executable code pages represent less than 10% of total memory on most systems, limiting analysis there offers orders of magnitude better performance to a full memory scan.
Check out the POC write-up here: https://jlospinoso.github.io/security/assembly/c/cpp/developing/software/2017/03/04/gargoyle-memory-analysis-evasion.html
The big problems here are the code is read-only during most of its life and the APC call used to wake Gargoyle is not something that can be trivially enumerated. This represents a challenge to memory analysis at scale.
Impact to Defenders:
Actually it's not THAT bad... the good news is that this is only a proof of concept and no use of the technique has been seen in the wild. The bad news, for the paranoid, is it still hasn't been seen in the wild.
There is some more good news though. Our research has shown the technique has some stability issues and will require a persistence mechanism (such as in the registry) to keep it going. Additionally, behavior-based advanced endpoint protection products should be able to make a signature for the unique ROP chain it’s forced to do to wake itself up.
Stay tuned next week for part two, which will provide an in depth explanation of why you need memory scanning (most endpoint protection and EDR solutions do NOT do memory analysis), how Infocyte enables you to scalably find adversaries in memory and how Infocyte is responding to the latest in memory evasion techniques (including Gargoyle!).