Phantom in the vault: Obsidian abused to deliver PhantomPulse RAT
Detection stack
- AIDR
- Alert
- ETL
- Query
Summary
Elastic Security Labs uncovered a new social engineering campaign that abuses the Obsidian note-taking platform and its community plugin ecosystem to deliver PhantomPulse, a previously undocumented RAT targeting both Windows and macOS systems. The operation appears aimed at individuals in the financial and cryptocurrency space, with attackers using LinkedIn and Telegram to distribute a compromised Obsidian vault as the initial lure. On Windows, the infection chain relies on PowerShell, a custom in-memory loader known as PhantomPull, and reflective loading techniques. On macOS, the attackers use AppleScript along with a Telegram-based dead-drop command-and-control mechanism. The campaign also incorporates blockchain-based C2 discovery through Ethereum transaction data.
Investigation
Researchers reproduced the attack by building a weaponized Obsidian vault that used the Shell Commands and Hider plugins to trigger malicious execution. During analysis, they observed PowerShell scripts downloading a loader named syncobs.exe from 195.3.222.251, which then retrieved an encrypted payload and loaded it reflectively in memory. The loader created a mutex, communicated with a control panel hosted at panel.fefea22134.net, and supported fallback infrastructure derived from blockchain data. On macOS, the malware established persistence through a LaunchAgent plist and downloaded a secondary AppleScript payload from a hard-coded domain and a Telegram channel. Investigators recovered key artifacts from JSON configuration files and in-memory resources tied to both infection paths.
Mitigation
Organizations should prevent Obsidian from spawning unauthorized child processes, apply strict controls over community plugin usage, and monitor for PowerShell activity where Obsidian appears as the parent process. Network defenses should block outbound traffic to 195.3.222.251 and the domains panel.fefea22134.net, 0x666.info, and known Telegram dead-drop locations associated with the campaign. Security teams should also look for signs of reflective loading, timer-queue callback abuse, and the specific mutex value used by the malware loader.
Response
If suspicious child processes are detected from Obsidian, isolate the affected host immediately and collect the .obsidian directory for forensic review of malicious plugin files and vault content. Hunt for the mutex hVNBUORXNiFLhYYh, then scan endpoints for traces of the PHANTOMPULL loader and PHANTOMPULSE RAT binaries. Block the identified command-and-control infrastructure, revoke any compromised Obsidian-related credentials, and perform a broader review for credential theft exposure involving financial and cryptocurrency accounts.
"graph TB %% Class definitions classDef technique fill:#99ccff classDef tool fill:#ffcc99 classDef malware fill:#ff9999 classDef process fill:#ccffcc %% Technique nodes tech_valid_accounts["<b>Technique</b> – <b>T1078 Valid Accounts</b><br/><b>Description</b>: Adversaries use compromised credentials to gain access to victim accounts.<br/><b>Details</b>: Obsidian credentials provided to victim"] class tech_valid_accounts technique tech_user_execution["<b>Technique</b> – <b>T1204 User Execution</b><br/><b>Description</b>: Users are tricked into executing malicious code.<br/><b>Details</b>: Victim opens shared vault and enables community plugin sync"] class tech_user_execution technique tech_powershell_initial["<b>Technique</b> – <b>T1059.001 PowerShell</b><br/><b>Description</b>: PowerShell is used to execute commands and scripts.<br/><b>Details</b>: Base64u2011encoded PowerShell command downloads script1.ps1"] class tech_powershell_initial technique tech_bits_transfer["<b>Technique</b> – <b>T1105 Ingress Tool Transfer</b><br/><b>Description</b>: Transfer of tools or payloads to a compromised host.<br/><b>Details</b>: BitsTransfer downloads syncobs.exe (secondu2011stage binary)"] class tech_bits_transfer technique tech_reflective_loading["<b>Technique</b> – <b>T1620 Reflective Code Loading</b><br/><b>Description</b>: Load executable code directly into memory without touching disk.<br/><b>Details</b>: PHANTOMPULL extracts AESu2011256u2011CBC encrypted payload and loads it in memory"] class tech_reflective_loading technique tech_process_injection["<b>Technique</b> – <b>T1055.002 Portable Executable Injection</b><br/><b>Description</b>: Inject malicious code into a running process via PE injection.<br/><b>Details</b>: Moduleu2011stomping reflective PE injection"] class tech_process_injection technique tech_dynamic_resolution["<b>Technique</b> – <b>T1568 Dynamic Resolution</b><br/><b>Description</b>: Resolve commandu2011andu2011control locations at runtime, e.g., via blockchain transactions.<br/><b>Details</b>: Blockchain transaction resolves C2 URL"] class tech_dynamic_resolution technique tech_powershell_c2["<b>Technique</b> – <b>T1059.001 PowerShell</b><br/><b>Description</b>: PowerShell used for beaconing and command execution with the C2 server"] class tech_powershell_c2 technique tech_applescript["<b>Technique</b> – <b>T1059.007 AppleScript</b><br/><b>Description</b>: AppleScript employed to run malicious code on macOS.<br/><b>Details</b>: macOS dropper executed via osascript"] class tech_applescript technique tech_launch_agent["<b>Technique</b> – <b>T1543.001 Launch Agent</b><br/><b>Description</b>: Create or modify a LaunchAgent for persistence.<br/><b>Details</b>: Persistent LaunchAgent plist installed"] class tech_launch_agent technique tech_dead_drop_resolver["<b>Technique</b> – <b>T1102.001 Dead Drop Resolver</b><br/><b>Description</b>: Use a web service as a deadu2011drop resolver for C2.<br/><b>Details</b>: Telegram channel used as fallback C2"] class tech_dead_drop_resolver technique %% Tool / Malware nodes tool_syncobs_exe["<b>Tool</b> – <b>Name</b>: syncobs.exe<br/><b>Description</b>: Secondu2011stage binary delivered via BitsTransfer"] class tool_syncobs_exe tool malware_phantompull["<b>Malware</b> – <b>Name</b>: PHANTOMPULL<br/><b>Description</b>: Reflective loader that decrypts and executes an AESu2011256u2011CBC payload"] class malware_phantompull malware %% Flow connections tech_valid_accounts –>|leads_to| tech_user_execution tech_user_execution –>|leads_to| tech_powershell_initial tech_powershell_initial –>|executes| tech_bits_transfer tech_bits_transfer –>|downloads| tool_syncobs_exe tool_syncobs_exe –>|enables| tech_reflective_loading tech_reflective_loading –>|loads| malware_phantompull malware_phantompull –>|facilitates| tech_process_injection tech_process_injection –>|injects| tool_syncobs_exe tech_process_injection –>|enables| tech_dynamic_resolution tech_dynamic_resolution –>|resolves| tech_powershell_c2 tech_dynamic_resolution –>|resolves| tech_applescript tech_powershell_c2 –>|beacons| tech_dead_drop_resolver tech_applescript –>|creates| tech_launch_agent tech_launch_agent –>|persists| tech_dead_drop_resolver "
Attack Flow
Detections
Download or Upload via Powershell (via cmdline)
View
Suspicious Powershell Strings (via cmdline)
View
Suspicious Usage of Invoke-RestMethod (via powershell)
View
Suspicious Powershell Strings (via powershell)
View
Possible Bits Transfer Activity (via powershell)
View
Suspicious Trycloudflare Domain Communication (via proxy)
View
Suspicious File Download Direct IP (via proxy)
View
Suspicious Trycloudflare Domain Communication (via dns)
View
Obsidian Abused for Code Execution and Persistence [Windows Process Creation]
View
Suspicious PowerShell Execution with Obsidian as Parent Process [Windows Powershell]
View
Simulation Execution
Prerequisite: The Telemetry & Baseline Pre‑flight Check must have passed.
Rationale: This section details the precise execution of the adversary technique (TTP) designed to trigger the detection rule. The commands and narrative MUST directly reflect the TTPs identified and aim to generate the exact telemetry expected by the detection logic. Abstract or unrelated examples will lead to misdiagnosis.
-
Attack Narrative & Commands:
- Initial Compromise: The attacker drops a malicious Obsidian plugin (
evil-plugin.js) into the user’s Obsidian plugin directory. - Execution Trigger: When Obsidian starts, the plugin runs a PowerShell one‑liner that launches
notepad.exeviaStart-Process. This creates the exactObsidian.exe → notepad.exeprocess chain the rule watches. - Persistence: The plugin is set to autoload on every Obsidian launch, ensuring the malicious child process recurs.
- Evasion: The plugin also briefly invokes
rundll32.exe(T1216.002) to load a benign DLL, masking the true intent while keeping the detection‑triggering chain intact.
- Initial Compromise: The attacker drops a malicious Obsidian plugin (
-
Regression Test Script:
# ------------------------------------------------- # Malicious Obsidian plugin simulation (PowerShell) # ------------------------------------------------- # 1. Ensure Obsidian is installed at the expected path $obsidianPath = "C:Program FilesObsidianObsidian.exe" if (-Not (Test-Path $obsidianPath)) { Write-Error "Obsidian not found at $obsidianPath" exit 1 } # 2. Launch Obsidian *as the parent* and immediately spawn Notepad $startInfo = New-Object System.Diagnostics.ProcessStartInfo $startInfo.FileName = $obsidianPath $startInfo.Arguments = "-c `"Start-Process notepad.exe`"" $startInfo.UseShellExecute = $false $startInfo.CreateNoWindow = $true $proc = [System.Diagnostics.Process]::Start($startInfo) # 3. Optional: invoke a signed binary (rundll32) to simulate T1216.002 Start-Process -FilePath "C:WindowsSystem32rundll32.exe" -ArgumentList "shell32.dll,Control_RunDLL" -WindowStyle Hidden # 4. Keep the script alive briefly to allow logs to be emitted Start-Sleep -Seconds 5 # ------------------------------------------------- -
Cleanup Commands:
# Terminate any stray Obsidian or Notepad instances created by the test Get-Process -Name "Obsidian","notepad","rundll32" -ErrorAction SilentlyContinue | Stop-Process -Force # Remove the simulated malicious plugin file (if it existed) $pluginPath = "$env:APPDATAObsidianpluginsevil-plugin.js" if (Test-Path $pluginPath) { Remove-Item $pluginPath -Force } Write-Host "Cleanup complete."