PureLogs Delivered Through PawsRunner Steganography
Detection stack
- AIDR
- Alert
- ETL
- Query
Summary
The campaign relies on a phishing email carrying a TXZ archive that delivers a JavaScript loader, which sets environment variables and launches conhost.exe in headless mode. The loader then decrypts a .NET assembly known as PawsRunner, which retrieves PNG images containing hidden encrypted content through steganographic techniques. From those images, the malware extracts the final payload: the PureLogs .NET infostealer. Once active, PureLogs connects to a remote command-and-control server over HTTPS and exfiltrates browser credentials along with system information.
Investigation
Analysis showed that the JavaScript loader pulls commands from process environment variables, launches PowerShell with a hidden window flag, and decrypts an AES-encrypted payload that is executed through .NET reflection. PawsRunner rotates between three network APIs and three different user-agent strings while fetching PNG files, then parses iTXt and IEND chunks to locate the concealed data and decrypts the next stage with RC4. PureLogs in turn uses TripleDES and Gzip to load a downloader DLL, makes TLS-protected HTTP requests to specific endpoints, and collects a broad set of browser-related data from the victim system.
Mitigation
Organizations should block TXZ attachments at the email gateway, monitor for conhost.exe instances running without a visible window, and detect PowerShell launched with the -w hidden flag. Security teams should also deploy signatures for both PawsRunner and PureLogs, restrict outbound traffic to the identified command-and-control domain and IP address, and limit execution of unsigned .NET assemblies. Where possible, steganography detection should be applied to suspicious inbound image files.
Response
If this activity is detected, isolate the affected endpoint, terminate suspicious conhost.exe and PowerShell processes, and remove any dropped .NET binaries from the system. Compromised credentials should be revoked, multi-factor authentication enforced, and stored browser passwords reset. Investigators should also perform network forensics to confirm that no additional command-and-control communication occurred and apply remediation steps to prevent reinfection.
"graph TB %% Class Definitions classDef action fill:#99ccff classDef tool fill:#cccccc classDef process fill:#ffdd99 classDef malware fill:#ff9999 %% Nodes initial_phishing["<b>Action</b> – <b>T1566.001 Spearphishing Attachment</b><br/>Attacker sends a phishing email with a TXZ archive attachment that contains the malicious payload."] class initial_phishing action malicious_archive["<b>Malware</b> – <b>Name</b>: Malicious TXZ Archive<br/><b>Description</b>: Archive used to deliver the initial JavaScript payload."] class malicious_archive malware user_execution["<b>Action</b> – <b>T1204.004 User Execution</b><br/>Victim extracts the archive, the JavaScript runs PowerShell in hidden mode and reads commands from environment variables."] class user_execution action powershell_loader["<b>Process</b> – <b>Name</b>: PowerShell Loader<br/><b>Description</b>: Executes decrypted .NET assembly via reflection without writing to disk."] class powershell_loader process defense_compile["<b>Action</b> – <b>T1027.004 Compile After Delivery</b><br/>Decrypted .NET assembly is loaded in memory via reflection."] class defense_compile action defense_compress["<b>Action</b> – <b>T1027.015 Compression</b><br/>Payload is AESu2011decrypted then decompressed using Gzip."] class defense_compress action defense_stego["<b>Action</b> – <b>T1027.003 Steganography</b><br/>Loader downloads PNG images and extracts hidden encrypted data from iTXt/IEND chunks."] class defense_stego action masquerade_icon["<b>Action</b> – <b>T1036.008 Masquerading</b><br/>Binary uses cat pictures as its application icon to appear benign."] class masquerade_icon action c2_encrypted["<b>Action</b> – <b>T1573 Encrypted Channel</b><br/>Further C2 communication occurs over HTTPS with AESu2011256 encrypted payloads."] class c2_encrypted action credential_access["<b>Action</b> – <b>T1555.003 Credentials from Web Browsers</b><br/>PureLogs enumerates browsers and extracts saved passwords, cookies, and cryptou2011wallet files."] class credential_access action purelogs_tool["<b>Tool</b> – <b>Name</b>: PureLogs<br/><b>Description</b>: Credentialu2011dumping utility that harvests browser data."] class purelogs_tool tool collection_archive["<b>Action</b> – <b>T1560.003 Archive Collected Data</b><br/>Harvested data is compressed with Gzip and encrypted with AES before exfiltration."] class collection_archive action exfiltration_http["<b>Action</b> – <b>T1048.003 Exfiltration Over Unencrypted Nonu2011C2 Protocol</b><br/>Data is sent via HTTP POST requests to multiple external endpoints."] class exfiltration_http action %% Connections initial_phishing –>|delivers| malicious_archive malicious_archive –>|triggers| user_execution user_execution –>|executes| powershell_loader powershell_loader –>|performs| defense_compile defense_compile –>|uses| defense_compress defense_compress –>|uses| defense_stego defense_stego –>|enables| masquerade_icon masquerade_icon –>|establishes| c2_encrypted c2_encrypted –>|enables| credential_access credential_access –>|uses| purelogs_tool credential_access –>|collects| collection_archive collection_archive –>|exfiltrates via| exfiltration_http %% Class Assignments class initial_phishing action class malicious_archive malware class user_execution action class powershell_loader process class defense_compile action class defense_compress action class defense_stego action class masquerade_icon action class c2_encrypted action class credential_access action class purelogs_tool tool class collection_archive action class exfiltration_http action "
Attack Flow
Detections
The Possibility of Execution Through Hidden PowerShell Command Lines (via cmdline)
View
LOLBAS WScript / CScript (via process_creation)
View
Call Suspicious .NET Methods from Powershell (via powershell)
View
Possible Powershell Obfuscation Indicators (via powershell)
View
LOLBAS Conhost (via cmdline)
View
IOCs (HashSha256) to detect: PureLogs: Delivery via PawsRunner Steganography
View
IOCs (SourceIP) to detect: PureLogs: Delivery via PawsRunner Steganography
View
IOCs (DestinationIP) to detect: PureLogs: Delivery via PawsRunner Steganography
View
PowerShell AES Decryption from Environment Variables [Windows Powershell]
View
Detection of Malicious Process Execution via Hidden Conhost and PowerShell [Windows Process Creation]
View
Simulation Execution
Prerequisite: The Telemetry & Baseline Pre‑flight Check must have passed.
-
Attack Narrative & Commands
- Stage 1 – Prepare the encrypted payload
- The attacker creates a small dummy payload (
"secret"), encrypts it with AES‑256 using a known key, Base64‑encodes the ciphertext, and stores it in an environment variableENC_PAYLOAD.
- The attacker creates a small dummy payload (
- Stage 2 – Execute the PowerShell decryption loader
- A one‑liner reads
ENC_PAYLOAD, decodes the Base64 string, constructs a .NETAesCryptoServiceProvider, derives the key/IV, decrypts the data, and optionally executes the plaintext.
- A one‑liner reads
- Stage 3 – Generate detection telemetry
- The PowerShell command includes the literal word “AES” (e.g.,
New-Object System.Security.Cryptography.AesCryptoServiceProvider) and is logged as EventID 4104, satisfying the detection rule.
- The PowerShell command includes the literal word “AES” (e.g.,
- Stage 1 – Prepare the encrypted payload
-
Regression Test Script
# ------------------------------------------------- # PowerShell AES Decryption Simulation (Triggers detection) # ------------------------------------------------- # 1. Define a static 256‑bit key and IV (for demo purposes) $key = [byte[]](0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10, 0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20) $iv = [byte[]](0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf,0xb0) # 2. Plaintext payload (example) $plain = [System.Text.Encoding]::UTF8.GetBytes("secret data") # 3. Encrypt the payload using AES (CBC, PKCS7) $aes = [System.Security.Cryptography.AesCryptoServiceProvider]::new() $aes.Key = $key $aes.IV = $iv $aes.Mode = [System.Security.Cryptography.CipherMode]::CBC $aes.Padding = [System.Security.Cryptography.PaddingMode]::PKCS7 $encryptor = $aes.CreateEncryptor() $cipherBytes = $encryptor.TransformFinalBlock($plain,0,$plain.Length) $cipherB64 = [Convert]::ToBase64String($cipherBytes) # 4. Store ciphertext in an environment variable # 5. Decryption loader – the exact line that will be logged (contains "AES") $loader = @" `$enc = [System.Environment]::GetEnvironmentVariable('ENC_PAYLOAD') `$bytes = [Convert]::FromBase64String(`$enc) `$aes = New-Object System.Security.Cryptography.AesCryptoServiceProvider `$aes.Key = $($key -join ',') `$aes.IV = $($iv -join ',') `$decryptor = `$aes.CreateDecryptor() `$plain = `$decryptor.TransformFinalBlock(`$bytes,0,`$bytes.Length) `$result = [System.Text.Encoding]::UTF8.GetString(`$plain) Write-Output `"Decrypted: `$result`" "@ # Execute the loader (will be captured as EventID 4104) Invoke-Expression $loader -
Cleanup Commands
# Remove the environment variable # Clear any temporary variables from the session Remove-Variable -Name key,iv,plain,cipherBytes,cipherB64,loader -ErrorAction SilentlyContinue
Post‑Simulation Validation
- Run the validation query (KQL example above) but filter for
ScriptBlockText contains "AES"to confirm the detection fired. - Review the alert details in the SIEM; verify that the alert name matches the rule (if defined) and that severity is reported as High.
Closing Remarks
- The rule successfully detects the straightforward “AES” usage scenario.
- Adversaries can evade by splitting the word (e.g.,
"AE"+"S"), loading the .NET class via reflection, or performing decryption within compiled binaries. - Enhancing the rule with behavioral indicators (use of environment variables for ciphertext, high‑entropy strings, creation of
AesCryptoServiceProviderobjects, and subsequentTransformFinalBlockcalls) will improve resilience to simple obfuscation.