Back in more innocent times, circa 2015, we began to hear about hackers going malware-free and “living off the land.” They used whatever garden-variety IT tools were lying around on the target site. It’s the ideal way to do post-exploitation without tripping any alarms.
This approach has taken off and gone mainstream, primarily because of off-the-shelf post-exploitation environments like PowerShell Empire.
I’ve already written about how PowerShell, when supplemented with PowerView, becomes a potent purveyor of information for hackers. (In fact, all this PowerShell pen-testing wisdom is available in an incredible ebook that you should read as soon as possible.)
Any tool can be used for good or bad, so I’m not implying PowerShell was put on this earth to make the life of hackers easier.
But just as you wouldn’t leave a 28” heavy-duty cable cutter next to a padlock, you probably don’t want to allow, or at least make it much more difficult for, hackers get their hands on PowerShell.
This brings up a large topic in the cybersecurity world: restricting application access, which is known more commonly as whitelisting or blacklisting. The overall idea is for the operating system to strictly control what apps can be launched by users.
For example, as a member of homo blogus, I generally need some basic tools and apps (along with a warm place to sleep at night), and can live without PowerShell, netcat, psexec, and some other cross-over IT tools I’ve discussed in previous posts. The same applies to most employees in an organization, and so a smart IT person should be able come up with a list of apps that are safe to use.
In the Windows world, you can enforce rules on application execution using Software Restriction Policies and more recently AppLocker.
However, before we get into these more advanced ideas, let’s try two really simple solutions and then see what’s wrong with them.
ACLs and Other Simplicities
We often think of Windows ACLs as being used to control access to readable content. But they can also be applied to executables — that is, .exe, .vbs, .ps1, and the rest.
I went back into Amazon Web Services where the Windows domain for the mythical and now legendary Acme company resides and then did some ACL restriction work.
The PowerShell .exe, as any sys admin can tell you, lives in C:\Windows\System32\WindowsPowerShell\v1.0. I navigated to the folder, clicked on properties, and effectively limited execution of PowerShell to a few essential groups: Domain Admins and Acme-SnowFlakes, which is the group of Acme employee power users.
I logged backed into the server as Bob, my go to Acme employee, and tried to bring up PowerShell. You see the results below.
In practice, you could probably come up with a script — why not use PowerShell? — to automate this ACL setting for all the laptops and servers in a small- to mid-size site.
It’s not a bad solution.
If you don’t like the idea of setting ACLs in executableefiles, PowerShell offers its own execution restriction controls. As a user with admin privileges, you can use, what else but a PowerShell cmdlet called Set-ExecutionPolicy.
It’s not nearly as blunt a force as the ACLs, but you can restrict PowerShell to work only in interactive mode – with the
Restricted parameter — so that it won’t execute scripts that contain the hackers’ malware. PowerShell would still be available in a limited way, but it wouldn’t be capable of running the scripts containing hacker PS malware.
However, this would PowerShell scripts from being run by your IT staff. To allow IT-approved scripts, but disable evil hacker scripts, you use the
RemoteSigned parameter in
Set-ExecutionPolicy. Now PowerShell will only launch signed scripts. The IT staff, of course, would need to create their own scripts and sign them using an approved credential.
I won’t go into the details how to do this, mostly because it’s so easy to get around these controls. Someone even has a listicle blog post in which 15 PowerShell security workarounds are described.
The easiest one is using the Bypass parameter in PowerShell itself. Duh! (below).
So PowerShell has some basic security flaws. It’s somewhat understandable since it is, after all, just a shell program.
But even the ACL restriction approach has a fundamental problem.
If hackers loosen up the “live off the land” philosophy, they can simply download — say, using a remote access trojan (RAT) — their own copy of PowerShell .exe. And then run it directly, avoiding the permission restrictions with the resident PowerShell.
Software Restriction Policies
These basic security holes (and many others) are always an issue with a consumer-grade operating systems. This has led OS researchers to come up with secure secure operating systems that have direct power to control what can be run.
In the Windows world, these powers are known as Software Restriction Policies (SRP) — for a good overview, see this — that are managed through the Group Policy Editor.
With SRP you can control which apps can be run, based on file extension, path names, and whether the app has been digitally signed.
The most effective, though most painful approach, is to disallow everything and then add back application that you really, really need. This is known as whitelisting.
We’ll go into more details in the next post.
Anyway, you’ll need to launch the policy editor, gpedit, and navigate to Local Computer Policy>Windows Settings>Security Settings>Software Restriction Polices>Security Levels. If you click on “Disallowed”, you can then make this the default security policy — to not run any executables!
This is more like a scorched earth policy. In practice, you’ll need to enter “Additional Rules” to add back the approved apps (with their path names). If you leave out PowerShell, then you’ve effectively disabled this tool on the site.
Unfortunately, you can’t fine-tune the SRP rules based on AD groups or users. Drat!
And that we’ll bring us to Microsoft’s latest and greatest security enforcer, known as AppLocker, which does provide some nuance to application access. We’ll take that up next time as well.