Cmdlets

2.2 Cmdlets

As we’ve seen in the previous section, cmdlets (“command-lets”) are a big part of how we will leverage PowerShell for our offensive purposes, two of which we’ve already briefly covered:

• “Get-Help”
• “Get-Command”

Let’s first generally summarize what cmdlets are:

• Light-weight PowerShell scripts that perform a single function
(Can be as small as a few lines of code).
• Instances of .NET Framework classes derived from the Cmdlet
Base Class and provide access to system functions.
• Cmdlets are native commands in PowerShell (We can also
create our own).

cmdlets summarization continued:

• Typically written in a “Verb-Noun” file name format which
helps us determine their function (e.g., Invoke-Command).
• Typically used to return output to other Cmdlets to be then
processed via a pipeline (|).

IMPORTANT: It should be noted that most cmdlets, by default, when run without other parameters will return a limited set of information or “Columns.”

For example, just running the “Get-ChildItem” cmdlet without any other arguments or options, returns four columns named “Mode,” “LastWriteTime,” “Length” and “Name”.

But by piping the output of a cmdlet to the “Format-List” cmdlet, rather than columns and names as seen in the previous slide, we can return all named properties associated with its objects in a different list-like format :

PS C:\> Get-ChildItem | Format-List *

The results of all cmdlet output, are usually referred to as “objects.” These objects can be further processed using what is known as “pipelining,” similar to how we can chain commands together in a Linux bash shell for instance with the Pipe Operator (|).

An example of this processing of cmdlet output objects with pipelines would be something like the following:

PS C:\> Get-Process | Sort-Object -Unique | Select-Object ProcessName

The above returns a list of processes (Get-Process), then sorts the list (Sort-Object) with the (-Unique) parameter, and finally, selects the “ProcessName” objects (Select-Object ProcessName) and returns a unique list of process names.

PS C:\> Get-Process | Sort-Object -Unique | Select-Object ProcessName

We can also redirect the results of our pipeline operation to a file using a standard Redirect Operator (>):

 PS C:> Get-Process | Sort-Object -Unique | Select-Object ProcessName > uniq_procs.txt

Running the “Get-Process” cmdlet without any arguments returns basic information as we can see, and is formatted in a table-like format, which includes column names (properties).

To get all of the information (properties) associated with all of the processes, we can pipe it to the “Format-List *” cmdlet and wildcard argument. This will give us a better idea of how we can filter the data for specific properties.

PS C:\> Get-Process | Format-List *

We can further extend this to get information about specific processes and paths to their executables (in this example, Chrome and Firefox), by using the “Format-List” cmdlet and also specifying the “Path” property name.

PS C:\> Get-Process chrome, firefox | Sort-Object -Unique | Format-List Path

We can also append multiple property names to the Format-List cmdlet, and obtain the processes Paths, and associated PID’s (Id) for instance:

PS C:\> Get-Process chrome, firefox | Sort-Object -Unique | Format-List Path,Id

Something that’s good to know about cmdlets is that most of them have “Aliases.” For instance, the “Get-ChildItem” cmdlet which simply lists items in a directory, can be alternatively called by issuing the “ls” command, which is an alias for the Get-ChildItem cmdlet.

We would get the same exact results by simply just running “Get-ChildItem.”

To find what the aliases are for a specific cmdlet, we can use the “GetAlias” cmdlet with the “-Definition” parameter followed by a cmdlet name, like in the following example:

PS C:\Users> Get-Alias -Definition Get-ChildItem

As we can see, the “Get-ChildItem” cmdlet has three aliases, “dir,” “gci,” and “ls.”

Another alias you’ll see quite often is “select” when used in conjunction with other cmdlets in pipeline operations, and is an alias for the “Select-Object” cmdlet. In this example, we’re using the “Get-WmiObject” cmdlet, (used to return information about WMI objects) in conjunction with the “- class win32_operatingsystem” parameter and arguments, and then selecting (select) all (*) properties related to that WMI object class; this returns all information related to the current operating system.

PS C:\> Get-WmiObject -class win32_operatingsystem | select -Property *

Alternatively, we could use the Format-List alias “fl” with the wildcard argument, and obtain the same list of all properties for the WMI Object:

PS C:\> Get-WmiObject -class win32_operatingsystem | fl *

We can use the Get-WmiObject cmdlet to obtain information regarding any WMI Class, for instance, getting a detailed list of properties for all services with the “win32_service” class:

PS C:\> Get-WmiObject -class win32_service |Format-List *

And we can further extend our pipeline and filtering operation just to give us “PathName” which includes command line arguments and paths to all service executables:

PS C:\> Get-WmiObject -class win32_service |Sort-Object -Unique PathName | fl Pathname

And of course, saving the information we’re gathering to a file is important as well. We can either redirect the output of the pipeline operation to a file with the (>) Redirect Operator as we saw in an earlier example or sometimes, we may need the results in a different format for processing. For this, we can pipe all of the output to the “Export-Csv” cmdlet, and save the results in CSV format:

PS C:\> Get-WmiObject -class win32_operatingsystem | fl * | Export-Csv C:\host_info.csv

For access to Windows Registry hives, PowerShell provides a convenient method with the following command:

PS C:\> cd HKLM:\

We can easily navigate into areas we might be interested in with “cd,” which is the alias for “Set-Location,” and furthermore, list the contents of our current hive with “Get-ChildItem” cmdlet or “ls”:

PS HKLM:\> cd .\SOFTWARE\Microsoft\Windows\CurrentVersion\
PS HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\> ls

The Select-String cmdlet along with the “-Path” and “-Pattern” arguments is yet another useful PowerShell command we can use to scour the system for files containing certain strings. In the example below, we search for files of a .txt extension within a user's “Documents” directory, containing the string “pass*” in their contents:

PS C:\> Select-String -Path C:\users\user\Documents\*.txt -Pattern pass*

We can then use the “Get-Content” cmdlet to display the full contents of the “passwords.txt” file.

PS C:\> Get-Content C:\Users\user\Documents\passwords.txt

Alternatively, we can obtain the same results by using the “Get-ChildItem” cmdlet alias with the recurse parameter (ls -r) which lists files within a directory recursively, then, search for files types of .txt with the “-File” parameter. We’ll then pipe that to the “For-Each-Object” alias which is (%) and a script block {} that searches for the string “pass*” in all files in the path specified with the alias for the “Select-String” cmdlet (sls):

PS C:\> ls -r C:\users\user\Documents -File *.txt | % {sls -Path $_ -Pattern pass* }

We will learn more about how we can use the “ForEach-Object” cmdlet a bit later for certain tasks.

The “Get-Service” cmdlet will get us information regarding currently installed services and can be useful in the case we can identify a service which might be vulnerable to a privilege escalation exploit.

Running it without parameters or arguments simply returns a three column list of all services.

PS C:\> Get-Service

We can extend those results, as we’ve seen before, with the “Sort-Object” cmdlet. In this example, all services starting with “s*” in descending order and sorting by the “Status” property.

PS C:\> Get-Service “s*” | Sort-Object Status -Descending 

Last updated