T1185

Browser Session Hijacking

Collection Last updated:

Adversaries may take advantage of security vulnerabilities and inherent functionality in browser software to change content, modify user behaviors, and intercept information as part of various browser session hijacking techniques. A specific example is when an adversary injects software into a browser process that allows them to inherit cookies, HTTP sessions, and SSL client certificates of a user, then uses the browser as a pivot into an authenticated intranet. Executing browser-based behaviors such as pivoting may require specific process permissions, such as SeDebugPrivilege and/or high-integrity/administrator rights. Another technique involves redirecting browser traffic through an adversary-controlled proxy injected into the browser process, allowing session impersonation without modifying user-visible traffic. Malware families such as TrickBot, Dridex, IcedID, QakBot, and Cobalt Strike implement browser pivoting and web inject techniques to steal banking credentials, session tokens, and SSL certificates.

What is T1185 Browser Session Hijacking?

Browser Session Hijacking (T1185) maps to the Collection tactic — the adversary is trying to gather data of interest to their goal in MITRE ATT&CK.

This page provides production-ready detection logic for Browser Session Hijacking, covering the data sources and telemetry it touches: Process: Process Access, Module: Module Load, Microsoft Defender for Endpoint DeviceEvents, Microsoft Defender for Endpoint DeviceImageLoadEvents. The queries below are rated high severity at high confidence, and ship for 7 SIEM platforms — KQL, SPL, Elastic, QRadar, Sumo, YARA-L, LogScale.

MITRE ATT&CK

Tactic
Collection
Technique
T1185 Browser Session Hijacking
Canonical reference
https://attack.mitre.org/techniques/T1185/
Microsoft Sentinel / Defender
kusto
let BrowserProcesses = dynamic(["chrome.exe", "msedge.exe", "firefox.exe", "iexplore.exe", "microsoftedge.exe", "brave.exe", "opera.exe", "safari.exe"]);
let KnownGoodInjectors = dynamic(["MsMpEng.exe", "csrss.exe", "werfault.exe", "WerFaultSecure.exe", "dwm.exe", "taskmgr.exe"]);
// === Detection 1: Process injection into browser processes ===
let BrowserInjection = DeviceEvents
| where Timestamp > ago(24h)
| where ActionType in ("CreateRemoteThreadApiCall", "WriteProcessMemoryApiCall", "SetThreadContextRemoteApiCall", "QueueUserApcRemoteApiCall", "OpenProcessApiCall")
| where FileName in~ (BrowserProcesses)
| where InitiatingProcessFileName !in~ (BrowserProcesses)
| where InitiatingProcessFileName !in~ (KnownGoodInjectors)
| extend InjectionMethod = case(
    ActionType == "CreateRemoteThreadApiCall", "Remote thread injection",
    ActionType == "WriteProcessMemoryApiCall", "Memory write injection",
    ActionType == "SetThreadContextRemoteApiCall", "Thread context hijacking",
    ActionType == "QueueUserApcRemoteApiCall", "APC queue injection",
    ActionType == "OpenProcessApiCall", "Suspicious process handle open",
    "Unknown injection"
)
| project Timestamp, DeviceName, AccountName, DetectionSource="ProcessInjection",
         InjectionMethod, TargetBrowser=FileName,
         InjectorProcess=InitiatingProcessFileName,
         InjectorCommandLine=InitiatingProcessCommandLine,
         InjectorParent=InitiatingProcessParentFileName;
// === Detection 2: Suspicious DLL loads inside browser processes ===
let SuspiciousBrowserDllLoads = DeviceImageLoadEvents
| where Timestamp > ago(24h)
| where InitiatingProcessFileName in~ (BrowserProcesses)
| where not(FolderPath has_any (
    "\\Google\\Chrome\\", "\\Mozilla Firefox\\", "\\Microsoft\\Edge\\",
    "\\Windows\\System32\\", "\\Windows\\SysWOW64\\", "\\Windows\\WinSxS\\",
    "\\Program Files\\Google\\", "\\Program Files (x86)\\Mozilla\\",
    "\\Program Files\\Microsoft\\", "\\Program Files (x86)\\Microsoft\\"
))
| where not(FileName has_any ("d3d", "opengl", "vulkan", "nvidia", "amd", "intel"))
| project Timestamp, DeviceName, AccountName, DetectionSource="SuspiciousDllLoad",
         InjectionMethod="Reflective/manual DLL load in browser",
         TargetBrowser=InitiatingProcessFileName,
         InjectorProcess=FileName,
         InjectorCommandLine=FolderPath,
         InjectorParent=InitiatingProcessParentFileName;
// === Combine and surface ===
BrowserInjection
| union SuspiciousBrowserDllLoads
| sort by Timestamp desc

Detects browser session hijacking via two complementary signals in Microsoft Defender for Endpoint: (1) process injection events targeting browser processes — CreateRemoteThread, WriteProcessMemory, SetThreadContext, APC queue injection, and suspicious OpenProcess API calls against chrome.exe, msedge.exe, firefox.exe, and others from unexpected initiating processes; (2) unexpected DLL loads inside browser processes from non-standard paths, which indicate reflective injection or manual DLL mapping used by web inject malware families such as TrickBot, Dridex, IcedID, and Cobalt Strike. Legitimate browser security tools (MsMpEng.exe, WerFault.exe) and inter-browser IPC are excluded to reduce false positives.

high severity high confidence

Data Sources

Process: Process Access Module: Module Load Microsoft Defender for Endpoint DeviceEvents Microsoft Defender for Endpoint DeviceImageLoadEvents

Required Tables

DeviceEvents DeviceImageLoadEvents

False Positives

  • Screen reader and accessibility software (NVDA, JAWS, ZoomText) that legitimately hook into browser processes to read on-screen content
  • Password manager browser extensions with companion desktop agents (1Password, LastPass desktop app) that access browser process memory for autofill
  • Security products with browser integration features (some DLP agents, Netskope, Zscaler client) that inject helper modules into browsers
  • Crash reporting and debugging tools (Visual Studio debugger, Process Monitor) opening handles to browser processes during development or troubleshooting
  • Endpoint detection products performing memory scanning may trigger OpenProcessApiCall events against browser processes during scheduled scans

Sigma rule & cross-platform mapping

The detection logic for Browser Session Hijacking (T1185) above is provided in a vendor-neutral form so you can deploy it on any SIEM. The same logic is shipped here as native KQL (Microsoft Sentinel / Defender), SPL (Splunk), Elastic (Elastic Security (EQL)), QRadar (IBM QRadar (AQL)), Sumo (Sumo Logic CSE), YARA-L (Google Chronicle / SecOps), LogScale (CrowdStrike LogScale (CQL)) queries. In Sigma terms, this detection targets the following logsource:

logsource:
  category: process_creation
  product: windows

Browse the community-maintained Sigma rules for this technique:


Testing Methodology

Validate this detection against 4 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.

  1. Test 1Browser Process Enumeration and Handle Open (ReadVM Access)

    Expected signal: Sysmon EventCode=10 (ProcessAccess): SourceImage=powershell.exe, TargetImage=<browser>.exe, GrantedAccess=0x10 (PROCESS_VM_READ), CallTrace will show the kernel32.dll and ntdll.dll call stack. MDE DeviceEvents ActionType=OpenProcessApiCall with FileName=<browser>.exe, InitiatingProcessFileName=powershell.exe.

  2. Test 2Chrome Cookie Database Exfiltration via File Copy

    Expected signal: Sysmon EventCode=11 (FileCreate): TargetFilename=%TEMP%\argus_test_cookies_*.db, Image=powershell.exe. Sysmon EventCode=1 (ProcessCreate): powershell.exe with command line referencing LOCALAPPDATA\Google\Chrome\User Data. MDE DeviceFileEvents with ActionType=FileCreated, FileName=argus_test_cookies_*.db, InitiatingProcessFileName=powershell.exe.

  3. Test 3Browser Proxy Configuration via Registry (Browser Pivot Simulation)

    Expected signal: Sysmon EventCode=13 (RegistryValueSet): TargetObject=HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ProxyServer, Details=127.0.0.1:4444, Image=powershell.exe. Second EventCode=13 for ProxyEnable=1. MDE DeviceRegistryEvents with ActionType=RegistryValueSet, RegistryValueName=ProxyServer, RegistryValueData=127.0.0.1:4444.

  4. Test 4CreateRemoteThread Simulation into Browser Process (Benign Payload)

    Expected signal: Sysmon EventCode=8 (CreateRemoteThread): SourceImage=powershell.exe, TargetImage=<browser>.exe, StartAddress=<kernel32!Sleep address>, StartModule=C:\Windows\System32\kernel32.dll, StartFunction=Sleep. MDE DeviceEvents ActionType=CreateRemoteThreadApiCall, FileName=<browser>.exe, InitiatingProcessFileName=powershell.exe. Security Event ID 4688 for the PowerShell process if command line auditing is enabled.


Response Playbook

Triage

  1. Identify the injecting process — capture InitiatingProcessFileName, InitiatingProcessCommandLine, and InitiatingProcessParentFileName. Is this a known legitimate tool (password manager, accessibility software, security agent) or an unexpected process like rundll32.exe, regsvr32.exe, cmd.exe, or an unsigned binary from %TEMP%?
  2. Inspect the target browser process — which browser and which user session? Cross-reference with the user's authentication state: are they actively logged into banking, VPN portals, SaaS applications (O365, Okta, Salesforce) that an adversary would want to hijack?
  3. Check for SeDebugPrivilege usage — query DeviceEvents for PrivilegeUseApiCall or review Security Event ID 4703 for the injecting process. Cobalt Strike browser pivoting explicitly requires SeDebugPrivilege or running as high-integrity/SYSTEM.
  4. Correlate with concurrent network events — query DeviceNetworkEvents for the browser's PID around the injection timestamp. Look for new outbound connections to external IPs that were not present before the injection event, indicating browser pivot C2 traffic riding on the victim's session.
  5. Examine the CallTrace field in Sysmon EventCode=10 — if CallTrace shows a path through an unbacked memory region (e.g., 'UNKNOWN(...)' or an address not corresponding to a loaded module), this is a strong indicator of shellcode-based injection rather than a legitimate tool.
  6. Determine if this is a Cobalt Strike browser pivot — check for a proxy listener pattern: does the attacker's machine appear in network connections, or are there new SOCKS/HTTP proxy configurations added to browser settings (HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings)?

Containment

  1. If active session hijacking is confirmed: immediately isolate the endpoint using EDR network isolation to sever the adversary's browser pivot connection while preserving forensic state for investigation
  2. Revoke all active authenticated sessions for the affected user account across all connected services — invalidate OAuth tokens, Kerberos tickets (klist purge on affected host), and browser session cookies via admin-level session revocation in each SaaS platform
  3. If banking or financial sessions were exposed: notify the affected user and relevant financial institution security teams immediately; time-sensitive credential/session reuse is the primary risk
  4. Reset the user's password and force re-authentication across all SSO/MFA-enrolled services — an adversary with cloned SSL certificates may authenticate without the user's knowledge even after password reset
  5. Block identified C2 infrastructure — extract any new external IPs or domains from browser network connections post-injection and push IOCs to proxy/firewall/DNS blocks; also check for browser proxy settings changes indicating persistent browser pivot configuration
  6. If web inject malware is confirmed (TrickBot/Dridex/IcedID/QakBot pattern): escalate to full incident response — these malware families typically have additional persistence mechanisms (scheduled tasks, service installation, registry run keys) requiring comprehensive remediation

Evidence Collection

  1. Sysmon EventCode=10 logs — full CallTrace showing the injection call stack, GrantedAccess value, SourceImage, and TargetImage for the browser process access event
  2. Sysmon EventCode=8 logs — StartAddress and StartModule fields showing where the remote thread was created; UNKNOWN module indicates shellcode
  3. Sysmon EventCode=3 (Network) for the browser PID — capture all outbound connections made by the browser process before and after the injection timestamp to identify C2 or data exfiltration destinations
  4. Browser process memory dump — use Task Manager or ProcDump (procdump.exe -ma <pid> <output.dmp>) before isolation to capture injected code, hook tables, and in-memory session data for malware analysis
  5. Browser profile directories — copy %LOCALAPPDATA%\Google\Chrome\User Data\Default\Cookies, Login Data, Web Data, and Session Storage to forensic staging; these contain DPAPI-encrypted credentials the adversary may have decrypted in-memory
  6. Windows Registry: HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings — check ProxyEnable, ProxyServer, AutoConfigURL for adversary-set proxy pivot configuration
  7. Memory artifacts of the injecting process — capture full process memory of the injector (not just the browser) for indicators of the loader/packer used by the malware family
  8. Security Event ID 4703 — token privilege adjustment events for SeDebugPrivilege on the injecting process account, confirming elevated access used for injection

Escalation Criteria

  • ! Cobalt Strike or known C2 framework identified — browser process injection combined with outbound connections to C2 infrastructure (Cobalt Strike malleable C2, Metasploit SOCKS proxy) requires immediate incident response escalation
  • ! Financial institution or VPN portal sessions were active in the browser at time of injection — direct risk of fraudulent transactions, unauthorized network access, or data exfiltration via authenticated session pivot
  • ! SYSTEM or domain admin account context — browser hijacking under a privileged account allows lateral movement to any intranet resource accessible to that account, including SharePoint, Exchange, and internal admin portals
  • ! Known banking trojan IOCs matched — process, DLL, or network indicators matching TrickBot, Dridex, IcedID, QakBot, or Ursnif family signatures require immediate IR engagement and potential fraud team notification
  • ! Multiple hosts show similar injection patterns within a short time window — indicates automated propagation or a coordinated campaign requiring enterprise-wide hunting rather than single-host containment
  • ! Browser SSL client certificates were in use — adversary may have cloned certificates from browser session, enabling persistent impersonation even after password reset; notify PKI/certificate authority team

Investigation Guide

Forensic Artifacts

  • > Browser process memory: injected hooks typically manifest as trampolines at the start of WinInet/NSS3 SSL functions (InternetSendRequest, PR_Write) — visible in memory analysis as JMP instructions to shellcode regions
  • > File System: %LOCALAPPDATA%\Google\Chrome\User Data\Default\Cookies — SQLite database containing DPAPI-encrypted session cookies; adversary decrypts using Chrome's DPAPI key extracted from Local State file
  • > File System: %LOCALAPPDATA%\Google\Chrome\User Data\Local State — contains the DPAPI-protected AES key used to encrypt Chrome's cookie database; critical artifact for understanding session theft scope
  • > Registry: HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ProxyServer — adversary-configured proxy indicating browser pivot is active and routing traffic through attacker infrastructure
  • > Registry: HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings\AutoConfigURL — PAC file URL may point to adversary-controlled server delivering malicious proxy configuration
  • > Sysmon EventCode=7 ImageLoad records — check for DLLs loaded into browser processes from %TEMP%, %APPDATA%, or AppData\Roaming directories that are not digitally signed by the browser vendor
  • > Prefetch: C:\Windows\Prefetch\CHROME.EXE-*.pf — tracks DLLs loaded by Chrome across recent executions; compare against baseline to identify anomalous modules loaded post-infection
  • > Network capture: browser pivot traffic appears as browser process (chrome.exe, firefox.exe) making direct TCP connections to internal intranet hosts on ports 80/443/8080 that the user never navigated to, or SOCKS proxy negotiation traffic to external IPs

Tuning Guidance

The primary source of false positives in this detection is legitimate security and productivity software that requires browser process access: password manager desktop agents (1Password, LastPass, Bitwarden with companion apps), accessibility tools (NVDA, JAWS), and enterprise security products with browser DLP or SSO integration (Netskope, Zscaler, Okta Verify). Build an allowlist using the combination of InitiatingProcessFileName + InitiatingProcessFolderPath + digital signature status — legitimate tools are almost always signed by known vendors and installed to Program Files, not %TEMP% or %APPDATA%. For Sysmon EventCode=10 GrantedAccess filtering, focus on high-privilege access masks (0x1F0FFF full access, 0x1FFFFF all access, combined VM_READ + VM_WRITE + VM_OPERATION patterns) rather than low-privilege read-only handles. The CallTrace field is the most discriminating signal: legitimate injectors have fully-backed call stacks through known DLL paths, while shellcode-based injectors show UNKNOWN or raw memory address entries in CallTrace. Consider enriching detections with binary signature checks — unsigned or self-signed binaries accessing browser processes should carry higher confidence than signed vendor software. If your environment deploys Cobalt Strike or other commercial offensive tools for red team exercises, coordinate with the red team to establish scheduled maintenance windows and suppression rules tied to specific operator machine hostnames.


Hunting Queries

Hunt for browser processes establishing outbound connections on non-standard ports shortly after a process injection event targeting them. Cobalt Strike browser pivot and banking trojans establish proxy/C2 channels through the hijacked browser process that appear as the browser process making unusual TCP connections. Connections on non-standard ports from browser processes are rare in legitimate use.

Hunting — KQL
kql
// Hunt: Browser processes making unusual outbound network connections post-process-access event
let BrowserProcesses = dynamic(["chrome.exe", "msedge.exe", "firefox.exe", "iexplore.exe", "brave.exe"]);
let InjectionWindow = DeviceEvents
| where Timestamp > ago(7d)
| where ActionType in ("CreateRemoteThreadApiCall", "WriteProcessMemoryApiCall", "OpenProcessApiCall")
| where FileName in~ (BrowserProcesses)
| where InitiatingProcessFileName !in~ (BrowserProcesses)
| where InitiatingProcessFileName !in~ ("MsMpEng.exe", "WerFault.exe", "csrss.exe")
| project DeviceName, InjectionTime=Timestamp, BrowserProcess=FileName;
DeviceNetworkEvents
| where Timestamp > ago(7d)
| where InitiatingProcessFileName in~ (BrowserProcesses)
| where RemoteIPType == "Public"
| where RemotePort !in (80, 443, 8080, 8443)
| join kind=inner InjectionWindow on DeviceName
| where Timestamp between (InjectionTime .. (InjectionTime + 1h))
| project Timestamp, DeviceName, InitiatingProcessFileName, RemoteIP, RemotePort, RemoteUrl, InjectionTime
| sort by Timestamp desc
Hunting — SPL
spl
index=wineventlog sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=3
(Image="*\\chrome.exe" OR Image="*\\msedge.exe" OR Image="*\\firefox.exe" OR Image="*\\iexplore.exe")
NOT (DestinationPort=80 OR DestinationPort=443 OR DestinationPort=8080 OR DestinationPort=8443)
NOT (DestinationIp="10.*" OR DestinationIp="172.16.*" OR DestinationIp="192.168.*" OR DestinationIp="127.*")
| stats count as Connections, values(DestinationIp) as DestIPs, values(DestinationPort) as DestPorts by host, User, Image, _time span=1h
| where Connections > 3
| sort - Connections

Hunt for the SeDebugPrivilege acquisition followed by browser process access — the two-step pattern required for Cobalt Strike browser pivoting. Legitimate software rarely needs SeDebugPrivilege combined with browser process access rights. This sequence is a strong indicator of intentional session hijacking rather than benign tooling.

Hunting — KQL
kql
// Hunt: Processes acquiring SeDebugPrivilege then accessing browser processes
let DebugPrivEvents = DeviceEvents
| where Timestamp > ago(7d)
| where ActionType == "PrivilegeUseApiCall"
| where AdditionalFields has "SeDebugPrivilege"
| project DeviceName, AccountName, DebugPrivTime=Timestamp, PrivProcess=InitiatingProcessFileName, PrivProcessId=InitiatingProcessId;
DeviceEvents
| where Timestamp > ago(7d)
| where ActionType in ("OpenProcessApiCall", "CreateRemoteThreadApiCall", "WriteProcessMemoryApiCall")
| where FileName in~ (dynamic(["chrome.exe", "msedge.exe", "firefox.exe", "iexplore.exe", "brave.exe"]))
| join kind=inner DebugPrivEvents on DeviceName, AccountName
| where Timestamp between (DebugPrivTime .. (DebugPrivTime + 300s))
| project Timestamp, DeviceName, AccountName, ActionType, TargetBrowser=FileName, PrivProcess, DebugPrivTime
| sort by Timestamp desc
Hunting — SPL
spl
index=wineventlog sourcetype="WinEventLog:Security" EventCode=4703
"SeDebugPrivilege"
| eval PrivTime=_time
| join host, SubjectUserName [
    search index=wineventlog sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=10
    (TargetImage="*\\chrome.exe" OR TargetImage="*\\msedge.exe" OR TargetImage="*\\firefox.exe" OR TargetImage="*\\iexplore.exe")
    NOT (SourceImage="*\\MsMpEng.exe" OR SourceImage="*\\WerFault.exe")
    | rename ComputerName as host
]
| where _time > PrivTime AND _time < PrivTime + 300
| table _time, host, SubjectUserName, TargetImage, SourceImage, GrantedAccess, PrivTime
| sort - _time

Hunt for browser proxy settings being modified by non-browser processes to point at external or unexpected addresses. Browser pivot attacks using proxy injection often persist configuration changes to WinInet proxy settings in the registry, enabling continued session access even after the injecting process exits. Modifications from non-browser initiating processes pointing to external IPs are highly suspicious.

Hunting — KQL
kql
// Hunt: Browser proxy registry modifications indicating browser pivot configuration
DeviceRegistryEvents
| where Timestamp > ago(7d)
| where RegistryKey has_any (
    "Internet Settings",
    "ProxyServer",
    "AutoConfigURL",
    "ProxyEnable"
)
| where RegistryValueName in~ ("ProxyServer", "AutoConfigURL", "ProxyEnable")
| where InitiatingProcessFileName !in~ ("chrome.exe", "msedge.exe", "iexplore.exe", "firefox.exe", "brave.exe", "SettingSyncHost.exe", "svchost.exe")
| where not(RegistryValueData has_any ("proxy.internal", "proxy.corp", "wpad.", "10.", "172.16.", "192.168."))
| project Timestamp, DeviceName, AccountName, RegistryKey, RegistryValueName, RegistryValueData,
         InitiatingProcessFileName, InitiatingProcessCommandLine
| sort by Timestamp desc
Hunting — SPL
spl
index=wineventlog sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=13
(TargetObject="*\\Internet Settings\\ProxyServer" OR
 TargetObject="*\\Internet Settings\\AutoConfigURL" OR
 TargetObject="*\\Internet Settings\\ProxyEnable")
NOT (Image="*\\chrome.exe" OR Image="*\\msedge.exe" OR Image="*\\iexplore.exe" OR Image="*\\SettingSyncHost.exe")
| eval IsExternalProxy=if(NOT match(Details, "10\\.|172\.1[6-9]\\.|192\.168\\.|proxy\.internal|corp\.proxy|wpad\\."), 1, 0)
| table _time, host, User, Image, TargetObject, Details, IsExternalProxy
| sort - IsExternalProxy, - _time

Atomic Red Team Tests

Test 1 Browser Process Enumeration and Handle Open (ReadVM Access)
windows

Enumerates running browser processes and opens a limited read-only handle using PROCESS_VM_READ (0x0010) access rights — the minimum access required for session token theft from browser memory. This simulates the initial process access step of browser session hijacking tools and triggers Sysmon EventCode=10 (ProcessAccess). No memory is read; only the handle open call is made.

Command

powershell
Add-Type -TypeDefinition @"
using System;
using System.Runtime.InteropServices;
public class BrowserAccess {
    [DllImport("kernel32.dll")]
    public static extern IntPtr OpenProcess(uint access, bool inherit, int pid);
    [DllImport("kernel32.dll")]
    public static extern bool CloseHandle(IntPtr h);
    public const uint PROCESS_VM_READ = 0x0010;
}
"@
$target = Get-Process -Name 'chrome','msedge','firefox' -ErrorAction SilentlyContinue | Select-Object -First 1
if ($target) {
    $h = [BrowserAccess]::OpenProcess([BrowserAccess]::PROCESS_VM_READ, $false, $target.Id)
    Write-Output "Opened handle 0x$($h.ToString('X')) to $($target.Name) PID $($target.Id)"
    [BrowserAccess]::CloseHandle($h) | Out-Null
} else {
    Write-Output 'No target browser process found. Launch chrome/edge/firefox first.'
}

Expected Telemetry

Sysmon EventCode=10 (ProcessAccess): SourceImage=powershell.exe, TargetImage=<browser>.exe, GrantedAccess=0x10 (PROCESS_VM_READ), CallTrace will show the kernel32.dll and ntdll.dll call stack. MDE DeviceEvents ActionType=OpenProcessApiCall with FileName=<browser>.exe, InitiatingProcessFileName=powershell.exe.

Expected Detection

SPL query fires: EventCode=10 with TargetImage matching browser process, SourceImage=powershell.exe not in exclusion list. InjectionType='ProcessAccess to browser'. KQL fires: ActionType='OpenProcessApiCall', FileName matches BrowserProcesses, InitiatingProcessFileName=powershell.exe not in KnownGoodInjectors.

Test 2 Chrome Cookie Database Exfiltration via File Copy
windows

Copies Chrome's SQLite cookie database to TEMP directory — demonstrating file-based session token theft used by malware families like Vidar, RedLine, and browser info-stealer components of banking trojans. When Chrome is running, the Cookies file is locked; this test copies the Cookies file from the Default profile. The copied database contains DPAPI-encrypted session cookies. This technique does not require process injection and is complementary to in-memory session hijacking.

Command

powershell
$chromeCookies = "$env:LOCALAPPDATA\Google\Chrome\User Data\Default\Cookies"
$edgeCookies = "$env:LOCALAPPDATA\Microsoft\Edge\User Data\Default\Cookies"
$dest = "$env:TEMP\argus_test_cookies_$((Get-Date -Format 'yyyyMMddHHmmss')).db"
if (Test-Path $chromeCookies) {
    Copy-Item -Path $chromeCookies -Destination $dest -Force
    Write-Output "Chrome Cookies copied to $dest ($($(Get-Item $dest).Length) bytes)"
} elseif (Test-Path $edgeCookies) {
    Copy-Item -Path $edgeCookies -Destination $dest -Force
    Write-Output "Edge Cookies copied to $dest"
} else {
    Write-Output 'No Chrome or Edge cookie database found. Ensure browser has been launched.'
}

Cleanup

powershell
Remove-Item "$env:TEMP\argus_test_cookies_*.db" -ErrorAction SilentlyContinue

Expected Telemetry

Sysmon EventCode=11 (FileCreate): TargetFilename=%TEMP%\argus_test_cookies_*.db, Image=powershell.exe. Sysmon EventCode=1 (ProcessCreate): powershell.exe with command line referencing LOCALAPPDATA\Google\Chrome\User Data. MDE DeviceFileEvents with ActionType=FileCreated, FileName=argus_test_cookies_*.db, InitiatingProcessFileName=powershell.exe.

Expected Detection

MDE query: DeviceFileEvents where InitiatingProcessFileName !in~ browsers AND FileName has 'Cookies' AND FolderPath has 'Chrome\User Data'. This pattern is caught by data source 'File: File Access' detections for browser credential theft. SOC should correlate with hunting query #3 (proxy registry changes) for full attack chain.

Test 3 Browser Proxy Configuration via Registry (Browser Pivot Simulation)
windows

Modifies WinInet proxy settings in the registry to redirect browser HTTP traffic through a loopback proxy address — simulating the proxy injection phase of Cobalt Strike browser pivoting. The Cobalt Strike browser pivot sets up a local SOCKS proxy and configures the victim's browser to route all traffic through it, inheriting the user's authenticated sessions. This test sets and then removes a benign loopback proxy entry, triggering both registry modification and proxy change detection.

Command

powershell
# Set proxy to loopback (simulates browser pivot proxy configuration)
$regPath = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings'
$originalProxy = (Get-ItemProperty -Path $regPath -Name ProxyServer -ErrorAction SilentlyContinue).ProxyServer
$originalEnabled = (Get-ItemProperty -Path $regPath -Name ProxyEnable -ErrorAction SilentlyContinue).ProxyEnable
Set-ItemProperty -Path $regPath -Name ProxyServer -Value '127.0.0.1:4444'
Set-ItemProperty -Path $regPath -Name ProxyEnable -Value 1
Write-Output "Browser proxy set to 127.0.0.1:4444 (Cobalt Strike browser pivot simulation)"
Write-Output "Original ProxyServer: $originalProxy, ProxyEnable: $originalEnabled"
Start-Sleep -Seconds 3
# Cleanup immediately
if ($originalProxy) {
    Set-ItemProperty -Path $regPath -Name ProxyServer -Value $originalProxy
} else {
    Remove-ItemProperty -Path $regPath -Name ProxyServer -ErrorAction SilentlyContinue
}
if ($null -ne $originalEnabled) {
    Set-ItemProperty -Path $regPath -Name ProxyEnable -Value $originalEnabled
} else {
    Remove-ItemProperty -Path $regPath -Name ProxyEnable -ErrorAction SilentlyContinue
}
Write-Output 'Proxy settings restored to original values'

Expected Telemetry

Sysmon EventCode=13 (RegistryValueSet): TargetObject=HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ProxyServer, Details=127.0.0.1:4444, Image=powershell.exe. Second EventCode=13 for ProxyEnable=1. MDE DeviceRegistryEvents with ActionType=RegistryValueSet, RegistryValueName=ProxyServer, RegistryValueData=127.0.0.1:4444.

Expected Detection

KQL hunting query #3 fires: RegistryValueName='ProxyServer', InitiatingProcessFileName=powershell.exe (not in browser exclusion list), RegistryValueData does not match corporate proxy patterns. SPL hunting query #3 fires: EventCode=13 for ProxyServer key, Image=powershell.exe, IsExternalProxy=1 (127.0.0.1 doesn't match corporate exclusions in this context).

Test 4 CreateRemoteThread Simulation into Browser Process (Benign Payload)
windows

Demonstrates the CreateRemoteThread injection technique targeting a browser process using a benign thread that immediately returns — simulating the initial stage of web inject loaders used by TrickBot and Dridex. The thread executes Sleep(0) via a pointer to a known safe API. Requires the browser to be running and administrator rights. This is the exact technique Cobalt Strike's browser pivot uses to inject its proxy agent into a browser tab process.

Command

powershell
Add-Type -TypeDefinition @"
using System;
using System.Runtime.InteropServices;
public class RemoteThread {
    [DllImport("kernel32.dll")]
    public static extern IntPtr OpenProcess(uint access, bool inherit, int pid);
    [DllImport("kernel32.dll")]
    public static extern IntPtr GetProcAddress(IntPtr hMod, string proc);
    [DllImport("kernel32.dll")]
    public static extern IntPtr GetModuleHandle(string name);
    [DllImport("kernel32.dll")]
    public static extern IntPtr CreateRemoteThread(IntPtr hProc, IntPtr lpAttr, uint stackSize,
        IntPtr startAddr, IntPtr param, uint flags, out uint threadId);
    [DllImport("kernel32.dll")]
    public static extern bool CloseHandle(IntPtr h);
    public const uint PROCESS_ALL_ACCESS = 0x1F0FFF;
}
"@
$target = Get-Process -Name 'chrome','msedge','firefox' -ErrorAction SilentlyContinue | Select-Object -First 1
if (-not $target) { Write-Output 'No browser found. Launch Chrome/Edge/Firefox first.'; exit }
$hProc = [RemoteThread]::OpenProcess([RemoteThread]::PROCESS_ALL_ACCESS, $false, $target.Id)
$sleepAddr = [RemoteThread]::GetProcAddress([RemoteThread]::GetModuleHandle('kernel32.dll'), 'Sleep')
$tid = 0
$hThread = [RemoteThread]::CreateRemoteThread($hProc, [IntPtr]::Zero, 0, $sleepAddr, [IntPtr]::Zero, 0, [ref]$tid)
Write-Output "CreateRemoteThread into $($target.Name) PID $($target.Id): hThread=0x$($hThread.ToString('X')), TID=$tid"
[RemoteThread]::CloseHandle($hThread) | Out-Null
[RemoteThread]::CloseHandle($hProc) | Out-Null

Expected Telemetry

Sysmon EventCode=8 (CreateRemoteThread): SourceImage=powershell.exe, TargetImage=<browser>.exe, StartAddress=<kernel32!Sleep address>, StartModule=C:\Windows\System32\kernel32.dll, StartFunction=Sleep. MDE DeviceEvents ActionType=CreateRemoteThreadApiCall, FileName=<browser>.exe, InitiatingProcessFileName=powershell.exe. Security Event ID 4688 for the PowerShell process if command line auditing is enabled.

Expected Detection

SPL query fires at highest priority (IsHighRisk=1): EventCode=8, SourceImage=powershell.exe, TargetImage=<browser>.exe, InjectionType='CreateRemoteThread in browser'. KQL fires: ActionType='CreateRemoteThreadApiCall', FileName in BrowserProcesses, InitiatingProcessFileName=powershell.exe, InjectionMethod='Remote thread injection'.

Related Detections

Tactic Hub