PowerShell overview and introduction

This is a long overdue post I was planning on writing as a reference for myself, since I don’t write that much PowerShell. Depending on your own knowledge about powershell you can just skip to whatever sections seems useful to you. Also feel free to correct any mistakes in this article since I intent it mostly as a basic reference :) The resource section contains a nice collection of links to other PowerShell articles & tools, which means you can consider this article a small recap of all the resources linked.

TL;DR The resource section contains useful URLs to learn Power Shell, the blog post itself is just a micro-recap of those resources.

  • What is PowerShell and why would you use it?
  • Basic PowerShell environment
  • How do you run PowerShell?
  • What is the PowerShell syntax?
  • Our first script
  • Calling Windows functions
  • Resources

basic-powershell-commands-intro-840x420

What is PowerShell and why would you use it?

PowerShell is the “new” scripting language for the Windows operating system. It’s build upon the .NET framework and fully object orientated. Even the output is an object which means that the text you see on screen is usually only a subset of what the object is made of. This might need some getting used to, but in the end it’s well worth the effort. You could compare it to bash under linux, but in my opinion it’s much more powerful.

One of the reasons is because it’s so tightly integrated with a lot of Windows components and Windows itself, which makes it the perfect language to perform administration on Windows. Like we all know when hacking Windows networks a lot of times you are mainly performing administration tasks or obtaining access by abusing administrative workflows.

Like you can read the main reason to want to use PowerShell is the fact that it’s fully integrated into the operating system. That means that in theory you don’t need to introduce any foreign executables onto a system and you could perform all your actions in an obfuscated and in-memory only way.

Basic PowerShell environment

Even though PowerShell is integrated into the operating system it’s still pretty useful to understand the basic PowerShell environment as well as how to get around with the build in help. After all, how unlikely it may seem, sometimes you won’t have access to internet and you will need to handle yourself in PowerShell without it.

So just like linux one of the most helpful commands is ‘man’, jup that works just like ‘alias’. Kid you not!

man alias
alias | findstr "help"

Those commands just work under PowerShell and are more or less the basics of starting out. However we still need a way to list like almost all possible commands under PowerShell. You can more or less achieve this by doing:

Get-Help *

Since everything is an object you might want to know what the members or methods available are for an object. You can use Get-Member for this:

(dir)[0] | Get-Member

That might look like gibberish, but it translates to “get the first object from the result of the dir command”, parentheses are there to indicate order and the “[0]” notation is the usual array accessing one. If you are wondering how to figure the above out, it would be by reading the following:

man Get-Help
man Get-Member
man about_arrays
man about_Command_Syntax

So like you can see even without internet you can get pretty far by just reading the available help. Admitted that you have to do more reading than just directly searching for the answer on google. Fun stuff you can do with simple commands is stuff like:

(dir) | foreach-object -process {$_.lastaccesstime}

Which prints out the lastaccesstime for all the objects outputted by the dir command. Which is again a reminder that with PowerShell it will mostly occur that you will see less on the screen than what the actual object holds. Which more or less makes Get-Member mandatory to really know what kind of data is available after you run a command or cmdlet.

How do you run PowerShell?

Running PowerShell is pretty straightforward if we leave the execution policy out of the equation for a moment:

powershell

 

Like you can see you can execute PowerShell code from within PowerShell or by passing your code as a command line argument to the ‘powershell.exe’ executable. You can of course also execute code which resides in a separate file, a script file if you will:

[cmd.exe]
powershell.exe -File test.ps1

[powershell prompt]
.\test.ps1

Which will probably give you a big nasty ugly error about the execution policy. Before we even start bypassing the execution policy, let’s first check it out. Copy pasting directly from Microsoft they say the following:

    The execution policy is not a security system that restricts user actions.
    For example, users can easily circumvent a policy by typing the script 
    contents at the command line when they cannot run a script. Instead, the
    execution policy helps users to set basic rules and prevents them from 
    violating them unintentionally.

Well that at least creates the right expectations. Seems that the execution policy is certainly not intended to prevent anyone from running scripts on purpose, only by accident. This is also very visible if you search around for ‘execution policy bypass’ in which the first hit is actually a pretty great article which depicts 15 ways in which you can bypass the execution policy.

An important note with the whole execution policy bypass thing is not to forget about the PowerShell scope, since this can sometimes be the difference between the bypass working or not working. Microsoft makes it really easy to understand the correct situation vs precedence situation:

        - Group Policy: Computer Configuration
        - Group Policy: User Configuration
        - Execution Policy: Process (or PowerShell.exe -ExecutionPolicy)
        - Execution Policy: CurrentUser
        - Execution Policy: LocalMachine    

Always make sure to try the most narrow scope before you give up on a execution policy bypass tricks :-)

What is the PowerShell syntax

This is just something of personal preference, but I always like to at least have somewhat of a notion of the language’s syntax before I just start out trying stuff. Also like explained at the beginning of my blog post, everything is a recap from the resources linked in this article. If you want a more extensive explanation make sure you check the resource section or the link previously mentioned.

semi colons

Those are not needed to terminate statements. You can however use them to separate statements on the command line

escape character

The backtick (grave accent) represented as the character ` is the escape character within PowerShell. You can use this character to for example print tabs `t or escape characters with a special meaning like the $ character as in `$ or escaping quotes like `”.

You can also use the backtick character to span your statements over multiple lines, which can sometimes come in handy.

variables

Variables in PowerShell have a ‘$’ sign in front of them, like:

$myvar = 'some value'
$myothervar = 42

single & double quotes

There actually is a distinction when using these. The single quote represents everything literally, the double quotes interprets what’s inside it.

$dummyvalue = 'dummy'
write 'test$dummyvalue'
write "test$dummyvalue"

The first one will print ‘test$dummyvalue’ the second one will print ‘testdummy’. And like most scripting language you can use the quotes to encapsulate each other like “soo he said ‘wow’, jus he did”.

brackets and colons/periods

The round brackets, parenthesis, ‘(‘ and ‘)’ can be used to specify order and to pass arguments to .NET methods. When calling function you defined in PowerShell you pass the arguments SPACE separated and without parenthesis since they could cause an error.

The square brackets can be used to access list/array members like most languages:

$test = 1,2,3,4,5
write $test[0]

The above will produce the output ‘1’ since it’s accessing the first members in the array. The other use case for these brackets is to define types and accessing .NET classes as in:

$test = [DateTime]
write $test::now

The above will print the current date time. Like you can see here you can use a double colon to access properties of a class, to access methods you can use the period character

$test = New-Object System.datetime
write $test
write $test.AddYears(2015)

Which doesn’t do that much except print the year 2016 and demonstrate how to access methods.

Functions

So there is an important distinctions between calling functions and calling methods. Functions in PowerShell use spaces for the parameters and not brackets, which you might confuse in the beginning when you mix in calls to methods.

We could go on endlessly about all the syntax, but usually for me this is the basics. The other stuff you can read from the linked ‘PowerShell syntax’ section in the resource section or google around for it. you might be thinking YOU FORGOT CONTROL FLOW stuff, but those don’t really vary that much from other languages :)

Our first script

As usually advised in the infosec community, learning by doing teaches best. Let’s write some useful scripts to learn a bit more about PowerShell scripting. Try to understand them and google the unknown bits =)

Portscanner

[CmdletBinding()]
Param(	
		[Parameter(Mandatory=$true)][string]$myhost, 
		[int[]]$myports=(80,443)
	 )

#Simple port scanner example
#DiabloHorn - https://diablohorn.wordpress.com

foreach($myport in $myports){
	try{
		$scanner = New-Object System.Net.Sockets.TcpClient($myhost,$myport)
		#returns if it's connected
		Write-Output "$myhost`t$myport`t$TRUE"
		$scanner.Close()
	}catch{
		#any exception will pretend the port was closed
		Write-Output "$myhost`t$myport`t$FALSE"
	}
}

 

Calling Windows functions

One of the main advantages of PowerShell in my opinion is the fact that besides fully integrating with the .NET framework you are also able to call native win32 API functions. This adds the benefit that you can do a lot of cool stuff and also perform a large part of that cool stuff in memory only. As an example the following code calls the MessageBox win32 API:


$c_sharp_code = @'
[DllImport("user32.dll", CharSet=CharSet.Auto)]
public static extern int MessageBox(IntPtr hWnd, String text, String caption, int options);
'@
#Write-Output $c_sharp_code
$user32dll = Add-Type -MemberDefinition $c_sharp_code -Name 'User32' -Namespace 'Win32' -PassThru
#Write-Output $user32dll
$user32dll::MessageBox(0,"hello from powershell","PS Hello",0)

The actual explanation for the above can be found in the resource section under “Accessing Windows API”. For now the most important bit to know is that PowerShell actually in-memory compiles the code into a class which you can then just use, this is called Platform Invoke (P/INVOKE) calls for unmanaged functions. This is the supported method as far as I know and the one a lot of examples uses. The draw back can be however that some disk interaction takes place, so if you want to fully remain in memory you’d have to lookup the methods described by Matt Graeber which remain fully in memory, they are referenced in an excellent blog post by harmj0y in the resource section of this blog.

Resources

This section contains more or less all the resources I’ve used in the past when learning PowerShell and each and every time I need to refresh my memory on the topic, since I don’t write PowerShell that often. Feel free to leave additional useful resources in the comments :)

One thought on “PowerShell overview and introduction”

  1. PowerShell is a nice shell, but I feel it excels at being at *shell* while developing cmdlets or scripts is cumbersome at times and, in some instances, counter-intuitive. Developer Helge Klein articulates well some complaints I also have with PowerShell:

    https://helgeklein.com/blog/2014/11/hate-powershell/

    As a bonus, Jeffrey Snover (from the PowerShell team) actually comments on the article and helps explain some of the design decisions.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: