Introduction to Windows Command Line

 


PowerShell has become increasingly prominent among IT and Infosec professionals. It has widespread utility for System Administrators, Penetration Testers, SOC Analysts, and many other technical disciplines where ever Windows systems are administered. There are countless ways to use PowerShell from an IT admin context, and being mindful of that context can be helpful for us as penetration testers and even as defenders. As a sysadmin, PowerShell can provide us with much more capability than CMD. It is expandable, built for automation and scripting, has a much more robust security implementation, and can handle many different tasks that CMD simply cannot. PowerShell's logging and history capability is powerful and will log more of our interactions with the host. So if we do not need PowerShell's capabilities and wish to be more stealthy, we should utilize CMD.

We can type PowerShell in Windows Search to find and launch the PowerShell application and command console.Windows Terminal is a newer terminal emulator application developed by Microsoft to give anyone using the Windows command line a way to access multiple different command line interfaces, systems, and sub-systems through a single app. This application will likely become the default terminal emulator on Windows operating systems.


Using the Help function. If we want to see the options and functionality available to us with a specific cmdlet, we can use the Get-Help cmdlet.One of these additional options is -online, which will open a Microsoft docs webpage for the corresponding cmdlet if the host has Internet access.We can also use a helpful cmdlet called Update-Help to ensure we have the most up-to-date information for each cmdlet on the Windows system.

We can determine our current working directory (in relation to the host system) by utilizing the Get-Location cmdlet.The Get-ChildItem cmdlet can display the contents of our current directory or the one we specify.Changing our location is simple; we can do so utilizing the Set-Location cmdlet.if we wish to see the contents of a file, we can use Get-Content.Get-Command is a great way to find a pesky command that might be slipping from our memory right when we need to use it. With PowerShell using the verb-noun convention for cmdlets, we can search on either.We can trim this down more by filtering on the verb or the noun portion of the cmdlet.

Using the -verb modifier and looking for any cmdlet, alias, or function with the term get in the name, we are provided with a detailed list of everything PowerShell is currently aware of. We can also perform the exact search using the filter get* instead of the -verb get. The Get-Command cmdlet recognizes the * as a wildcard and shows each variant of get(anything).we utilized the -noun modifier.


Get-History will only show the commands that have been run during this active session. Notice how the commands are numbered; we can recall those commands by using the alias r followed by the number to run that command again. For example, if we wanted to rerun the arp -a command, we could issue r 14, and PowerShell will action it.Keep in mind that if we close the shell window, or in the instance of a remote shell through command and control, once we kill that session or process that we are running, our PowerShell history will disappear. With PSReadLine, however, that is not the case. PSReadLine stores everything in a file called $($host.Name)_history.txt located at  get-content $env:APPDATA\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt

: Reads the contents of a file line by line.

: Dynamically fetches the current user's AppData\Roaming folder path.

: This file stores every command you've typed into PowerShell (unless you've disabled history).

If we ran the above command and were a frequent user of the CLI, we would have an extensive history file to sort through. 

we can remove the text from our console window by using the command Clear-Host.We can also use clear or cls if we prefer using short commands or aliases.One of PowerShell's best functionalities must be tab completion of commands. We can use tab and SHIFT+tab to move through options that can complete the command we are typing.

Our last tip to mention is Aliases. A PowerShell alias is another name for a cmdlet, command, or executable file. We can see a list of default aliases using the Get-Alias cmdlet. Most built-in aliases are shortened versions of the cmdlet, making it easier to remember and quick to use.An alias is a shortcut name for a longer command. like:


you can also use gal.

We can also set an alias for a specific cmdlet using Set-Alias. Let us practice with this by making an alias for the Get-Help cmdlet. When using Set-Alias, we need to specify the name of the alias (-Name gh) and the corresponding cmdlet (-Value Get-Help). exampl: Set-Alias -Name gh -Value Get-Help.

For those familiar with BASH, you may have noticed that many of the aliases match up to commands widely used within Linux distributions. This knowledge can be helpful and help ease the learning curve.

                                                              PowerShell Modules

A PowerShell module is structured PowerShell code that is made easy to use & share. As mentioned in the official Microsoft docs, a module can be made up of the following:

  • Cmdlets
  • Script files
  • Functions
  • Assemblies
  • Related resources (manifests and help files)
Through this section, we are going to use the PowerView project to examine what makes up a module and how to interact with them. PowerView.ps1 is part of a collection of PowerShell modules organized in a project called PowerSploit created by the PowerShellMafia to provide penetration testers with many valuable tools to use when testing Windows Domain/Active Directory environments.We will not extensively cover the usage and implementation of PowerSploit in this module. We will just be using it as a reference to understand PowerShell better. 

Once we decide what PowerShell module we want to use, we will have to determine how and from where we will run it. We also must consider if the chosen module and scripts are already on the host or if we need to get them on to the host. Get-Module can help us determine what modules are already loaded.Get-Module -ListAvailable .The -ListAvailable modifier will show us all modules we have installed but not loaded into our session.We have already transferred the desired module or scripts onto a target Windows host. We will then need to run them. We can start them through the use of the Import-Module cmdlet.The Import-Module cmdlet allows us to add a module to the current PowerShell session.To understand the idea of importing the module into our current PowerShell session, we can attempt to run a cmdlet (Get-NetLocalgroup) that is part of PowerSploit. We will get an error message when attempting to do this without importing a module. Once we successfully import the PowerSploit module (it has been placed on the target host's Desktop for our use), many cmdlets will be available to us, including Get-NetLocalgroup.A PowerShell data file (.psd1) is a Module manifest file. Contained in a manifest file we can often find:

  • Reference to the module that will be processed
  • Version numbers to keep track of major changes
  • The GUID
  • The Author of the module
  • Copyright
  • PowerShell compatibility information
  • Modules & cmdlets included
  • Metadata

for practicing this you have to download it in  to you machine. then access this folder and then the next process. but sometimes its make problems Notice how at the beginning of the clip, Get-NetLocalgroup was not recognized. This event happened because it is not included in the default module path.we can check path by typing  $env:PSModulePathWhen the PowerSploit.psd1 module is imported, the Get-NetLocalgroup function is recognized. This happens because several modules are included when we load PowerSploit.psd1. It is possible to permanently add a module or several modules by adding the files to the referenced directories in the PSModulePath. This action makes sense if we were using a Windows OS as our primary attack host, but on an engagement, our time would be better off just transferring specific scripts over to the attack host and importing them as needed.

An essential factor to consider when attempting to use PowerShell scripts and modules is PowerShell's execution policy. As outlined in Microsoft's official documentation, an execution policy is not a security control. It is designed to give IT admins a tool to set parameters and safeguards for themselves.The host's execution policy makes it so that we cannot run our script. We can get around this, however. First, let us check our execution policy settings. by typing Get-ExecutionPolicy .


Our current setting restricts what the user can do. If we want to change the setting, we can do so with the Set-ExecutionPolicy cmdlet.

By setting the policy to undefined, we are telling PowerShell that we do not wish to limit our interactions. Now we should be able to import and run our script. now if you run the script it will run without any restriction .

we can see that we successfully loaded PowerSploit. Now we can use the tools as needed.

Note: As a sysadmin, these kinds of changes are common and should always be reverted once we are done with work. As a pentester, us making a change like this and not reverting it could indicate to a defender that the host has been compromised. Be sure to check that we clean up after our actions. Another way we can bypass the execution policy and not leave a persistent change is to change it at the process level using -scope. 



If we wish to see what aliases, cmdlets, and functions an imported module brought to the session, we can use Get-Command -Module <modulename> to enlighten us.

When it comes to PowerShell modules, the PowerShell Gallery Is the best place for that. It is a repository that contains PowerShell scripts, modules, and more created by Microsoft and other users. They can range from anything as simple as dealing with user attributes to solving complex cloud storage issues. Conveniently for us, There is already a module built into PowerShell meant to help us interact with the PowerShell Gallery called PowerShellGet. Let us take a look at it:


One module that will prove extremely useful to system admins is the AdminToolbox module. It is a collection of several other modules with tools meant for Active Directory management, Microsoft Exchange, virtualization, and many other tasks an admin would need on any given day.Like with many other PowerShell cmdlets, we can also search using wildcards. Once we have found a module we wish to utilize, installing it is as easy as Install-Module. Remember that it requires administrative rights to install modules in this manner.


In the image above, we chained Find-Module with Install-Module to simultaneously perform both actions. We can find the locations for each specific PowerShell profile Here.Besides creating our own modules and scripts or importing them from the PowerShell Gallery, we can also take advantage of Github and all the amazing content the IT community has come up with externally.

Tools To Be Aware Of

Below we will quickly list a few PowerShell modules and projects we, as penetration testers and sysadmins, should be aware of. Each of these tools brings a new capability to use within PowerShell. Of course, there are plenty more than just our list; these are just several we find ourselves returning to on every engagement.

  • AdminToolbox: AdminToolbox is a collection of helpful modules that allow system administrators to perform any number of actions dealing with things like Active Directory, Exchange, Network management, file and storage issues, and more.

  • ActiveDirectory: This module is a collection of local and remote administration tools for all things Active Directory. We can manage users, groups, permissions, and much more with it.

  • Empire / Situational Awareness: Is a collection of PowerShell modules and scripts that can provide us with situational awareness on a host and the domain they are apart of. This project is being maintained by BC Security as a part of their Empire Framework.

  • Inveigh: Inveigh is a tool built to perform network spoofing and Man-in-the-middle attacks.

  • BloodHound / SharpHound: Bloodhound/Sharphound allows us to visually map out an Active Directory Environment using graphical analysis tools and data collectors written in C# and PowerShell.

                                                       User and Group Management

When thinking about accounts, we typically run into four different types:

  • Service Accounts
  • Built-in accounts
  • Local users
  • Domain users

Several accounts are created in every instance of Windows as the OS is installed to help with host management and basic usage. Below is a list of the standard built-in accounts.

Built-In Accounts

Account Description
Administrator This account is used to accomplish administrative tasks on the local host.
Default Account The default account is used by the system for running multi-user auth apps like the Xbox utility.
Guest Account This account is a limited rights account that allows users without a normal user account to access the host. It is disabled by default and should stay that way.
WDAGUtility Account This account is in place for the Defender Application Guard, which can sandbox application sessions.

We can see there are groups for simple things like Administrators and guest accounts, but also groups for specific roles like administrators for virtualization applications, remote users, etc. Let us interact with users and groups now that we understand them. 

Adding/Removing/Editing User Accounts & Groups

Like most other things in PowerShell, we use the get, new, and set verbs to find, create and modify users and groups. If dealing with local users and groups, localuser & localgroup can accomplish this. For domain assets, aduser & adgroup does the trick. If we were not sure, we could always use the Get-Command *user* cmdlet to see what we have access to. Let us give a few of them a try.Get-LocalUser will display the users on our host. These users only have access to this particular host. Let us say that we want to create a new local user.We can accomplish the task using New-LocalUser. If we are unsure of the proper syntax, please do not forget about the Get-Help Command.When creating a new local user, the only real requirement from a syntax perspective is to enter a name and specify a password (or -NoPassword). All other settings, such as a description or account expiration, are optional.see here .

Above, we created the user JLawrence and did not set a password. So this account is active and can be logged in without a password.  Depending on the version of Windows we are using, by not setting a Password, we are flagging to windows that this is a Microsoft live account, and it attempts to login in that manner instead of using a local password.If we wish to modify a user, we could use the Set-LocalUser cmdlet. For this example, we will modify JLawrence and set a password and description on his account. like this command.
Set-LocalUser -Name "JLawrence" -Password $(here)Password -Description "CEO EagleFang" 

and if you want to encrypt your password just   type:$Password = Read-Host -AsSecureString and then the password that you type the prompt ⇧


Now, let us move on to checking out groups. If it feels like a bit of an echo...well, it is. The commands are similar in use.we ran the Get-LocalGroup cmdlet to get a printout of each group on the host. In the second command, we decided to inspect the Users group and see who is a member of said group. We did this with the Get-LocalGroupMember command. Now, if we wish to add another group or user to a group, we can use the Add-LocalGroupMember command.

Managing Domain Users and Groups

Before we can access the cmdlets we need and work with Active Directory, we must install the ActiveDirectory PowerShell Module. If you installed the AdminToolbox, the AD module might already be on your host. If not, we can quickly grab the AD modules and get to work. One requirement is to have the optional feature Remote System Administration Tools installed. This feature is the only way to get the official ActiveDirectory PowerShell module. The edition in AdminToolbox and other Modules is repackaged, so use caution. install by typing ::
Get-WindowsCapability -Name RSAT* -Online | Add-WindowsCapability -Online
The above command will install ALL RSAT features in the Microsoft Catalog. If we wish to stay lightweight, we can install the package named Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0. Now we should have the ActiveDirectory module installed.for check type:Get-Module -Name ActiveDirectory -ListAvailable


now we can get started with AD User and Group management. The easiest way to locate a specific user is by searching with the Get-ADUser cmdlet.
The parameter -Filter * lets us grab all users within Active Directory. Depending on our organization's size, this could produce a ton of output. We can use the -Identity parameter to perform a more specific search for a user by distinguished name, GUID, the objectSid, or SamAccountName. Do not worry if these options seem like gibberish to you; that is all right. The specifics of these are not important right now; for more reading on the topic, check out this article or the Intro To Active Directory module.

We can see from the output several pieces of information about the user, including:

  • Object Class: which specifies if the object is a user, computer, or another type of object.
  • DistinguishedName: Specifies the object's relative path within the AD schema.
  • Enabled: Tells us if the user is active and can log in.
  • SamAccountName: The representation of the username used to log into the ActiveDirectory hosts.
  • ObjectGUID: Is the unique identifier of the user object.
we can also search by attribute name :: Get-ADUser -Filter {EmailAddress -like/name/surename.......etc 'text type'}

In our output, we can see that we only had one result for a user with an email address matching our naming context *greenhorn.corp. This is just one example of attributes we can filter on. For a more detailed list, check out this Technet Article.

Let us give the New-ADUser cmdlet a try.

it's almost previouse one:: 

New-ADUser -Name "*" -Surname "**" -GivenName "**" -Office "***" -OtherAttributes @{'title'="**";'mail'="adm@gmail.com"} -Accountpassword (Read-Host -AsSecureString "**") -Enabled $true/false

Ok, a lot is going on here. It may look daunting but let us dissect it. The first portion of the output above is creating our user:

  • New-ADUser -Name "" : We issue the New-ADUser command and set the user's SamAccountName.
  • -Surname "" -GivenName "": This portion sets our user's Lastname and Firstname.
  • -Office "": Sets the extended property of Office or position.
  • -OtherAttributes @{'title'="";'mail'="mail"}: Here we set other extended attributes such as title and Email-Address.
  • -Accountpassword (Read-Host -AsSecureString "pasword"): With this portion, we set the user's password by having the shell prompt us to enter a new password. (we can see it in the line below with the stars)
  • -Enabled $true: We are enabling the account for use. The user could not log in if this was set to \$False.

The second is validating that the user we created and the properties we set exist:

  • Get-ADUser -Identity MTanaka -Properties *: Here, we are searching for the user's properties MTanaka.
  • | : This is the Pipe symbol. It will be explored more in another section, but for now, it takes our output from Get-ADUser and sends it into the following command.
  • Format-Table Name,Enabled,GivenName,Surname,Title,Office,Mail: Here, we tell PowerShell to Format our results as a table including the default and extended properties listed.

Now, what if we need to modify a user? Set-ADUser is our ticket. Many of the filters we looked at earlier apply here as well. We can change or set any of the attributes that were listed. type this command :: Set-ADUser -Identity then the name the user and what you want to change type this here. see this


                                                              Why it's so importent:

Users and groups provide a wealth of opportunities regarding Pentesting a Windows environment. We will often see users misconfigured. They may be given excessive permissions, added to unnecessary groups, or have weak/no passwords set. Groups can be equally as valuable. Often groups will have nested membership, allowing users to gain privileges they may not need. These misconfigurations can be easily found and visualized with Tools like Bloodhound. For a detailed look at enumerating Users and Groups, check out the Windows Privilege Escalation module.

                                             Creating/Moving/Deleting Files & Directories

Many of the cmdlets we will discuss in this section can apply to working with files and folders, so we will combine some of our actions to work more efficiently. 

Command Alias Description
Get-Item gi Retrieve an object (could be a file, folder, registry object, etc.)
Get-ChildItem ls / dir / gci Lists out the content of a folder or registry hive.
New-Item md / mkdir / ni Create new objects. ( can be files, folders, symlinks, registry entries, and more)
Set-Item si Modify the property values of an object.
Copy-Item copy / cp / ci Make a duplicate of the item.
Rename-Item ren / rni Changes the object name.
Remove-Item rm / del / rmdir Deletes the object.
Get-Content cat / type Displays the content within a file or object.
Add-Content ac Append content to a file.
Set-Content sc overwrite any content in a file with new data.
Clear-Content clc Clear the content of the files without deleting the file itself.
Compare-Object diff / compare Compare two or more objects against each other. This includes the object itself and the content within.

foe creating file or folder just type:: new-item -name "desire name" -type directory/file

We can do so with the Add-Content cmdlet.for adding the txt just type Add-content ./ location or file name and "text here"

We can quickly knock this task out using the Rename-Item cmdlet. Lets' give it a try:Rename-Item .\previous file name -NewName new name. we can also change multiple file name or type at a time. like this. by typing this : get-childitem -Path *.txt | rename-item -NewName {$_.name -replace ".txt",".md"}. if you type this command it will change all file name in this location.

                                                                  Finding & Filtering Content

this section will dive into specifics of how PowerShell utilizes Objects, how we can filter based on Properties and content, and describe components like the PowerShell Pipeline further. Let us look at this through a user object context. A user can do things like access files, run applications, and input/output data.that command is spot-on for inspecting the administrator   local user object in PowerShell. Get-LocalUser administrator | get-member.The Select-Object cmdlet will help us achieve this. In this manner, we now understand what makes up a user object. Get-LocalUser administrator | Select-Object -Property *.that command gives you a full property dump of the administrator local user object.

that command is a radiant way to audit local users and see when their passwords were last set. Get-LocalUser * | Select-Object -Property Name, PasswordLastSet.We can also sort and group our objects on these properties. type this command.::Get-LocalUser * | Sort-Object -Property Name | Group-Object -Property Enabled

 that command filters services whose DisplayName contains the word that we will provide here :Get-Service | where DisplayName -like '*Defender*'.

Where and many other cmdlets can evaluate objects and data based on the values those objects and their properties contain. The output above is an excellent example of this utilizing the -like Comparison operator. It will look for anything that matches the values expressed and can include wildcards such as *. Below is a quick list (not all-encompassing) of other useful expressions we can utilize:

Comparison Operators

Expression Description
Like Like utilizes wildcard expressions to perform matching. For example, '*Defender*' would match anything with the word Defender somewhere in the value.
Contains Contains will get the object if any item in the property value matches exactly as specified.
Equal to Specifies an exact match (case sensitive) to the property value supplied.
Match Is a regular expression match to the value supplied.
Not specifies a match if the property is blank or does not exist. It will also match $False.

there are many other comparison operators we can use like, greater than, less than, and negatives like NotEqual, but in this kind of searching they may not be as widely used.  this command gives you a full property dump of any service whose display name contains  Defender. Get-Service | where DisplayName -like '*Defender*' | Select-Object -Property *. Now we can look at the services, determine if they are running, and even if we can, at our current permission level, affect the status of those services. we have used the | symbol to concatenate multiple commands we would usually issue separately. You can find a great example of installing PowerShell 7 here so that you can use many of the new and updated features. PowerShell allows us to have conditional execution of pipelines with the use of Chain operators. These operators ( && and || ) serve two main functions:

  • &&: Sets a condition in which PowerShell will execute the next command inline if the current command completes properly.

  • ||: Sets a condition in which PowerShell will execute the following command inline if the current command fails.

Some tools exist, like Snaffler, Winpeas, and the like, that can search for interesting files and strings. Select-String (sls as an alias) for those more familiar with using the Linux CLI, functions much in the same manner as Grep does or findstr.exe within the Windows Command-Prompt.

                                                               Working with Service

Get-Help *-Service 

The command  in PowerShell is used to retrieve help topics for all cmdlets whose names include the  verb-noun pattern. This is a wildcard search that matches any cmdlet ending with . for investing the services type ::   Get-Service | ft DisplayName,Status. it will  Display Name and Status in a formatted table.and for counting the service number type:: Get-Service | measure.for start, stop and restart the service just use :: start/stop/restart-service and service name.

for checking the service just use get-service and for more specificlly type get-service service name or if you want to customizable format. just use this Get-Service name of service | Select-Object -Property Name, StartType, Status, DisplayName

Now that we know how to work with services, let us look at how we can interact with remote hosts.The -ComputerName parameter allows us to specify that we want to query a remote host. Get-Service -ComputerName like desktop311509/rakib/hpelitbook etc, or more specificlly get theservices just type Get-Service -ComputerName name| Where-Object {$_.Status -eq "Running"}

Let us break this down now:

  • Invoke-Command: We are telling PowerShell that we want to run a command on a local or remote computer.
  • Computername: We provide a comma-defined list of computer names to query.
  • ScriptBlock {commands to run}: This portion is the enclosed command we want to run on the computer. For it to run, we need it to be enclosed in {}.

                                                      Working with the Registry

the Registry can be considered a hierarchal tree that contains two essential elements: keys and values.As Pentesters, the Registry is a great spot to find helpful information, plant persistence, and more. MITRE provides many great examples of what a threat actor can do with access (locally or remotely) to a host's registry hive. 

Keys, in essence, are containers that represent a specific component of the PC. A host systems Registry root keys are stored in several different files and can be accessed from C:\Windows\System32\Config\.For a detailed list of all Registry Hives and their supporting files within the OS, we can look HERE. Now let's discuss Values within the Registry. Values represent data in the form of objects that pertain to that specific Key. Those values are nested within the Installer key, which is, in turn, inside another key. We can reference the complete list of Registry Key Values HERE. In all, there are 11 different value types that can be configured. 

Registry Hives

Each Windows host has a set of predefined Registry keys that maintain the host and settings required for use. Below is a breakdown of each hive and what can be found referenced within.

Hive Breakdown

Name Abbreviation Description
HKEY_LOCAL_MACHINE HKLM This subtree contains information about the computer's physical state, such as hardware and operating system data, bus types, memory, device drivers, and more.
HKEY_CURRENT_CONFIG HKCC This section contains records for the host's current hardware profile. (shows the variance between current and default setups) Think of this as a redirection of the HKLM CurrentControlSet profile key.
HKEY_CLASSES_ROOT HKCR Filetype information, UI extensions, and backward compatibility settings are defined here.
HKEY_CURRENT_USER HKCU Value entries here define the specific OS and software settings for each specific user. Roaming profile settings, including user preferences, are stored under HKCU.
HKEY_USERS HKU The default User profile and current user configuration settings for the local computer are defined under HKU.

There are other predefined keys for the Registry, but they are specific to certain versions and regional settings in Windows. For more information on those entries and Registry keys in general, check out the documentation provided by Microsoft.

the Registry can be a treasure trove of information that can help us further our engagements. Everything from what software is installed, current OS revision, pertinent security settings, control of Defender, and more can be found in the Registry.

How Do We Access the Information?

we have several options to access the Registry and manage our keys. The first is using reg.exe. Reg is a dos executable explicitly made for use in managing Registry settings. The second is using the Get-Item and Get-ItemProperty cmdlets to read keys and values. If we wish to make a change, the use of New-ItemProperty will do the trick.

We will look at using Get-Item and Get-ChildItem first.Get-Item -Path Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run | Select-Object -ExpandProperty PropertyIt's a simple output and only shows us the name of the services/applications currently running. If we wished to see each key and object within a hive, we could also use Get-ChildItem with the -Recurse parameter like so:Get-ChildItem -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion -Recurseit is expanding and showing each key and associated values within the HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion key. We can make our output easier to read using the Get-ItemProperty cmdlet. Let's try that same query but with Get-ItemProperty.Get-ItemProperty -Path Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunNow let's break this down. We issued the Get-ItemProperty command, specified out path as looking into the Registry, and specified the key HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run. The output provides us with the name of the services started and the value that was used to run them (the path they were executed from). This Registry key is used to start services/applications when a user logs in to the host. It is a great key to have visibility over and to keep in mind as a penetration tester. There are several versions of this key which we will discuss a little later in this section.We queried the HKEY_LOCAL_MACHINE\SOFTWARE\7-Zip key with Reg.exe, which provided us with the associated values.For us as pentesters and administrators, finding data within the Registry is a must-have skill. This is where Reg.exe really shines for us. We can use it to search for keywords and strings like Password and Username through key and value names or the data contained. Before we put it to use, let's break down the use of Reg Query. We will look at the command string REG QUERY HKCU /F "password" /t REG_SZ /S /K.

  • Reg query: We are calling on Reg.exe and specifying that we want to query data.
  • HKCU: This portion is setting the path to search. In this instance, we are looking in all of HKey_Current_User.
  • /f "password": /f sets the pattern we are searching for. In this instance, we are looking for "Password".
  • /t REG_SZ: /t is setting the value type to search. If we do not specify, reg query will search through every type.
  • /s: /s says to search through all subkeys and values recursively.
  • /k: /k narrows it down to only searching through Key names.

Creating and Modifying Registry Keys and Values

When dealing with the modification or creation of new keys and values, we can use standard PowerShell cmdlets like New-Item, Set-Item, New-ItemProperty, and Set-ItemProperty or utilize Reg.exe again to make the changes we need. Let's try and create a new Registry Key below.
New-Item -Path HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce\ -Name TestKey
                                           
We now have a new key within the RunOnce key. By specifying the -Path parameter, we avoid changing our location in the shell to where we want to add a key in the Registry, letting us work from anywhere as long as we specify the absolute path. Let's set a Property and a value now. cmd:: New-ItemProperty -Path HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce\TestKey -Name "access" -PropertyType String -Value "C:\Users\htb-student\Downloads\payload.exe"

After using New-ItemProperty to set our value named access and specifying the value as C:\Users\htb-student\Downloads\payload.exe we can see in the results that our value was created successfully, and the corresponding information, such as path location and Key name.we can see the new key and its values in the image below from the GUI Registry editor.

If we wanted to add the same key/value pair using Reg.exe, we would do so like this: reg add "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce\TestKey" /v access /t REG_SZ /d "C:\Users\htb-student\Downloads\payload.exe"


Remove

Remove-ItemProperty -Path HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce\TestKey -Name "access"

                                                     Windows Event Log

Event is any action or occurrence that can be identified and classified by a system's hardware or software.Events can be generated or triggered through a variety of different ways including some of the following:

  • User-Generated Events
    • Movement of a mouse, typing on a keyboard, other user-controlled peripherals, etc.
  • Application Generated Events
    • Application updates, crashes, memory usage/consumption, etc.
  • System Generated Events
    • System uptime, system updates, driver loading/unloading, user login, etc.

Event Logging as defined by Microsoft:

"...provides a standard, centralized way for applications (and the operating system) to record important software and hardware events."

Windows attempts to resolve this issue by providing a standardized approach to recording, storing, and managing events and event information through a service known as the Windows Event Log.The main four log categories include application, security, setup, and system. Another type of category also exists called forwarded events.

Log Category Log Description
System Log The system log contains events related to the Windows system and its components. A system-level event could be a service failing at startup.
Security Log Self-explanatory; these include security-related events such as failed and successful logins, and file creation/deletion. These can be used to detect various types of attacks that we will cover in later modules.
Application Log This stores events related to any software/application installed on the system. For example, if Slack has trouble starting it will be recorded in this log.
Setup Log This log holds any events that are generated when the Windows operating system is installed. In a domain environment, events related to Active Directory will be recorded in this log on domain controller hosts.
Forwarded Events Logs that are forwarded from other hosts within the same network.

There are five types of events that can be logged on Windows systems:

Type of Event Event Description
Error Indicates a major problem, such as a service failing to load during startup, has occurred.
Warning A less significant log but one that may indicate a possible problem in the future. One example is low disk space. A Warning event will be logged to note that a problem may occur down the road. A Warning event is typically when an application can recover from the event without losing functionality or data.
Information Recorded upon the successful operation of an application, driver, or service, such as when a network driver loads successfully. Typically not every desktop application will log an event each time they start, as this could lead to a considerable amount of extra "noise" in the logs.
Success Audit Recorded when an audited security access attempt is successful, such as when a user logs on to a system.
Failure Audit Recorded when an audited security access attempt fails, such as when a user attempts to log in but types their password in wrong. Many audit failure events could indicate an attack, such as Password Spraying

Each log can have one of five severity levels associated with it, denoted by a number:

Severity Level Level # Description
Verbose 5 Progress or success messages.
Information 4 An event that occurred on the system but did not cause any issues.
Warning 3 A potential problem that a sysadmin should dig into.
Error 2 An issue related to the system or service that does not require immediate attention.
Critical 1 This indicates a significant issue related to an application or a system that requires urgent attention by a sysadmin that, if not addressed, could lead to system or application instability.

The Windows Event Log provides information about hardware and software events on a Windows system. All event logs are stored in a standard format and include the following elements:

  • Log name: As discussed above, the name of the event log where the events will be written. By default, events are logged for system, security, and applications.
  • Event date/time: Date and time when the event occurred
  • Task Category: The type of recorded event log
  • Event ID: A unique identifier for sysadmins to identify a specific logged event
  • Source: Where the log originated from, typically the name of a program or software application
  • Level: Severity level of the event. This can be information, error, verbose, warning, critical
  • User: Username of who logged onto the host when the event occurred
  • Computer: Name of the computer where the event is logged

There are many Event IDs that an organization can monitor to detect various issues. In an Active Directory environment, this list includes key events that are recommended to be monitored for to look for signs of a compromise. This searchable database of Event IDs is worth perusing to understand the depth of logging possible on a Windows system.

The Windows Event Log is handled by the EventLog services. On a Windows system, the service's display name is Windows Event Log, and it runs inside the service host process svchost.exe. It is set to start automatically at system boot by default. It is difficult to stop the EventLog service as it has multiple dependency services. If it is stopped, it will likely cause significant system instability. By default, Windows Event Logs are stored in C:\Windows\System32\winevt\logs with the file extension .evtx.

We can interact with the Windows Event log using the Windows Event Viewer GUI application via the command line utility wevtutil, or using the Get-WinEvent PowerShell cmdlet. Both wevtutil and Get-WinEvent can be used to query Event Logs on both local and remote Windows systems via cmd.exe or PowerShell.

The wevtutil command line utility can be used to retrieve information about event logs. It can also be used to export, archive, and clear logs, among other commands.

here's a lot of command that you can try one by one. let's say we want to display the last 5 most recent events from the Security log in text format. Local admin access is needed for this command.

 wevtutil : Windows Event Utility—used to query, export, and manage event logs.

• qe    : Query Events from a specified log.

• Security: Targets the Security event log.

• /c:5 : Limits output to the 5 most recent events.

• /rd:true : Reverse direction—starts from the newest and goes backward.

• /f:text : Formats output as plain text (instead of XML).

We can also export events from a specific log for offline processing. Local admin is also needed to perform this export. type this command:;

wevtutil epl System C:\system_export.evtx

we can interact with Windows Event Logs using the Get-WinEvent PowerShell cmdlet.
We can query for the last X number of events, looking specifically for the last five events using the -MaxEvents parameter. Here we will list the last five events recorded in the Security log. By default, the newest logs are listed first. If we want to get older logs first, we can reverse the order to list the oldest ones first using the -Oldest parameter.
Practice more with wevtutil and Get-WinEvent to become more comfortable with searching logs. Microsoft provides some examples for Get-WinEvent, while this site shows examples for wevtutil, and this site has some additional examples for using Get-WinEvent.

                                                        NETWORKING

Below we will quickly cover some standard protocols you could run into when administering or pentesting Windows hosts.

Protocol Description
SMB SMB provides Windows hosts with the capability to share resources, files, and a standard way of authenticating between hosts to determine if access to resources is allowed. For other distros, SAMBA is the open-source option.
Netbios NetBios itself isn't directly a service or protocol but a connection and conversation mechanism widely used in networks. It was the original transport mechanism for SMB, but that has since changed. Now it serves as an alternate identification mechanism when DNS fails. Can also be known as NBT-NS (NetBIOS name service).
LDAP LDAP is an open-source cross-platform protocol used for authentication and authorization with various directory services. This is how many different devices in modern networks can communicate with large directory structure services such as Active Directory.
LLMNR LLMNR provides a name resolution service based on DNS and works if DNS is not available or functioning. This protocol is a multicast protocol and, as such, works only on local links ( within a normal broadcast domain, not across layer three links).
DNS DNS is a common naming standard used across the Internet and in most modern network types. DNS allows us to reference hosts by a unique name instead of their IP address. This is how we can reference a website by "WWW.google.com" instead of "8.8.8.8". Internally this is how we request resources and access from a network.
HTTP/HTTPS HTTP/S HTTP and HTTPS are the insecure and secure way we request and utilize resources over the Internet. These protocols are used to access and utilize resources such as web servers, send and receive data from remote sources, and much more.
Kerberos Kerberos is a network level authentication protocol. In modern times, we are most likely to see it when dealing with Active Directory authentication when clients request tickets for authorization to use domain resources.
WinRM WinRM Is an implementation of the WS-Management protocol. It can be used to manage the hardware and software functionalities of hosts. It is mainly used in IT administration but can also be used for host enumeration and as a scripting engine.
RDP RDP is a Windows implementation of a network UI services protocol that provides users with a Graphical interface to access hosts over a network connection. This allows for full UI use to include the passing of keyboard and mouse input to the remote host.
SSH SSH is a secure protocol that can be used for secure host access, transfer of files, and general communication between network hosts. It provides a way to securely access hosts and services over insecure networks.

PowerShell has several powerful built-in cmdlets made to handle networking services and administration. The NetAdapter, NetConnection, and NetTCPIP modules are just a few that we will practice with today.

Net Cmdlets

Cmdlet Description
Get-NetIPInterface Retrieve all visible network adapter properties.
Get-NetIPAddress Retrieves the IP configurations of each adapter. Similar to IPConfig.
Get-NetNeighbor Retrieves the neighbor entries from the cache. Similar to arp -a.
Get-Netroute Will print the current route table. Similar to IPRoute.
Set-NetAdapter Set basic adapter properties at the Layer-2 level such as VLAN id, description, and MAC-Address.
Set-NetIPInterface Modifies the settings of an interface to include DHCP status, MTU, and other metrics.
New-NetIPAddress Creates and configures an IP address.
Set-NetIPAddress Modifies the configuration of a network adapter.
Disable-NetAdapter Used to disable network adapter interfaces.
Enable-NetAdapter Used to turn network adapters back on and allow network connections.
Restart-NetAdapter Used to restart an adapter. It can be useful to help push changes made to adapter settings.
test-NetConnection Allows for diagnostic checks to be ran on a connection. It supports ping, tcp, route tracing, and more.

When we cannot access Windows systems or need to manage hosts remotely, we can utilize PowerShell, SSH, and RDP, among other tools, to perform our work. Let's cover the main ways we can enable and use remote access. First, we will discuss SSH.We can use SSH to access PowerShell on a Windows system over the network.We can set up an SSH server on a Windows target using the Add-WindowsCapability cmdlet and confirm that it is successfully installed using the Get-WindowsCapability cmdlet. Once we have confirmed SSH is installed, we can use the Start-Service cmdlet to start the SSH service. We can also use the Set-Service cmdlet to configure the startup settings of the SSH service if we choose.With SSH installed and running on a Windows target, we can connect over the network with an SSH client. Just type in the shell :: ssh username@ip. likr this ssh htb-student@10.129.224.248


Windows Remote Management (WinRM) can be configured using dedicated PowerShell cmdlets and we can enter into a PowerShell interactive session as well as issue commands on remote Windows target(s). We will notice that WinRM is more commonly enabled on Windows Server operating systems, so IT admins can perform tasks on one or multiple hosts. It's enabled by default in Windows Server.Windows desktop operating systems (Windows 10 & Windows 11) as well. When WinRM is enabled on a Windows target, it listens on logical ports 5985 & 5986.WinRM can be enabled on a Windows target using the following commands:


Once we have enabled and configured WinRM, we can test remote access using the Test-WSMan PowerShell cmdlet.We also have the option to use the Enter-PSSession cmdlet to establish a PowerShell session with a Windows target.Enter-PSSession -ComputerName "ip here" -Credential "username" -Authentication Negotiate. whrn prompt then type password

                                                Interacting With The Web

When it comes to interacting with the web via PowerShell, the Invoke-WebRequest cmdlet is our champion. We can use it to perform basic HTTP/HTTPS requests (like GET and POST), parse through HTML pages, download files, authenticate, and even maintain a session with a site. If you prefer aliases, the Invoke-WebRequest cmdlet is aliased to wget, iwr and curl. Those familiar with Linux. Let's look at the help from Invoke-WebRequest for a minute.

Notice in the synopsis from the Get-Help output it states:

"Gets content from a web page on the Internet."

While this is the core functionality, we can also use it to get content that we host on web servers in the same network environment. We have talked it up, and now let's try and do a simple web request using Invoke-WebRequest. We can perform a basic Get request of a website using the -Method GET modifier with the Invoke-WebRequest cmdlet, as seen below.

We can practice using Invoke-WebRequest by downloading a popular tool used by many pentesters called PowerView.Using Invoke-WebRequest is simple; we specify the cmdlet and the exact URL of a resource we want to download:

-Uri "past file url"

After the URL, we specify the location and file name of the resource on the Windows system we are downloading it from:

-OutFile "C:\PowerView.ps1"

for example see this :: Invoke-WebRequest -Uri "https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Recon/PowerView.ps1" -OutFile "C:\PowerView.ps1"


this is the file url and after the typing the url it will download here as a output file location will be the C  drive.
 This could allow us to download files onto the target host, allowing us to further our access to that target and move to others on the network. File transfer methods are covered in greater detail in the module File Transfers.

What If We Can't Use Invoke-WebRequest?

So what happens if we are restricted from using Invoke-WebRequest for some reason? Not to fear, Windows provides several different methods to interact with web clients. The first and more challenging interaction path is utilizing the .Net.WebClient class. This handy class is a .Net call we can utilize as Windows uses and understands .Net. This class contains standard system.net methods for interacting with resources via a URI (web addresses like github.com/project/tool.ps1). Let's look at an example:


So it worked. Let's break down what we did:

  • First we have the Download cradle (New-Object Net.WebClient).DownloadFile(), which is how we tell it to execute our request.
  • Next, we need to include the URI of the file we want to download as the first parameter in the (). For this example, that was "https://github.com/BloodHoundAD/BloodHound/releases/download/4.2.0/BloodHound-win32-x64.zip".
  • Finally, we need to tell the command where we want the file written to with the second parameter , "BloodHound.zip".

The command above would have downloaded the file to the current directory we are working from as Bloodhound.zip. Looking at our terminal, we can see that it executed successfully because the file Bloodhound.zip now exists in our working directory. If we wanted to place it somewhere else, we would have to specify the full path. 


0 Comments