AMOS Stealer (Atomic macOS Stealer) — June 2026 Keychain-Theft Campaign
Executive Summary
AMOS (Atomic macOS Stealer) is a financially motivated macOS infostealer being distributed through a June 2026 campaign that pairs deceptive software downloads and fake websites with ClickFix-style social engineering: the victim is instructed to copy a command and paste it into Terminal (or, in newer variants, into Script Editor via an applescript:// URL to dodge Apple's Terminal paste-protection). That single pasted command is a curl | sh loader.
The loader uses macOS's built-in curl with -fsSL — flags that suppress progress bars and error output so the download runs silently — to pull a remote script, then launches AppleScript via the zsh/osascript chain. Running curl|sh straight from Terminal sidesteps Gatekeeper because no quarantined app bundle is ever launched. Once executing, AMOS copies the macOS Keychain database login.keychain-db; harvests passwords, cookies and autofill from Google Chrome and Microsoft Edge; and reads developer secrets at ~/.ssh, ~/.kube, ~/.zshrc and ~/.gitconfig.
Stolen data is compressed with the native ditto tool into /tmp/osalogging.zip, split into 10 MB chunks, and exfiltrated over HTTP PUT via curl (retrying failed uploads up to eight times) to attacker infrastructure such as bestbuydomain.com. A session ID is derived from the current timestamp mixed with an OpenSSL hex string. The malware then cleans up with rm -f /tmp/osalogging.zip and rm -rf /tmp/sync.
Defender priority: The highest-fidelity signals are behavioral and live in Falcon for macOS process telemetry — a curl -fsSL ... | sh chain launched from Terminal/zsh, an osascript spawned in that same chain, a non-Apple process touching login.keychain-db, and ditto writing /tmp/osalogging.zip. Any confirmed Keychain copy or osalogging.zip staging is a probable live infostealer — assume ALL Keychain, browser, SSH and cloud credentials on that host are exfiltrated and rotate them.
Source Review & Web Hunter Notes
| Tier | Source | Key Finding | Carry Forward |
|---|---|---|---|
| 1 · Vendor | Trend Micro Research | AMOS distributed via deceptive downloads / fake sites; curl -fsSL loader, ditto staging, chunked PUT exfil, retry-8. | Yes |
| 1 · Vendor | Microsoft Security Blog (ClickFix macOS) | ClickFix fake-utility lures push Terminal-pasted base64 → curl|sh that loads AMOS / MacSync / Shub; targets Keychain, wallets. | Yes |
| 1 · Vendor | Jamf Threat Labs | Variant abuses applescript:// URL scheme → Script Editor to deliver Atomic Stealer, bypassing Terminal paste-protection on macOS Tahoe 26.4. | Yes |
| 2 · Press | Hackread | AMOS copies login.keychain-db, Chrome/Edge passwords + cookies + autofill, reads .ssh/.kube/.zshrc/.gitconfig; C2 bestbuydomain.com. | Yes |
| 2 · Press | Sophos / Infosecurity Magazine | AMOS at scale; ClickFix evolution; Atomic Stealer bypasses Apple security warnings via user-driven Terminal execution. | Partial |
Web-hunter note: AMOS is sold as a stealer-as-a-service, so payload hashes, lure domains and staging server hosts rotate constantly. Durable indicators here are behavioral (the curl|sh-from-Terminal loader, Keychain copy, ditto→osalogging.zip, chunked PUT). Treat the named domain and filenames as hunt/enrich values and confirm in your own telemetry before promoting any single host/hash to a durable block.
Hunt Brief & Attack Chain
Hypotheses (ordered by fidelity)
- H1 (high):
curllaunched fromTerminal/zshwith-fsSLand its output piped to a shell (curl ... | sh/zsh/bash) → the ClickFix loader (T1059.004, T1105). Very low FP. - H2 (high): A non-Apple, non-Keychain-Access process reads or copies
login.keychain-db→ Keychain credential theft (T1555.001). Strong. - H3 (high):
ditto(or any process) writesosalogging.zip/ touches/tmp/sync→ archive staging of collected data (T1560). Near-unique to this campaign. - H4 (medium):
osascript/ AppleScript spawned byTerminal/zshin the install chain → scripted execution (T1059.002). - H5 (medium): An untrusted, recently-spawned process reads browser cookie/login stores or developer keys (
~/.ssh,~/.kube,~/.gitconfig, Chrome/EdgeLogin Data/Cookies) → credential harvesting (T1552.001, T1539, T1555.003). - H6 (medium): A non-browser process makes outbound DNS/connections to
bestbuydomain.comor issuescurlHTTP PUT to a rare host → exfiltration over C2 (T1041, T1071).
Attack chain
| Step | Telemetry | Hunt Angle |
|---|---|---|
| 1 · ClickFix lure: user pastes command into Terminal/Script Editor | ProcessRollup2 (ParentBaseFileName=Terminal/zsh) | H1 — curl -fsSL piped to a shell |
| 2 · Loader fetches + runs remote script; AppleScript stage | ProcessRollup2 (osascript under Terminal/zsh) | H4 — osascript in install chain |
| 3 · Copy macOS Keychain DB | FileOpenInfo / ProcessRollup2 (login.keychain-db) | H2 — non-Apple proc touches Keychain |
| 4 · Harvest browser secrets + dev keys | FileOpenInfo (Cookies, Login Data, .ssh/.kube) | H5 — untrusted reads of cred stores |
| 5 · Stage archive via ditto | FileCreateInfo (TargetFileName=osalogging.zip) | H3 — ditto → /tmp/osalogging.zip |
| 6 · Chunked HTTP PUT exfil; cleanup | DnsRequest / NetworkConnectIP4; CommandLine (curl -T / PUT, rm) | H6 — PUT to rare host / IOC domain |
Consolidated IOC Table
AMOS is stealer-as-a-service; payload hashes and lure/staging hosts rotate. The values below are behavioral and contextual. Replace REPLACE_WITH_* placeholders with indicators confirmed in your own telemetry before promoting to a block.
| Type | Value | Confidence | Action | Context |
|---|---|---|---|---|
| behavior | Terminal/zsh → curl -fsSL ... piped to sh/zsh/bash | high | detect | ClickFix curl|sh loader (H1) |
| behavior | Non-Apple process reads/copies login.keychain-db | high | detect | Keychain theft (H2) |
| filename | osalogging.zip | high | detect | ditto staging archive (H3) |
| path | /tmp/osalogging.zip, /tmp/sync | high | hunt | Staging + scratch dirs (H3) |
| domain | bestbuydomain.com | medium | detect | Exfil / C2 host (perishable) |
| sha256 | REPLACE_WITH_AMOS_PAYLOAD_SHA256 | medium | hunt | Confirmed loader/payload hash (perishable) |
| domain | REPLACE_WITH_LURE_OR_STAGING_DOMAIN | low | enrich | Fake-app download / script host |
Affected Surface & Telemetry Matrix
| Surface | Required Telemetry | Priority | Gap Risk |
|---|---|---|---|
| macOS endpoints (Falcon for macOS) — esp. developer/admin laptops | ProcessRollup2 (ParentBaseFileName, ImageFileName, CommandLine) | Critical | Low |
| Keychain & credential-store file access | FileOpenInfo (TargetFileName=login.keychain-db, Cookies, Login Data) | High | Med — file-read telemetry coverage varies |
| Archive staging dir (/tmp) | FileCreateInfo (TargetFileName=osalogging.zip) | High | Low |
| Outbound exfil / C2 | NetworkConnectIP4, DnsRequest | Medium | Low |
ATT&CK Mapping
| Tactic | Technique | Observed Behavior | Query / Control |
|---|---|---|---|
| Execution | T1059.004 — Unix Shell | curl -fsSL piped to sh from Terminal/zsh | Q1 · S12 |
| Execution | T1059.002 — AppleScript | osascript spawned by Terminal/zsh loader | Q2 |
| Command & Control | T1105 — Ingress Tool Transfer | curl -fsSL fetch of remote payload | Q1 |
| Credential Access | T1555.001 — Keychain | Copy of login.keychain-db | Q3 |
| Credential Access | T1539 / T1555.003 — Cookies / Browser Creds | Read Chrome/Edge Cookies + Login Data | Q4 |
| Credential Access | T1552.001 — Credentials in Files | Read ~/.ssh, ~/.kube, ~/.gitconfig | Q4 |
| Collection | T1560.001 — Archive via Utility (ditto) | ditto writes /tmp/osalogging.zip | Q5 |
| Exfiltration | T1041 / T1071.001 — Exfil over C2 / Web | Chunked HTTP PUT to rare host / IOC domain | Q6 |
Native Audit-Log Hunts (non-CQL)
Checks that do not require Falcon process telemetry — run these directly on a suspect macOS host or via MDM-pushed scripts:
- Staging artifact sweep: look for the staging archive and scratch dir:
ls -la /tmp/osalogging.zip /tmp/sync 2>/dev/null. Either present (or recently deleted, per FSEvents) is a strong AMOS indicator. - Shell history review: inspect
~/.zsh_historyand~/.bash_historyfor a pastedcurl -fsSL ... | shone-liner or anosascriptinvocation the user does not recognize — the ClickFix lure. - Keychain access time: check the mtime/atime of
~/Library/Keychains/login.keychain-dbagainst the suspected infection window; a copy/read by malware leaves access traces. - Quarantine / Gatekeeper: because curl|sh bypasses Gatekeeper, expect NO quarantine event for the payload — absence of a normal app-launch/quarantine record alongside the above is itself suspicious.
- Browser store integrity: confirm whether Chrome/Edge
CookiesandLogin DataSQLite files were read by a non-browser process during the window (correlate with Q4).
CrowdStrike LogScale CQL Hunt Queries
Looks for: a curl (or the shell wrapping it) launched under Terminal/zsh with the loader's signature -fsSL flags and a pipe to a shell — the ClickFix curl|sh stage (H1, T1059.004/T1105). FP: low; some developer install scripts use the same idiom — baseline trusted install hosts and exclude known package-manager bootstraps.
// HUNT: curl -fsSL piped to a shell, launched from Terminal/zsh (ClickFix loader) // MITRE: T1059.004, T1105 // CONF: high FP: low COST: low | REQUIRES: Falcon for macOS ProcessRollup2 // FALSE POSITIVES: legit dev install one-liners (Homebrew/nvm/rustup bootstraps) // TUNING: exclude CommandLine matching known install domains after baselining #event_simpleName=/ProcessRollup2|SyntheticProcessRollup2/ | ParentBaseFileName=/^(Terminal|zsh|bash|sh|iTerm2|Script Editor|osascript)$/i | ImageFileName=/\/(curl|zsh|bash|sh)$/i | CommandLine=/curl\s+(-\w*[fsSL]\w*\s+)+/i | CommandLine=/curl[^|]*\|\s*(sh|zsh|bash)/i | table([@timestamp, ComputerName, aid, ParentBaseFileName, ImageFileName, CommandLine, UserName], limit=200)
Looks for: osascript spawned by Terminal/zsh/curl in the install chain — the AppleScript stage of the loader (H4, T1059.002). FP: medium; admin/automation scripts and some apps drive osascript legitimately — baseline known automation and prioritize osascript whose ancestry includes curl or a freshly pasted shell.
// HUNT: osascript/AppleScript spawned by a Terminal/zsh loader chain // MITRE: T1059.002 // CONF: medium FP: medium COST: low | REQUIRES: ProcessRollup2 (macOS) // FALSE POSITIVES: legit admin automation / app-driven AppleScript // TUNING: exclude known automation CommandLine; favor hits with curl/sh ancestry #event_simpleName=/ProcessRollup2|SyntheticProcessRollup2/ | ParentBaseFileName=/^(Terminal|zsh|bash|sh|curl|Script Editor)$/i | ImageFileName=/\/osascript$/i | table([@timestamp, ComputerName, aid, ParentBaseFileName, ImageFileName, CommandLine, UserName], limit=200)
Looks for: a file open/access on login.keychain-db by a process that is not Keychain Access, the security daemon, or a signed Apple binary — Keychain credential theft (H2, T1555.001). FP: low after excluding Apple/Keychain tooling and known password managers; investigate every remaining hit.
// HUNT: Keychain DB (login.keychain-db) accessed by a non-Apple/non-Keychain process // MITRE: T1555.001 // CONF: high FP: low COST: medium | REQUIRES: FileOpenInfo (macOS) // FALSE POSITIVES: Keychain Access.app, securityd, signed password managers // TUNING: exclude trusted ImageFileName (Keychain Access, security, 1Password, etc.) #event_simpleName=/FileOpenInfo/ | TargetFileName=/login\.keychain-db$/i | ImageFileName!=/\/(Keychain Access|security|securityd|cloudd|trustd)$/i | ImageFileName!=/\/Applications\/(1Password|Bitwarden|Keeper)[^\/]*\.app\//i | table([@timestamp, ComputerName, aid, ImageFileName, TargetFileName, UserName], limit=200)
Looks for: a non-browser process reading Chrome/Edge Cookies/Login Data stores or developer secrets (~/.ssh, ~/.kube, ~/.gitconfig, ~/.zshrc) — credential harvesting (H5, T1539/T1552.001/T1555.003). FP: medium; the browsers themselves, backup tools and dev tooling read these — exclude the owning browser and known backup/sync agents.
// HUNT: Non-browser process reads browser cred stores or developer keys // MITRE: T1539, T1552.001, T1555.003 // CONF: medium FP: medium COST: medium | REQUIRES: FileOpenInfo (macOS) // FALSE POSITIVES: the browser itself; backup/sync agents; dev tooling // TUNING: exclude Google Chrome/Microsoft Edge bundles and known backup agents #event_simpleName=/FileOpenInfo/ | TargetFileName=/(\/(Cookies|Login Data|Web Data)$|\/\.(ssh|kube|gitconfig|zshrc))/i | ImageFileName!=/\/(Google Chrome|Microsoft Edge|Google Chrome Helper.*|com\.apple\.).*$/i | table([@timestamp, ComputerName, aid, ImageFileName, TargetFileName, UserName], limit=200)
Looks for: creation of osalogging.zip (or any write under /tmp/sync) — AMOS's ditto archive-staging step (H3, T1560.001). FP: very low; the filename is near-unique to this campaign. The companion process angle (ditto targeting /tmp/osalogging.zip) is folded in.
// HUNT: Archive staging — osalogging.zip created / ditto staging to /tmp // MITRE: T1560.001 // CONF: high FP: low COST: low | REQUIRES: FileCreateInfo + ProcessRollup2 (macOS) // FALSE POSITIVES: very low — filename is campaign-specific // TUNING: none typically needed; investigate every hit #event_simpleName=/ProcessRollup2|SyntheticProcessRollup2/ | TargetFileName=/osalogging\.zip$/i OR TargetFileName=/\/tmp\/sync\//i OR (ImageFileName=/\/ditto$/i AND CommandLine=/\/tmp\/(osalogging\.zip|sync)/i) | table([@timestamp, ComputerName, aid, ImageFileName, TargetFileName, CommandLine, UserName], limit=200)
Looks for: the exfil stage — a curl issuing an HTTP PUT / upload (-T / --upload-file / -X PUT), or a DNS request to the IOC domain bestbuydomain.com (H6, T1041/T1071.001). FP: medium for the curl-PUT idiom (legit API uploads) — scope to non-browser parents and rare destinations; the DNS branch is high-fidelity. Replace/extend the domain regex as new infra is confirmed.
// HUNT: Chunked exfil — curl PUT/upload or DNS to AMOS IOC domain // MITRE: T1041, T1071.001 // CONF: medium FP: medium COST: medium | REQUIRES: ProcessRollup2 + DnsRequest (macOS) // FALSE POSITIVES: legit curl PUT to internal/CDN APIs; exclude known upload endpoints // TUNING: add confirmed staging hosts; scope curl-PUT branch to non-browser parents #event_simpleName=/ProcessRollup2|SyntheticProcessRollup2|DnsRequest/ | (ImageFileName=/\/curl$/i AND CommandLine=/(--upload-file|\s-T\s|-X\s*PUT)/i) OR DomainName=/bestbuydomain\.com$/i | table([@timestamp, ComputerName, aid, ImageFileName, ParentBaseFileName, CommandLine, DomainName, UserName], limit=200)
Looks for: the post-exfil cleanup — rm -f /tmp/osalogging.zip or rm -rf /tmp/sync (T1070.004, Indicator Removal). FP: low; these exact paths are campaign-specific. A hit on Q7 with no preceding Q5 staging may indicate the staging file write was missed by file telemetry — still treat as a strong lead.
// HUNT: Post-exfil cleanup of AMOS staging artifacts // MITRE: T1070.004 // CONF: medium FP: low COST: low | REQUIRES: ProcessRollup2 (macOS) // FALSE POSITIVES: low — exact paths are campaign-specific // TUNING: none typically needed; correlate with Q5 staging #event_simpleName=/ProcessRollup2|SyntheticProcessRollup2/ | ImageFileName=/\/rm$/i | CommandLine=/\/tmp\/(osalogging\.zip|sync)/i | table([@timestamp, ComputerName, aid, ImageFileName, ParentBaseFileName, CommandLine, UserName], limit=200)
CrowdStrike Custom IOA Recommendations
Promotion candidates from the hunt queries above (macOS platform, Process Create rule type unless noted):
| IOA Name | Pattern | Exclusions | Action / Deployment |
|---|---|---|---|
| curl|sh From Terminal (ClickFix Loader) | Parent Terminal|zsh|Script Editor → curl/sh with -fsSL and pipe-to-shell in command line | Known dev install bootstraps (Homebrew/nvm/rustup) | Detect → Block after 1–2 wk baseline (from Q1) · M1040 |
| Keychain DB Access by Untrusted Proc | File access on login.keychain-db by non-Apple/non-password-manager image | Keychain Access, securityd, signed PW managers | Detect (from Q3) — file-keyed; deploy as scheduled-search detection |
| AMOS Staging Archive Written | FileCreate osalogging.zip or ditto → /tmp/osalogging.zip | None (campaign-specific name) | Detect → Block candidate (from Q5) |
Q3 and Q5 key on file telemetry rather than process creation — deploy them as scheduled-search / file-based detections rather than Process-Create IOAs. Q1 is the strongest blocking-IOA candidate once dev-install false positives are baselined out.
Machine-Readable IOC Appendix
One-click copy blocks for ingestion. Hashes and lure/staging hosts are perishable for this stealer-as-a-service — use placeholders until you confirm values in your own telemetry.
type,value,action,severity,expiration,description,tags domain,bestbuydomain.com,detect,high,2026-09-22,AMOS exfil/C2 host,campaign:AMOSStealer sha256,REPLACE_WITH_AMOS_PAYLOAD_SHA256,detect,critical,2026-12-22,AMOS loader/payload,campaign:AMOSStealer domain,REPLACE_WITH_LURE_OR_STAGING_DOMAIN,detect,high,2026-09-22,AMOS fake-app/script host,campaign:AMOSStealer
parent_proc IN (Terminal, zsh, Script Editor) AND child curl -fsSL ... | sh/zsh/bash # ClickFix loader file_access: login.keychain-db BY non-Apple proc # Keychain theft file_read: Chrome/Edge (Cookies, Login Data), ~/.ssh ~/.kube ~/.gitconfig file_create: osalogging.zip (ditto staging) net: curl PUT/upload to rare host | DNS bestbuydomain.com cleanup: rm -f /tmp/osalogging.zip ; rm -rf /tmp/sync
AMOS — Atomic macOS Stealer (Jun 2026 Keychain campaign) Delivery: ClickFix fake-app / Terminal-paste; applescript:// variant Loader: curl -fsSL <url> | sh -> osascript (zsh chain), bypasses Gatekeeper Targets: login.keychain-db; Chrome/Edge pw+cookies+autofill; ~/.ssh ~/.kube ~/.zshrc ~/.gitconfig Staging: ditto -> /tmp/osalogging.zip (10MB chunks); session id = ts + openssl hex Exfil: HTTP PUT via curl, retry x8 -> bestbuydomain.com Cleanup: rm -f /tmp/osalogging.zip ; rm -rf /tmp/sync
# Staging artifacts present (or recently removed) ls -la /tmp/osalogging.zip /tmp/sync 2>/dev/null # ClickFix one-liner in shell history grep -nE 'curl[^|]*\|[[:space:]]*(sh|zsh|bash)|osascript' \ ~/.zsh_history ~/.bash_history 2>/dev/null # Keychain DB access window stat -f '%Sa %N' ~/Library/Keychains/login.keychain-db 2>/dev/null
Detection Validation Gates
| Gate | Check | Pass Criteria |
|---|---|---|
| 1 · Telemetry ready | Falcon for macOS on all in-scope endpoints; ProcessRollup2, FileOpenInfo/FileCreateInfo, DnsRequest flowing | Events seen from a representative macOS fleet in last 24h |
| 2 · Benign baseline | Run Q1/Q2/Q4 over 7–14 days; catalog legit dev install one-liners, automation osascript, browser/backup file reads | Known-good command lines & reader images enumerated & excluded |
| 3 · Positive test | In a lab macOS host, run a benign curl -fsSL http://example/x | sh from Terminal and ditto -c -k somedir /tmp/osalogging.zip | Q1 and Q5 both fire on the test actions |
| 4 · Promotion | Q1 FP rate acceptable after excluding dev bootstraps; Q3/Q5 reviewed | Promote Q1 to blocking IOA; keep Q2/Q4/Q6 as investigate-only |
Hardening — Tiered
- User training against clipboard-paste-to-Terminal: the entire attack hinges on a user pasting a command into Terminal/Script Editor. Brief staff that no legitimate fix requires pasting a
curl … | shcommand, and report such prompts. (M1017 — User Training.) - Deploy Q1 + Q5 as detections now across all macOS endpoints — they catch the live loader and the staging archive even before policy changes land. (M1040 — Behavior Prevention on Endpoint; enable Falcon behavior-prevention for curl|sh.)
- Block the IOC domain
bestbuydomain.comat the proxy/DNS resolver and add to Falcon IOC management; sweep for/tmp/osalogging.zip+/tmp/syncfleet-wide (S10 audit). (M1037 — Filter Network Traffic.)
- Enforce Gatekeeper + notarization via MDM; block install of unsigned apps. Set
AllowIdentifiedDevelopers/Gatekeeper to App Store + identified developers and disablespctloverrides. Reduces the fake-app vector. (M1038 — Execution Prevention; CIS Apple macOS Benchmark.) - Protect the Keychain & restrict scripting: use MDM/PPPC to limit which apps get Full Disk Access (gating
login.keychain-dband browser stores), and where feasible restrict Terminal/osascripton non-developer fleets. (M1022 — Restrict File/Dir Permissions; M1042 — Disable or Remove Feature.) - Egress filtering from endpoints: require web egress through an inspecting proxy; alert on
curl-issued HTTP PUT/uploads to rare external hosts from non-browser processes. (M1037.)
- Credential hygiene program: move developer secrets off plaintext dotfiles (SSH key passphrases + agent, sealed kubeconfig, secret managers); enable browser passkeys / hardware-backed sync so a stolen cookie/keychain is less reusable. (M1027 / M1026.)
- ClickFix-aware policy: consider MDM removal of
applescript://URL-scheme handling for Script Editor on standard fleets and keep macOS patched to retain Terminal paste-protection. (M1042; M1051 — Update Software.)
Deployable Playbooks
A · Enforce Gatekeeper + block unsigned apps (MDM config profile)
Deploy this com.apple.systempolicy.control payload via your MDM (Jamf/Intune/Kandji) to require notarized, identified-developer apps:
<!-- profile payload: com.apple.systempolicy.control --> <key>EnableAssessment</key><true/> <key>AllowIdentifiedDevelopers</key><true/> <!-- forbid users disabling Gatekeeper (spctl --master-disable) --> <key>PayloadType</key><string>com.apple.systempolicy.control</string>
B · Host triage / IOC sweep (shell — push via MDM)
# AMOS staging + scratch artifacts ls -la /tmp/osalogging.zip /tmp/sync 2>/dev/null # ClickFix curl|sh or osascript in shell history (per user) grep -nE 'curl[^|]*\|[[:space:]]*(sh|zsh|bash)|osascript' \ /Users/*/.zsh_history /Users/*/.bash_history 2>/dev/null # Verify Gatekeeper is enforced spctl --status
C · Block IOC domain at the resolver / proxy
# /etc/hosts sinkhole (endpoint stopgap) or push to DNS RPZ / proxy denylist 0.0.0.0 bestbuydomain.com # Falcon: add domain to IOC Management (detect/block) — see S10 CSV
D · Credential rotation checklist (post-compromise)
# Treat ALL of these as exfiltrated on a confirmed host: # - macOS Keychain items (login.keychain-db copied) # - Chrome + Edge saved passwords, cookies/sessions -> force re-auth # - SSH keys (~/.ssh) -> revoke + reissue, rotate authorized_keys # - Kubeconfig (~/.kube) -> rotate cluster creds/tokens # - Git creds / tokens (~/.gitconfig, credential stores) -> revoke PATs
Containment Runbook
| Phase | Actions | Owner | Evidence |
|---|---|---|---|
| Isolate | Network-contain the host in Falcon; preserve memory + disk; do not reboot. Capture /tmp and shell history before they are wiped. | SOC / IR | Falcon containment record; /tmp/osalogging.zip + history captures |
| Eradicate | Kill the loader process tree (Terminal→curl→sh→osascript); remove staged artifacts (/tmp/osalogging.zip, /tmp/sync); remove any dropped persistence (LaunchAgents/Daemons). | IR | Process tree, removed-file inventory, persistence audit |
| Rotate creds | Assume full exfil: rotate ALL Keychain items, Chrome/Edge passwords, and revoke browser sessions/cookies; reissue SSH keys, rotate kubeconfig + cloud tokens, revoke Git PATs (S13-D). | IR / Identity | Rotation log; session-revocation confirmations |
| Recover | Reimage if integrity uncertain (stealer may have dropped second-stage tooling); restore from known-clean state; re-enroll in MDM with Gatekeeper enforced. | SOC / Endpoint | Reimage record; post-restore hunt (Q1–Q7) results |
| Report | Document the lure (source site/command), data accessed, and credentials rotated; notify affected SaaS/cloud owners of session revocation. | IR lead | Timeline; lure source; impact + rotation record |
Detection Coverage Map
| Technique | Behavior | CQL | IOA | Coverage |
|---|---|---|---|---|
| T1059.004 / T1105 | curl -fsSL | sh from Terminal (loader) | Q1 | Q1 (block candidate) | Good |
| T1059.002 | osascript in install chain | Q2 | — | Partial — FP tuning required |
| T1555.001 | login.keychain-db copied | Q3 | Q3 (file-keyed) | Good |
| T1539 / T1552.001 / T1555.003 | Browser stores + dev keys read | Q4 | — | Partial — needs reader baselining |
| T1560.001 | ditto → osalogging.zip | Q5 | Q5 (block candidate) | Good |
| T1041 / T1071.001 | Chunked PUT exfil / IOC DNS | Q6 | — | Partial — curl-PUT FP tuning |
| T1070.004 | Cleanup rm of staging artifacts | Q7 | — | Good |
| Wallet / crypto theft | Crypto-wallet file collection | — | — | GAP — out of scope; extend Q4 with wallet paths |
Validation: The loader spine (Q1), Keychain theft (Q3) and staging (Q5/Q7) are strong and low-FP. The credential-harvest read query (Q4) and exfil query (Q6) need reader/upload-endpoint baselining to keep FP acceptable. Crypto-wallet collection is not covered here — extend Q4's TargetFileName regex with wallet store paths if relevant to your fleet. Validate macOS file-event field names (FileOpenInfo vs FileCreateInfo) and the DomainName field against your tenant before deploying.
Hunt Summary Ticket
TITLE: Hunt — AMOS / Atomic macOS Stealer (ClickFix Keychain-theft campaign)
SEVERITY: High (active credential theft; Keychain + browser + dev keys exfiltrated)
SCOPE: macOS endpoints (Falcon for macOS) — prioritize developer/admin laptops
HYPOTHESIS: ClickFix lure -> user pastes curl -fsSL | sh in Terminal -> AMOS copies
login.keychain-db + browser/dev creds, ditto-stages /tmp/osalogging.zip,
exfils via chunked HTTP PUT, then cleans up.
QUERIES: Q1 curl|sh-from-Terminal | Q2 osascript | Q3 keychain copy |
Q4 browser/dev-key reads | Q5 osalogging.zip staging |
Q6 PUT/IOC-domain exfil | Q7 cleanup rm
DO FIRST: 1) Run Q1 + Q5 + Q3 across all macOS hosts
2) Sweep fleet for /tmp/osalogging.zip and /tmp/sync (S10 audit)
3) Any hit = treat as live infostealer -> containment + ROTATE ALL CREDS (S14)
FINDINGS: <fill: hosts, lure source, files, process trees, creds exfiltrated>
GAPS: Q4/Q6 need FP baselining; crypto-wallet collection out of scope
ACTIONS: Block bestbuydomain.com; enforce Gatekeeper via MDM; user training;
behavior-prevention on curl|sh; rotate Keychain/browser/ssh/cloud creds
OWNER: HuntPack
VERSION: v0.1 · 2026-06-22
Changelog
table() calls now carry an explicit row limit: the default is 200 and truncation is silent, so a capped result was indistinguishable from a complete one. Atomic-IOC sweeps (filters over 5+ hashes or C2 IPs) use limit=max so a wide infection is never silently under-scoped; behavioural hunts use limit=200, where exceeding the cap indicates the query needs tuning. Where present, event names that do not exist in the Falcon data model were corrected (e.g. ServiceInstalled is a Sysmon concept, not a Falcon event; ElfFileWritten is ELFFileWritten) — such queries could never return a row. No detection logic, fields, or IOCs changed.References
| Tier | Source | Used For | Access Date |
|---|---|---|---|
| 1 · Vendor | Trend Micro — Skills used to distribute Atomic macOS Stealer | Loader curl -fsSL, ditto staging, chunked PUT, retry-8 mechanics | 2026-06-22 |
| 1 · Vendor | Microsoft Security Blog — ClickFix fake macOS utilities deliver infostealers | ClickFix Terminal-paste lure; base64 → curl|sh; AMOS targets | 2026-06-22 |
| 1 · Vendor | Jamf Threat Labs — ClickFix abuses Script Editor to deliver Atomic Stealer | applescript:// URL-scheme variant; Terminal paste-protection bypass | 2026-06-22 |
| 2 · Press | Hackread — AMOS steals macOS Keychain files & browser passwords | login.keychain-db copy; Chrome/Edge; dotfiles; IOC domain | 2026-06-22 |
| 2 · Press | Sophos — Why AMOS matters: macOS malware stealing data at scale | AMOS scale, stealer-as-a-service context, ClickFix evolution | 2026-06-22 |