Skip to main content
Emerging ThreatsMalware & Ransomware

PamStealer Malware Evolves with Live C2 Decryption and Enhanced Persistence

Laptop screen displays fake website with cryptocurrency wallet download button in dimly lit background.

"Without the server's cooperation, the payload cannot be recovered statically," security researcher Thijs Xhaflaire warned in Jamf Threat Labs' analysis of a new PamStealer variant that ties payload recovery to a live command‑and‑control (C2) session.

How the Wavel lure and initial drop differ from prior PamStealer variants

Earlier PamStealer samples observed in July and August 2026 used fake sites impersonating utilities such as Maccy, Scoppr and Nancy Clipboard. The newest campaign instead uses a bogus site, "wavel[.]app," advertising a non-existent cryptocurrency wallet service named Wavel. Clicking "Download for macOS" on that site fetches a disk image file named "Wavel.dmg" containing a compiled AppleScript file. Opening that file launches Apple's Script Editor with instructions that trigger execution of a JavaScript for Automation (JXA) dropper.

JXA becomes a carrier; zsh runs the live decryption chain

Rather than embedding decryption key material in the JXA source as previous variants did, the Wavel JXA file contains no RC4 decryption logic. Instead the JXA layer decodes a base64 string and pipes the result into /bin/zsh -s. The JXA process exits immediately while the decoded zsh script continues in the background.

The decoded zsh script then carries out the live C2-dependent steps: it downloads and invokes a decryption utility called "pkgunpack" from "wavel.apple03cloudstore[.]com," performs an X25519 key exchange with the server, decrypts and stages the payload bundle, suppresses macOS notifications that would alert users to a new background login item, and polls for and uploads the staging directory as a ZIP archive.

pkgunpack, X25519 key exchange, and the effect on static analysis

Because the server holds the private key that completes the X25519 key exchange, the Data Encryption Key (DEK) cannot be recovered without the server’s cooperation; each execution generates a new ephemeral keypair so a captured DEK cannot be replayed to extract payload contents. Jamf Threat Labs concluded this design "makes static recovery of the payload significantly harder and shifts part of the operational control to the server operator," and that the encrypted payload is "effectively useless for static analysis without access to a live command‑and‑control (C2) session."

Multi-layer persistence: LaunchAgent, repair scripts, shell hooks and Git hooks

After staging, the zsh dropper installs four redundant persistence methods via LaunchAgent and writes a repair zsh script that will restore both the payload bundle and the LaunchAgent if they are removed. It also appends a shell hook to ~/.zshrc so every new interactive zsh session triggers the repair script. The repair script is additionally copied into "post-checkout" and "pre-commit" folders under "~/Library/Application Support/System/.githooks/," and the global Git configuration option "git config --global core.hooksPath" is set to that directory. As a result, any git checkout or git commit on the compromised system will silently activate the repair script.

Swift stealer: stolen data types and expanded browser targets

The final stage is a stealer component implemented in Swift — a change from the predecessor written in Rust — but the goals remain the same. The stealer:

  • serves a fake crash dialog to capture the system password and cross-checks entered information using a PAM‑based validation approach;
  • enumerates and retrieves keychain items;
  • steals credentials from a broad list of Chromium‑ and Firefox‑based browsers, including Google Chrome, Microsoft Edge, Mozilla Firefox, Brave, Vivaldi, Opera, Opera GX, Arc, Zen, Waterfox, LibreWolf, Yandex Browser, and Cốc Cốc;
  • fingerprints the system and gathers extensive metadata and the user's profile photo;
  • collects user‑centric files such as .zsh_history, .zshrc, .bash_history and .gitconfig; and
  • lists running processes and installed applications.

As Xhaflaire noted, "The inclusion of Arc, Zen and the less common regional and privacy‑focused browsers extends the target list noticeably beyond what is typical in commodity macOS stealers."

What this means for security teams, end users, and developers

  • Security teams: look for retrieval of "pkgunpack" from wavel.apple03cloudstore[.]com, unusual JXA processes that hand off to /bin/zsh, LaunchAgent entries, unexpected additions to ~/.zshrc, and global Git core.hooksPath changes that point at "~/Library/Application Support/System/.githooks/". Be aware that static samples may be unrecoverable without a live C2 interaction.
  • End users: the campaign uses a convincing macOS installer flow — opening a disk image, Script Editor prompts and a fake crash dialog to solicit the system password — and a lure presented as a cryptocurrency wallet called Wavel.
  • Developers and repository users: Git checkout or commit actions can become an activation vector when core.hooksPath is redirected to a hidden .githooks directory; reviewing global Git configuration and hooks paths can detect this behavior.

Jamf Threat Labs' analysis shows PamStealer's operators have invested in a delivery architecture that moves a decisive portion of decryption and operational control onto a live server. That shift renders conventional static analysis far less useful and leaves defenders dependent on live visibility or interception of the C2 session to recover second‑stage payloads.

Original report — The Hacker News