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:

powershell-started

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:

getting-to-grips

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:

this-was-much-better-depth-search

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:

using-filters

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:

path-and-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

using-get-command

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:

Get-Content

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.

piping

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...

select-object

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 ...

first-last-skip

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:

where-object

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:

cnotmatch-is-cool

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...

converting-base64

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

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.

grabbing-sid-properties

To completely disspell any question of what the object's properties are we can replace a value for *.

all-properties-of-users

Everything I've talked about for LocalUser is exactly the same for LocalGroup ...

local-group

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.

what-ports-are-open

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...

find-all-patches

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

found-backup

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"

keep-your-eyes-peeled

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

start-powershell

Well the first option didn't work, oh well... Now we need to have a look at some hidden files

what-does-the-elf-want

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\

see-contents-of-hidden-files

And now for our last challenge,

string-tinkering