Advent of Cyber - PowerShell
Advent of Cyber - PowerShell
In this chapter I will go over the series of boxes in the advent of cyber which covers PowerShell
, but also I will include another box which goes over the basics of this scripting language.
It is a lot more than just a scripting language like bash
though, as it is actually built on top of the .NET
Common Language Runtime (CLR) and so instead of simple functions and text that bash
works with, PowerShell
(which I will from now abbreviate to PS) works with .NET
objects , properties of those objects and creating new objects at times to work with. It still looks quite similar to bash
as it declares parameters in the same way - it's just under the hood is quite different.
It'll make more sense if we go through step by step in the shell together, so boot up a Windows VM or something and let's get started.
Remember that command prompt is still using the old MS-DOS
shell that has been around since the 1980s and so to start up the PS
framework you will have to type
start powershell
Or you can avoid all this hassle and just search for the powershell.exe
which is the program which loads up the framework:
Now that's started, lets do some familiar jobs that would've built up our proficiency in Linux - you know the cd
, ls
, piping to different commands etc.
The PS
philosophy is that you first declare what type of action you're going to be doing - which is demarcated by a verb like Get
- in the Advent of cyber room we will be using Get-NetUser
which is a object that holds data about the computers on an AD domain. The inverse of this verb would be Set
, as in Set-Location
to change directory
Set-Location 'Documents'
;; note PowerShell also leverages traditional commands like ls, cd for this sort of thing
;; too. For now we're just driving a Ferrari to the supermarket ... but soon you will why
;; what this can do!
All the common PS
verbs are:
- Get
- Start
- Stop
- Read
- Write
- New
- Out
With their complementary add-on which would usually demarcate whether we're working with files, registries, programs, networks etc...
All of the approved verbs that objects will be derived from can be seen on Microsoft's documentation here.
Commands such as Set-Location
are called cmdlets
as they are lot more expressive than normal commands such as ls
for example, they are like mini-programs in and of themselves.
The "equivalent" to ls
is Get-ChildItem
which let us view the contents of a directory, and we can look at the properties of all the list by adding -property
, but you just need to add the -
and keep hitting tab to cycle through the properties, and shift+tab to reverse back an option. This is a very quick and informative way of learning all the powers of the cmdlets
quickly:
When we try this we can see that it expected a number to specify to what degree we search through all folders and directories , trying this again:
Now we can see that Desktop
only had one lower layer, with some interesting files too - this level of searching done on each directory is pretty sweet, can we pipe it to another command that will lift the information on a specific directory though ? Yes !
We can add the -Filter
option , which takes a string - denoting a regular expression - allowing us to search for particular files, folders and users out of the output:
You can see that what it does really is qualify the path of thing we're trying to look for, giving us those links themselves , speaking of paths there is the -Path
option which will do similar things to Filter
:
When we do more intensive tasks, we are likely to find an error with one of the inputs we cycle too - in Linux we usually just appended the 2>/dev/null
snippet to redirects errors from stdout
, the same can be done in PS
by adding:
-ErrorAction SilentlyContinue
;;Specifies what action to take if the command encounters an error.
We can search for hidden files and/or directories by typing
Get-ChildItem -Hidden
;; this will give us all hidden files and directories, so we can append
Get-ChildItem -Hidden -File
;; which narrows the list to only show files
Get-ChildItem -Hidden -Directory
;; which narrows the list to only show directories
For a list of all commands, you can use the Get-Command
cmdlet
. Careful though, running this command with no arguments mean it will get all commands, what you want is usually to be able to narrow it down to it's noun - and then you can see the group of commands available. So , for example we could type
Right, after we've listed all the files under the sun it would be good if we could inspect their contents. For this we can turn to the Get-Content
cmdlet
and try it giving it some of the paths we've found:
And we can combine it with the other commands we know by using the |
operator, but the crucial difference is that instead of text we're always passing objects between cmdlets
- meaning the output has methods and properties.
NOTE : If you every get stuck on how to use a certain command , just use
Get-Help command
And this is the equivalent to 'man' for linux.
I pretty much have the -Examples option ingrained into me whenever I use it , like below:
Get-Help Get-Content -Examples
Illustrating that the output is in fact an object can be shown by using the Select-Object
command, the first one where we have used a Get
! But what this will show is what manipulations we can do on , say , the Get-ChildItem
command - what properties and methods we can work with...
As we can see we wanted to see the properties Mode and Name - and in the future when we have a lot of output this can become mighty useful ...
Now this is all well and good, but what if we want to find a specific value, say we wanted to check whether we had a Searches
directory for example? We can pipe output to Where-Object
instead and we use do the same thing and specify whether we want to look at properties or methods - and then we supply the additional operator value
parameter and argument , so to check if a value equalled something we could do:
Remember we're checking a specific property, so you don't need to list others such as Mode etc as it won't work.
And lastly, you can sort a given object by piping it to the Sort-Object
command:
Get-ChildItem | Sort-Object
;; does it alphabetically by Name if left unspecified
;; you can do the traditional -Property Name or -Property Mode if you want to sort on
;; specific attributes
;; you can also use -Last 5 , or -First 2 if you want to sort little sections.
We can also iterate through a list of objects if the cmdlet
provides more than one, though the iteration command can obviously still work for one output - it just loops once.
;; standard Where-Object
Get-ChildItem | Where-Object -Property Name -eq Searches
;; iteration version
Get-ChildItem | Where-Object {$_.Name -eq Searches}
;; $_ dereferences the object and .Name dereferences the property.
This is a little snippet of code that I used when trying to get to grips with how to search an entire system
Get-ChildItem -Depth 10 | Where-Object -Property Name -Match "interesting-file"
-ErrorAction SilentlyContinue
;; but this is far too clunky, the depth is arbitrary ... there must be something better
;; there is, we have the -Recurse option , which goes through each folder until it has
;; checked everything , much better. Let's stick a path in there too for modularity.
Get-Childitem –Path C:\ -Recurse -ErrorAction SilentlyContinue
;; remember that the -ErrorAction is so that we don't see the errors when the
;; "Permission denied"-style errors crop up.
Get-Childitem –Path C:\ -Recurse -ErrorAction SilentlyContinue | Where-Object -Property Name -Match "some-file"
;; So remember , no arbitrary depth, use -Recurse!
Checking how many cmdlets
there are
This was a nice little beginner challenge, and the docs are always a very handy resource - especially for Where-Object
as I made use of the CNotMatches
parameter, and this allows us to supply a regular expression, and a given entry doesn't match it then we allow it:
Making a web request with PowerShell
Different verb time ! Now we need to use the Invoke
- combined with WebRequest
, we could see all the different Invoke
verbs by doing:
Get-Command Invoke-*
To use Invoke-WebRequest
we need to supply the URL , the HTTP method and anything else
If you're stuck ,
Get-Help Invoke-WebRequest -Examples
;; you can do this to see if you have a connection
Invoke-WebRequest -Uri "google.com" -Method Get
Converting Base-64 strings to and fro
This is only possible because of the underlying .NET core utilities...
See this stack overflow too:
Enumeration with PowerShell
Here we are going to see what accounts are on the system, what groups and ports are available to us.
So we can list all possible User
commands are available with
Get-Command Get-*User*
;; and from this we find
Get-LocalUser
So there are five accounts...
Grabbing User Account SIDs
Remember that the output you see here is just an object, of which we can query for different properties - there is still some data in the shadows ! Such as the user ID.
To completely disspell any question of what the object's properties are we can replace a value for *
.
Everything I've talked about for LocalUser
is exactly the same for LocalGroup
...
Finding IP addresses and ports
The first is pretty simple,
Get-NetIPAddress | Select-Object -Property 'IPAddress'
Now for finding ports we can use Get-NetTCPConnection
which lists the state of all active ports, with 35770 the only port which seems to be established.
Finding Patches
Now this is one sweet cmdlet
as we don't have to look very far to get a good history of patches and who they were installed by...
Finding any backups on the system
Pretty much the same as finding any old file, but we can narrow down the file extensions to .bak
NOTE : If you wanted to use -Match instead of -Include, that is an option for Where-Object
Scanning for particular contents in files
Here we use Select-String
which can work when give a string or a file, and then we can append the Pattern
property which will check the contents for the expression we supply...
So we can do
Get-ChildItem -Path 'C:\' -File -Recurse -ErrorAction SilentlyContinue | Select-String -Pattern "API_KEY"
Get Running Processes
We can look at running processes by doing
Get-Process
And scheduled tasks by doing
Get-ScheduleTask
See who owns what , by leveraging the local Access Control List
As we're still searching for resources we turn yet again to the Get-*
verbiage this time needing the help of
Get-Acl
;; Get Access Control List, which will tell us who owns , say ,
Get-Acl "C:\"
;; will tell us the owner of the main drive.
Task 20 : [Blue Teaming] PowershELlF to the rescue
Here we shall use our newly acquired skills to snoop around this box - start by typing
Well the first option didn't work, oh well... Now we need to have a look at some hidden files
Now we have to be on the lookout for a hidden directory ...
Get-ChildItem -Path "C:\" -Recurse -Directory -Hidden -ErrorAction SilentlyContinue
Here I spotted the directory and we have to swap over to
Set-Location .\3lfthr3e\
And now for our last challenge,