2026-07-14 · view entry permalink →
CrashStealer — a native-C++ macOS infostealer using a notarized dropper and local dscl password validation to raid keychain, browsers and wallets
Jamf Threat Labs documents CrashStealer, a macOS infostealer written in native C++ (around an internal MacOSData class) rather than the AppleScript droppers or thin Objective-C wrappers typical of commodity macOS stealers; Jamf first saw a sample on VirusTotal in early May 2026 and observed in-the-wild payload detections by early July, and tracks it as a distinct family rather than a variant of Atomic (AMOS), MacSync or Phexia (Jamf Threat Labs, 2026-07-13; BleepingComputer, 2026-07-13). Initial access is a signed and Apple-notarized dropper distributed as a "Werkbit Setup" disk image (both the image and the inner app are signed under a valid Developer ID — which Jamf reported to Apple after confirming it was used to distribute malicious payloads — with hardened runtime enabled) — because it carries a valid notarization ticket it clears Gatekeeper on first launch, so the "right-click → Open" instruction the installer shows is pure social engineering rather than a technical bypass (Jamf Threat Labs, 2026-07-13). The dropper fetches a first-stage file from a GitHub repository (keeping the opening network hop on a trusted developer domain), decodes a curl command, and pulls a shell script delivered as successive Base64 blobs decoded at runtime and piped to bash; that script downloads the payload disk image, copies the app into a hidden /private/tmp/.CrashReporter directory, strips and re-signs it ad-hoc (codesign --remove-signature then codesign -s - --force --deep), registers it with Launch Services and launches it (Jamf Threat Labs, 2026-07-13).
The payload impersonates Apple's crash reporter (bundle identifier com.apple.crashreporter, executing from the hidden staging path), clears its own quarantine and last-used-date extended attributes with xattr -cr, then presents a native-styled password prompt and validates the entered credential locally with dscl . -authonly, looping until a valid password is supplied — so the operator only ever collects credentials that actually authenticate (Jamf Threat Labs, 2026-07-13). With the validated password it unlocks the login keychain, copies login.keychain-db into a hidden ~/.cache staging root, runs a reconnaissance sweep (defaults read for version paired with du -sh for on-disk size) against an embedded list skewed toward malware-analysis and EDR tooling to profile the defensive environment, and collects browser data, Chromium/Firefox extensions (including cryptocurrency-wallet extensions) and password-manager material — AES-GCM-encrypting each item into hidden staging files as it is collected (so the loot is never written to disk in the clear), then packaging each staging directory into its own zip archive before exfiltrating over libcurl. Persistence is a LaunchAgent registered under an Apple-impersonating label with a second re-signed copy of the binary. Anti-analysis is layered throughout: the binary checks for an attached debugger via sysctl process-flag (P_TRACED) inspection at two separate points in initialization — so patching out the first check alone does not defeat it — and its C2 address and collection-target list are held as encrypted, runtime-decoded strings behind control-flow-flattening obfuscation rather than in cleartext (Jamf Threat Labs, 2026-07-13).
Validating the password with dscl -authonly before harvesting lets the operator keep only credentials that actually work
Patching out that first check is not enough on its own: a second check later in application initialization exits the same way