I’m focusing on CrowdStrike Falcon for this article but it’s worth noting that generally speaking, vendors in the AV and EDR space are judged very harshly for their false positive to true positive ratio. Nobody wants another noisy security tool so CrowdStrike has made extensive efforts to ensure that their detections are accurate and enforceable. Unfortunately, this tendency to be quiet until it’s time to drop the hammer can be as detrimental as it is beneficial. The remainder or this post will highlight the detrimental side.
I spent several days testing various post-exploitation tools and techniques on a system running CrowdStrike’s Falcon Prevent product with the aim of demonstrating the value of combining an EDR solution with our SOAR+ security automation platform. I found that it is quite possible to “live off the land” so to speak and avoid triggering excessive detections from CrowdStrike. Before I go on, let’s do some housekeeping:
- Post-exploitation implies that local admin privileges have already been obtained. At this stage, an attacker is usually trying to persist in the environment and capture credentials so that they can move laterally and expand their access. This might sound like an unfair test since I’ve skipped past the initial compromise phase. If you assume that eventually, local admin privileges will be obtained by someone that shouldn’t have them, you better have a strategy in place to handle it.
- “Live off the land,” means leveraging tools that are already in place on the system to access and move information. It’s difficult for EDR vendors to alert on such activities without seeing a significant spike in their false positive rate.
Fortunately, we have two things working in our favor:
- A smart attacker will not try to kill off the EDR Sensor because doing so would alert us to their presence.
- Even if an attacker is trying to be as silent as possible, they’re still extremely likely to do something that triggers a detection.
I saw this first hand as I attempted various well known methods for extracting credentials from memory on my compromised host. In this example, I used a modified and obfuscated version of the well known invoke-mimikatz.ps1 utility. It was promptly blocked despite my attempts to mask the true nature of the script.
I tried several other obfuscated scripts that dump memory for the lsass.exe process (which holds Windows credentials in memory) but all of those efforts met a similar fate as the attempt above. This was the moment in my testing when I recalled the significance of Sun Tzu’s proverb - time to get creative.
I won’t go as far as providing the specific commands/scripts used but I will outline the basic concept. For starters, dumping credentials from memory might be the most obvious (and possibly overutilized) method for obtaining passwords in a Windows environment but it’s certainly not the only option. So here’s what I did instead:
- Download and execute a powershell based keylogger. Now, my first attempt at this failed because I tried to download the keylogger script and execute it in memory without writing it to disk. This is a common tactic employed by attackers so CrowdStrike blocked it:
- To work around this, I downloaded the same powershell based keylogger script and wrote it to disk and then executed it. This time, it worked. I was surprised to find that the keylogger script in of itself is not assumed to be suspicious so score one for ingenuity.
- Next, I used a powershell command to create a scheduled task that runs every time the host starts up. The scheduled task does the following:
By taking this approach, I’m able to establish a bit of persistence (I can update my keylogger script with new capabilities and it will be downloaded daily) without using traditional command and control methods and it could function undetected in the environment for quite a while. It may not be the quickest route to getting credentials and it would take a decent amount of work to find them in the uploaded files but hey, I never said ingenuity was easy. :)
So... back to that part about defenders needing to be diligent. We can’t assume the job is done just because an attacker’s attempt to extract credentials was prevented by an endpoint control. The attacker might have found another way to accomplish their objective. Hence, the importance of following a complete incident response procedure every time an EDR alert indicates that something obviously malicious was blocked. A security automation platform provides the structure needed to make sure that you run a consistent playbook every time. It has the added benefit of recording the actions so that you can review the response activities after the fact. It’s a bit like having a Monday morning film session after a big game.
Here’s how we would go about running a basic automated response with LogicHub’s SOAR+ platform:
First, we have a flow that consolidates multiple related alerts into a single case. These first two screenshots show a couple of the flow elements.
And this is the case that is generated from the flow.
As the incident responder, I first want to identify which users might have been impacted by a compromise of this system. So I use a LogicHub command to query a list of users that have accessed this host. You might be wondering where we’re getting this list from. One of the advanced capabilities of the LogicHub platform is the ability to build baselines and custom lists that can track user behaviors. So this command is actually querying a users per host list maintained within the LogicHub platform.
As you can see from the task output, we have one user and an administrator account that could be affected by this compromise.
So my next course of action is to disable the Active Directory account and Okta identity for the regular user.
For the administrator user, I would rather not disable the account so I’m going to reset the password instead. Tasks only work against fields that are available from the original case, which didn’t include the administrator user. Thankfully the Commands feature in LogicHub Cases allow us to execute a command with any input we choose.
So here, I’m executing the AD_Reset_User_Password command and passing the administrator user_id as an argument to the command.
The command updates the user account with a randomly generated password and returns the password as the output. Additional containment steps might include a host quarantine action and some notifications to affected parties, tasks that a good security automation solution can easily handle.
In my next post, I’ll outline a threat hunting automation solution that will use CrowdStrike to find some live off the land attack techniques like the ones I described earlier in this post. Thanks for reading and until next time, remember -
“If you know the enemy and know yourself, you need not fear the result of a hundred battles.”