Live Examination

Examining Processes

To examine a live system, investigate running processes using PowerShell's Get-Process cmdlet. Running it without arguments displays information on active processes.

PS C:\> Get-Process                  # Get brief information about running processes

When you run Get-Process, it returns an object with both visible and hidden data. To access more information, you can use the pipe (|) to send the output to Select-Object, which allows you to display additional fields or all data using the asterisk (*) wildcard.

PS C:\> Get-Process 'powersh*'                         # Get brief information about a named process with wildcard
PS C:\> Get-Process 'powershell' | Select-Object *     # Detailed information
PS C:\> Get-Process -ComputerName SEC504STUDENT        # Remote systems
PS C:\> Get-Process | Select-Object -First 1 *

With PowerShell, cmdlets like Get-Process are useful but limited; they don't provide details such as the parent process ID or command line parameters, which are crucial for incident response. To access this information, you can use Get-CimInstance, which leverages the Windows Management Instrumentation (WMI) framework. By querying the Win32_Process class, you can retrieve detailed process information, including the process ID, name, and command line parameters.

PS C:\> Get-CimInstance -Class Win32_Process | Select-Object ProcessId, ProcessName, CommandLine

We can combine Get-Process with Get-CimInstance to obtain more details about a process. For example, we can use Get-Process to find the process ID for LSASS, then use Get-CimInstance to check for any unusual child processes linked to LSASS, which can indicate a security compromise.

PS C:\> Get-Process 'lsass' | Select-Object -Property Id
PS C:\> Get-CimInstance -Class Win32_Process | Where-Object -Property ParentProcessId -EQ 716

TIP: Get-Process uses Id but Get-CimInstance uses ProcessId to refer to the same information.

c:\> wmic process list brief

Basic Process Information

wmic process list brief                                               # List all running processes:
wmic process list full                                                # Detailed information about all processes
wmic process get name,processid,commandline                           # List processes with specific fields
wmic process where "name='notepad.exe'" get processid,commandline     # Find a specific process by name
wmic process where "ProcessId=8096" get name,executablepath           # Find a process by PID
wmic process where "processid=1234" call terminate                    # Kill a process by PID
wmic process where "name='notepad.exe'" call terminate                # Kill a process by name

Identifying Suspicious Processes

  • Is it a new or unrecognized process?

  • Is the name random-looking?

  • Is it running from a non-standard path?

  • Is the parent suspicious?

  • Is the parent-child relationship suspicious?

  • Is it tied to suspicious activity?

  • Base64 encoded command-line options?

Pay close attention to any running processes that have base64-encoded command-line options, especially PowerShell. Many attackers and malware authors use PowerShell's -EncodedCommand option to specify the content of a script to run at the command line. This way there are no extraneous .ps1 files left in the file system. Note that not every PowerShell script that uses -EncodedCommand is malicious, but they are worthy of further investigation.

Examining Network Usage

For live Windows examination, checking current network usage is key. This involves identifying listening processes for inbound attacker connections or outbound connections to a C2 server. The PowerShell Get-NetTCPConnection cmdlet provides details on listening ports, established connections, and other network statuses, helping to investigate both inbound and outbound connections.

PS C:\> Get-NetTCPConnection

You can use Get-NetTCPConnection to filter connections by state (e.g., listening) and pipe it to Select-Object for specific details.

PS C:\> Get-NetTCPConnection -State Listen | Select-Object -Property LocalAddress,LocalPort,OwningProcess

The challenge with Get-NetTCPConnection is that it shows the process ID but not the process name. However, you can use Get-Process -Id processid to find the process name. Alternatively, you can combine both tasks into a single PowerShell command using a hash table with the @{} syntax.

PS C:\> Get-NetTCPConnection | select local*,remote*,state,@{Name='Process';Expression={(Get-Process -Id
$_.OwningProcess).ProcessName}} | format-table

Port 445 is listening on all interfaces: "::" for IPv6 and "0.0.0.0" for IPv4. The RemotePort is 0 because it doesn't apply to listening entries.

A service is listening on TCP port 9001, but it's restricted to the local IP address 127.0.0.1, meaning it's only accessible from the local system and not from any external systems.

Similar to identifying suspicious processes, there is no perfect list of suspicion indicators for identifying suspicious network traffic. With that in mind, here are some common things to consider:

  • Any unusual network activity by a process, like Notepad connecting to port 80 multiple times or a service making repeated outbound connections, which could also be an automatic update service.

  • Abnormal network activity for the environment, such as high activity during off-hours, long HTTP/HTTPS sessions, and frequent small outbound communications (beaconing).

  • Unique indicators for specific techniques include lateral movement over SMB, which involves connections to SMB ports (TCP/UDP 135-139 and 445) on internal systems.

  • Traffic to or from known malicious hosts, identified through threat intelligence or suspicious processes and connections.

Examining Services

Another live examination task is to check Windows services, which are background tasks managed by the services.exe process and can be set to start automatically. Attackers often use these services for persistence to maintain access after a reboot. Use the PowerShell Get-Service cmdlet to view all running services or specify a service name for details.

PS C:\> Get-Service
PS C:\> Get-Service FDResPub

Get-Service doesn't show all details, like the program's path. To get this, use Get-CimInstance -ClassName Win32_Service for more service information.

PS C:\> Get-CimInstance -ClassName Win32_Service | Format-List
Name,Caption,Description,PathName

Registry Interrogation

PowerShell can query the Windows registry like a file system, treating top-level keys (e.g., HKEY_LOCAL_MACHINE, HKEY_CURRENT_USER) as drives, similar to how folders and drive letters are organized.

PS C:\> Get-ChildItem 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows
\CurrentVersion\Uninstall\' | Select-Object PSChildName
PS C:\> Get-ItemProperty 'HKLM:Software\Microsoft\Windows\CurrentVersion\Run'

To navigate registry keys, use Get-ChildItem (or dir) to list contents, or Set-Location (or cd) to change to a registry key location and list items from there.

PS C:\> Set-Location 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\'

Unusual Accounts

During live examination, check local user accounts, as attackers may create new ones or add them to the Administrators group. Use the PowerShell cmdlet Get-LocalUser to list accounts, and pipeline it with Where-Object to filter by attributes, such as showing only enabled accounts with the $True variable.

PS C:\> Get-LocalUser
PS C:\> Get-LocalUser | Where-Object -Property Enabled -EQ $true
PS C:\> Get-LocalUser | Where-Object { $_.Enabled -eq $true }

Similarly, the Get-LocalGroup will display all local groups on the Windows host. The Get- LocalGroupMember cmdlet will display the members of the specified group.

PS C:\> Get-LocalGroup
PS C:\> Get-LocalGroupMember Administrators

Unusual Scheduled Tasks

A common Windows investigation task is examining scheduled tasks, which run at set intervals, specific times, or after certain events, like login failures. Attackers may use scheduled tasks for persistence, often giving them unusual names or disguising them with legitimate software names to blend into the system.

PS C:\> Get-ScheduledTask
PS C:\> Export-ScheduledTask -TaskName 'SR' -TaskPath \Microsoft\Windows\SystemRestore\
PS C:\> Get-ScheduledTaskInfo -TaskName 'SR' -TaskPath \Microsoft\Windows\SystemRestore\
PS C:\> Get-ScheduledTaskInfo -TaskName 'SR' -TaskPath \Microsoft\Windows\SystemRestore\ | Select-Object LastRunTime

The Get-ScheduledTask cmdlet doesn't show full details like the executed command or its arguments. To get these, use Export-ScheduledTask to export the task in XML format. For information on the last run time of a task, use Get-ScheduledTaskInfo to check the LastRunTime, NextRunTime, and LastTaskResult properties.

Unusual Log Entries

You can use the Get-WinEvent cmdlet in PowerShell to examine Windows Event Logs. It replaces the older Get-EventLog cmdlet. By specifying an event log name, Get-WinEvent displays a summary of events, and with filtering, you can narrow down the analysis to specific date ranges or log resources.

PS C:\> $start = Get-Date 8/23/2024;
PS C:\> $end = Get-Date 8/25/2024;
PS C:\> Get-WinEvent -FilterHashtable @{LogName='Security'; StartTime=$start; EndTime=$end;}

Get-WinEvent allows filtering by Event Log name using -LogName, and specific events can be displayed with Where-Object. While both Where-Object and FilterHashtable can be used, FilterHashtable is generally faster.

PS C:\> Get-WinEvent -LogName System | Where-Object -Property Id -EQ 7045 |
Format-List -Property TimeCreated,Message

In these examples we investigate the System and the Security Event Logs, but Windows records a lot of detail in other Event Logs as well. We can run Get-WinEvent -Listlog * | Select LogName, RecordCount to get a list of all Event Logs on the system and the number of records in each log.

Differential Analysis

During live examinations, the vast amount of data, such as services, processes, scheduled tasks, and network connections, can be overwhelming. Differential analysis helps by comparing the current system to a baseline configuration (like the original gold image) to narrow down the investigation.

PS C:\> Get-Service > baseline-services-20220325.txt
PS C:\> Get-Service > services-liveinvestigation.txt
PS C:\> $baseline = Get-Content .\baseline-services-20220325.txt
PS C:\> $current = Get-Content .\services-liveinvestigation.txt
PS C:\> Compare-Object -ReferenceObject $baseline -DifferenceObject $current

In this example, we use Get-Service to collect a list of services, saving the output to baseline-services-20220325.txt. During an investigation, we run the same command and save it to services-liveinvestigation.txt. Then, we load both files into PowerShell objects $baseline and $current using Get-Content, and compare them with Compare-Object, using -ReferenceObject for the baseline and -DifferenceObject for the investigation data.

The output of Compare-Object lets us quickly identify configuration changes between the gold image and the system under investigation.

PowerShell Cheat Sheet

Conduct a ping sweep:

PS C:\> 1..255 | % {echo "10.10.10.$_";ping -n 1 -w 100 10.10.10.$_ | Select-String ttl}

Conduct a por t scan:

PS C:\> 1..1024 | % {echo ((new-object
Net.Sockets.TcpClient).Connect("10.10.10.10",$_)) "Port $_ is
open!"} 2>$null

Fetch a file via HTTP (wget in PowerShell):

PS C:\> (New-Object
System.Net.WebClient).DownloadFile("http://10.10.10.10/nc.exe","
nc.exe")

Find all files with a par ticular name:

PS C:\> Get-ChildItem "C:\Users\" -recurse -include
*passwords*.txt

Get a listing of all installed Microsoft Hotfixes:

PS C:\> Get-HotFix

Navigate the Windows registry:

PS C:\> cd HKLM:\
PS HKLM:\> ls

List programs set to start automatically in the registry:

PS C:\> Get-ItemProperty HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\run
Functionality PowerShell Legacy Command

List processes

Get-Process

wmic.exe process

Network connections

Get-NetTCPConnection

netstat.exe -nao

List services

Get-Service

sc.exe query

Registry access

Get-ChildItem

reg.exe

List users

Get-LocalUser

net.exe user

List groups

Get-LocalGroup

net.exe localgroup

List scheduled tasks

Get-ScheduledTask

schtasks.exe

Access Event Logs

Get-WinEvent

wevtutil.exe

Identify differences

Compare-Object

fc.exe

It's OK to continue using legacy commands to get the information you need to complete your analysis! When invoking legacy commands, specify .exe at the end of the command to avoid using PowerShell aliases with the same name.

Additional Supporting Tools

The Sysinternals tools are excellent (and free!):

  • Process Explorer: Incredibly detailed information for running processes.

  • Process Monitor: Shows file system, registry, network, and process information in real time.

  • TCPView: Maps listening and active TCP and UDP activity to the associated applications.

  • Autoruns: Displays a comprehensive list of Autostart Extensibility Points (ASEP).

  • Sysmon: Collects detailed event information for system monitoring and analysis.

  • Procdump: CLI tool to capture memory for a running process for analysis.

Lab 1.1: Live Windows Examination

Identify the PowerShell commands that will allow you to examine various aspects of a system and nd signs of a possible compromise. Make sure to include commands that will:

  • Show what programs are running

  • Show listening ports

  • Show what accounts exist on the system

  • Show what groups exist, and which accounts are in each group

  • Show what network shares are available

  • Identify registry keys associated with Auto Start Extensibility

  • Identify interesting files

Process Enumeration

Let's look at the running processes by invoking the Get-Process command, as shown here.

Get-Process
  • Handles : A count of handles (open les, sockets, and pipe resources)

  • NPM(K) : The amount of non-paged memory the process is using in kilobytes

  • PM(K) : The amount of paged memory the process is using in kilobytes

  • WS(K) : The process working set size (the total amount of memory allocated to a process) in kilobytes

  • CPU(s) : The amount of processor time that the process has used on all processors, in seconds

  • Id : The unique identier for a process so that the system can reference it by the numeric value, also known as a PID

  • ProcessName : The process name, often the executable name

Get-Process lsass

We can also get more information about the process than the default columns displayed.

Get-Process lsass | Select-Object -Property *

In this command, we requested only three specific fields; Path, Name, and Id (process ID) instead of all properties as in the previous Get-Process command, making it more manageable to view.

Get-Process | Select-Object -Property Path, Name, Id
Get-Process | Select-Object -Property Path, Name, Id | Where-Object -Property Name -EQ explorer

We can use Where-Object to filter Get-Process output for potential IOCs, such as processes running from temporary directories, which is often a sign of malicious activity rather than normal system use.

Get-Process | Select-Object -Property Path, Name, Id | Where-Object -Property Path -Like "*temp*"

In this output we've identied a suspicious process: calcache . It's possible the process could be legitimate though, so let's continue our analysis to investigate other factors as well

Network Enumeration

In the previous section, we explored running processes; now we will examine the network listeners and connections on this host.

Get-NetTCPConnection

The command output is too broad to view easily. Let's use a technique similar to what we used with Get-Process to show only the LocalAddress, LocalPort, State, and OwningProcess fields.

Get-NetTCPConnection | Select-Object -Property LocalAddress, LocalPort, State, OwningProcess

Several processes are listening for connections on the local system. One process is listening on all interfaces (local address 0.0.0.0) and is using an uncommon Windows port number: 4444.

The process ID for TCP port 4444 is 4380. We know the process ID, but not the process name. We can return to the Get-Process command to display the process details for this process ID.

PS C:\Tools\LiveInvestigation> Get-Process | Select-Object -Property
Path, Name, Id | Where-Object -Property Id -eq 4380

The calcache process is back and listening on TCP port 4444. Let's terminate it.

PS C:\Tools\LiveInvestigation> Get-Process | Select-Object -Property
Path, Name, Id | Where-Object -Property Id -eq 4380 | Stop-Process

PS C:\Tools\LiveInvestigation> Get-Process calcache

We still need to figure out how the attacker started the suspicious process. Let's keep examining autostart locations in the Windows registry.

Registry Startup Keys

A common way to start a process automatically is by adding a registry value to the Windows Run or RunOnce keys, known as Autostart Extensibility Points (ASEPs). These keys initiate processes when the system boots or a user logs in. Windows supports several ASEP registry keys, with four being particularly common:

  • HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run

  • HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce

  • HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run

  • HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce

Using PowerShell, we can use the Get-ChildItem command to enumerate registry keys, and the Get-ItemProperty command to enumerate registry values in a specic key.

Get-ChildItem HKCU:

In this output we see the Name column, which will be registry keys, and the Property column, which will be registry values in the top-level keys for the HKEY_CURRENT_USER hive (abbreviated HKCU ).

Get-ItemProperty "HKLM:\Software\Microsoft\Windows\CurrentVersion\Run"
Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce"
Get-ItemProperty "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run"
Get-ItemProperty "HKCU:\Software\Microsoft\Windows\CurrentVersion\RunOnce"

The output shows no registry values in the RunOnce keys, but both HKLM and HKCU Run keys have values. The HKLM Run key includes two programs (SecurityHealth and VMware User Process) with associated property values.

For the HKCU Run command we see an entry for Calcache, which corresponds to the Calcache process we identified earlier.

Let's remove the Calcache value from the Run key using Remove-ItemProperty.

Remove-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run" -Name "Calcache"
Get-ItemProperty "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run\Calcache"

Next, let's remove the calcache.exe program as shown here.

Remove-Item $env:temp\calcache.exe
Get-ChildItem $env:temp\calcache.exe

Differential Analysis

The analysis is progressing well, but attackers have multiple ways to deploy malware. We need to establish a baseline for comparison to assess the current environment.

There are three baseline files for services, scheduled tasks, and local users are stored in the C:\Tools\LiveInvestigation\baseline folder. Let’s review them.

Get-ChildItem baseline

These three files are generated with the following commands.

Get-Service | Select-Object -ExpandProperty Name | Out-File "baseline/services.txt"
Get-ScheduledTask | Select-Object -ExpandProperty TaskName | Out-File "baseline/scheduledtasks.txt"
Get-LocalUser | Select-Object -ExpandProperty Name | Out-File "baseline/localusers.txt"

Let’s use the same commands to get the current services, scheduled tasks, and local users.

Next, we'll compare the newly-generated output to the baseline information.

Services Differential Analysis

$servicesnow = Get-Content .\services.txt
$servicesbaseline = Get-Content baseline\services.txt

Compare-Object $servicesbaseline $servicesnow

The Compare-Object output shows a new service, Dynamics. While it might be suspicious like the Calcache process, we need to further investigate to determine if it's malicious.

Users Differential Analysis

Let’s repeat this process, using differential analysis to evaluate the local users on the system.

$usersnow = Get-Content .\localusers.txt
$usersbaseline = Get-Content .\baseline\localusers.txt

Compare-Object $usersbaseline $usersnow

We can see the added username is dynamics.

We've used differential analysis to compare the system configuration to the baseline. Now, let's check for another way an attacker might maintain persistent access: a scheduled task.

Scheduled Tasks Differential Analysis

Scheduled tasks are jobs that run on Windows at a specic time and with a specic frequency.

Get-ScheduledTask
$scheduledtasksnow = Get-Content .\scheduledtasks.txt
$scheduledtasksbaseline = Get-Content .\baseline\scheduledtasks.txt

Compare-Object $scheduledtasksbaseline $scheduledtasksnow

Now we can see that the added scheduled task is Microsoft eDynamics.

Scheduled Task Detail

So far we’ve found signs of malicious behavior, but let’s keep investigating the scheduled tasks. Use the Export-ScheduledTask command to examine them in detail.

Export-ScheduledTask -TaskName "Microsoft eDynamics"

Look at the closing element labeled Actions . Here we see that the scheduled task launches a command C:\WINDOWS\dynamics.exe , and it uses the sc.exe (Service Control) utility to start the service whenever this task is executed on the host.

Removing Microsoft eDynamics

By analyzing the scheduled task, and through dierential analysis, we identied several components of this malicious software:

  • A service named dynamics (dierential analysis).

  • A process named dynamics (scheduled task detail).

  • A program named C:\WINDOWS\dynamics.exe (scheduled task detail)

  • A scheduled task named Microsoft eDynamics (dierential analysis).

  • A local user account named dynamics (differential analysis)

Let's clean up the system, starting with the service.

Stop-Service -Name Dynamics

Next, stop the Dynamics process.

Get-Process -Name Dynamics | Stop-Process

Next, remove the dynamics.exe directory from the C:\Windows directory.

Remove-Item C:\Windows\Dynamics.exe

The service has been stopped; now let’s remove it.

sc.exe delete dynamics
#OR
Get-CimInstance -ClassName Win32_Service -Filter "Name='Dynamics'" | Remove-CimInstance

Next, remove the scheduled task, using Unregister-ScheduledTask.

Unregister-ScheduledTask -TaskName "Microsoft eDynamics"

Finally, remove the local user using Remove-LocalUser.

Remove-LocalUser -Name dynamics

Bonus Challenge Walkthrough

1) What TCP port is the backdoor listening on?

Now we've a baseline of the listening TCP ports.

Get-NetTCPConnection -State Listen | Out-File tcpports-baseline.txt

Let's get the current listening TCP ports, save them to a file, load both files into variables, and compare to find differences.

Get-NetTCPConnection -State Listen | Out-File tcpports-cuurent.txt
$baseline = Get-Content .\tcpports-baseline.txt
$current = Get-Content .\tcpports-current.txt
Compare-Object $baseline $current

The Compare-Object output shows a single line of difference. 1572 is the new listening TCP port.

Answer: 1027

2) What is the process ID number of the backdoor?

We have the listening TCP port, but not the process ID. Let's use Get-NetTCPConnection to find it.

Get-NetTCPConnection -State Listen | Where-Object -Property LocalPort 
-EQ 1027 | Select-Object -Property OwningProcess

Answer: 3248

3) What is the parent process ID number of the backdoor?

Get-CimInstance -ClassName Win32_Process | Where-Object -Property ProcessId -EQ 3248 | 
Select-Object -Property ParentProcessId

Answer: 6544

4) What is the flag shown when you connect to the backdoor?

nc 127.0.0.1 1027
TheFlagisBack582474434

Answer: TheFlagisBack582474434

5) What TCP port is the backdoor listening on now?

The backdoor is listening on a different TCP port now. Since we know the process ID, we can get the tcp port number.

Get-NetTCPConnection -State Listen | Where-Object -Property OwningProcess -EQ 3248 
| Select-Object LocalPort

Answer: 1029

6) Stop the backdoor process using PowerShell.

Get-Process -Id 6544
Get-Process -Id 6544 | Stop-Process

7) What is the process ID number of the backdoor?

We are asked to identify the process ID of a new backdoor. The clue here is that the new backdoor is a PowerShell-based process.

Get-Process -Name powershell

The output shows both the backdoor session and the analysis PowerShell session. To distinguish them, let's rerun the command and include a pipeline to get the process ID and start time.

Get-Process -Name powershell | Select-Object Id, StartTime

The PowerShell process with the latest start time is the backdoor.

8) What is the flag contained in the script executed by the backdoor?

Get-CimInstance -Class Win32_Process | Where-Object -Property ProcessId -EQ 4316 | 
Select-Object -ExpandProperty CommandLine

Next we need to decode the Base64 value seen on the command line following -enc.

[System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String
("dwBoAGkAbABlACgAJAB0AHIAdQBlACkAewAkAGYAbABhAGcAIAA9ACAAIgBTAGEAcwBxAHUAYQB0AGMAaAA4ADYAMwAyADQANwA5ADIAMAA2ACIAOwAgAFsAUwB5AHMAdABlAG0ALgBUAGgAcgBlAGEAZABpAG4AZwAuAFQAaAByAGUAYQBkAF0AOgA6AFMAbABlAGUAcAAoADEAMAAwADAAMAApAH0AOwA="))

Answer: Sasquatch8632479206

9) We are finally asked to kill the backdoor process.

PS C:\temp> Get-Process -Id 4316 | Stop-Process

Last updated