PamStealer macOS Malware Reinvents Payload Security & Persistence

A newly observed version of PamStealer—malware targeting macOS—has introduced major enhancements designed to thwart static analysis and ensure persistent compromise. The changes, flagged by threat researchers at Jamf Threat Labs, include server-dependent payload decryption and reinforced multi-layer persistence mechanisms. These updates mark a significant shift in how macOS threats are delivered and maintained.

How the Delivery Evolved

The attack still begins with a JavaScript for Automation (JXA) dropper, as earlier PamStealer variants used. But rather than embedding decryption keys in the JXA code, this version fetches a custom decryption tool from an external server and performs a live key exchange. Without the remote server’s involvement, the payload can’t be decrypted. Previous months’ variants relied on RC4 decryption using embedded keys directly in the JXA source.

The lure has also shifted. Earlier campaigns impersonated clipboard management apps like Maccy, Scoppr, and Nancy. Now, attackers are using a fake site called “wavel.app,” advertising a crypto wallet named Wavel that doesn’t exist. When users click “Download for macOS,” they get a .dmg disk image containing an AppleScript file. Opening it triggers the Script Editor, which then fires off the JXA dropper sequence.

From Dropper to Payload: Infection Chain & Persistence

Once the user engages, the JXA script now acts mostly as a carrier: it takes a base64-encoded string, feeds it to /bin/zsh, and offloads control. From there, a zsh script carries out multiple steps: downloading the decryption utility (“pkgunpack”) from a remote server, performing an X25519 key exchange, decrypting and staging the true payload, and suppressing macOS notifications about new background login items.

For persistence, the malware employs several overlapping mechanisms. It installs a LaunchAgent, deploys a repair script to restore both the payload and LaunchAgent if removed, and appends a shell hook to ~/.zshrc so that each new interactive zsh session triggers the repair logic. Additionally, the attacker configures Git hooks in “.githooks” folders under ~/Library/Application Support/System, steering both commit and checkout actions to invoke the repair script silently.

Capabilities: What the Stealer Does

The stealer component is now written in Swift (previously in Rust), though its goals remain the same. It uses a fake crash dialog to trigger system password input validation via PAM, steals keychain items, harvests credentials from a wide range of browsers—including privacy‐focused and regional ones like Arc, Zen, Waterfox, Yandex, and more—and fingerprints the system while collecting metadata and the user’s profile photo. It also gathers shell history files (.zsh_history, .bash_history), Git config, running processes, and installed applications.

Critically, each instance of PamStealer generates a new pair of ephemeral keys, so even if an attacker retrieves a Data Encryption Key (DEK), it’s useless without the private key on the server. That live decryption link places considerable power in the attacker’s hands, making static forensics much less effective.

The evolution of PamStealer reflects a broader trend in macOS malware toward more sophisticated delivery chains, real‐time control from command-and-control (C2) servers, and layered persistence mechanisms. For defenders, it raises the bar on detection and response—not just spotting malicious code, but also breaking live C2 ties and removing all persistence layers. Going forward, monitoring for unusual Git hook activity, background login items, and shell hooks in config files may help catch advanced threats earlier.