← All hunts high TLP:CLEAR Part 1 of 2

MacSync Scripted Execution and Credential Theft

An attacker has deployed MacSync Stealer on a macOS host by tricking a user into executing a curl-to-zsh one-liner, which then runs in-memory scripts to harvest credentials and keychains.

Based on research by Huntress 2026-09-20 12 steps · 4 queries T1027 T1059.002 T1059.004 T1140 T1204.002 T1548.004 T1555.001 T1566.002

Brief

Why Now

The recent Huntress report, MacSync Stealer: How a Google Search for Claude Led to a macOS Infostealer (https://www.huntress.com/blog/fake-claude-macsync), details a campaign using malvertising to deliver infostealers to macOS users. The adversary uses a ClickFix lure, prompting users to paste a command into their terminal to fix a software error. This command is a one-liner that downloads and executes malicious scripts directly in memory. Our hunt provides a method to find these infections before the stealer exfiltrates keychains and browser data.

How the Hunt Flows

The hunt begins with a scoping phase using hb_software_inventory. We identify macOS hosts running AI-related packages like Claude, Anthropic, or ChatGPT. Attackers target these users specifically with fake software updates or fixes for these tools. This scoping step allows the team to prioritize workstations where the lure is most likely to succeed.

The first lead query targets hb_process_activity to find the initial infection vector. We search for instances where curl pipes content directly to zsh or sh. Because developers often use one-liners for legitimate software management, this query is not a high-fidelity detection on its own. The hunt provides these results to an analyst who judges the parent process and specific command arguments to separate malvertising lures from admin tasks.

After an analyst confirms a suspicious process lead, the hunt gates into parallel evidence gathering across hb_script_activity and hb_file_activity. We search for rare script content containing specific daemon_function logic and AppleScript osascript commands. These in-memory blocks are the core of the stealer, used to bypass TCC prompts and steal the user keychain. Simultaneously, the hunt looks for the creation of /tmp/osalogging.zip, the hardcoded staging path the stealer uses to store loot.

This multi-surface pivot is why this is a hunt, not a single detection. A rule looking only for curl-to-shell commands creates excessive noise, while a rule looking only for /tmp/osalogging.zip misses infections where the file was already moved or renamed. By linking the initial lure to the rare in-memory logic and the staging file, we confirm the full infection chain.

What the Hunt Cannot See

This hunt has two main blind spots. First, it depends on process command-line history in hb_process_activity. If the initial infection occurred outside the telemetry retention window, the lead query will return zero results. Second, the hunt requires comprehensive script block logging. If the macOS environment does not capture the content of AppleScript or shell blocks, the background logic used by the stealer remains invisible.

In this series

Steps

  1. Identify hosts with AI software

    Query · scoping

    Find macOS hosts running AI-related tools that match the malvertising campaign lures.

    reads hb_software_inventorysql
    SELECT device_hostname, package_name, vendor_name FROM hb_software_inventory WHERE (instr(',' || '{{ai_keywords}}' || ',', ',' || LOWER(package_name) || ',') > 0 OR instr(',' || '{{ai_keywords}}' || ',', ',' || LOWER(vendor_name) || ',') > 0)

    What a hit looks like. A list of hostnames to focus the hunt on. Silence means no known AI software matches were found.

  2. Suspicious curl-to-shell lead

    Query · detection candidate

    Identify the primary ClickFix delivery mechanism where curl pipes content directly to a shell interpreter.

    reads hb_process_activitysql
    SELECT device_hostname, process_name, process_cmd_line, time FROM hb_process_activity WHERE (LOWER(process_cmd_line) LIKE '%curl %' AND (LOWER(process_cmd_line) LIKE '%|%zsh%' OR LOWER(process_cmd_line) LIKE '%|%sh%')) AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days')

    What a hit looks like. Process events showing one-liner scripted execution. Silence proof that no such command ran within the retention window.

  3. Assess lead suspicion

    Agent triage

    Determine if the curl execution looks like the MacSync loader or a legitimate admin task.

  4. Gate on suspicious execution

    Decision

    Open the expensive queries only if a suspicious lead is confirmed.

  5. MacSync in-memory script logic

    Query · baseline

    Identify the rare background daemon functions and AppleScript keychain theft logic.

    reads hb_script_activitysql
    SELECT device_hostname, script_content, time FROM hb_script_activity WHERE (LOWER(script_content) LIKE '%daemon_function%' OR LOWER(script_content) LIKE '%osascript%') AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days') GROUP BY script_content HAVING COUNT(DISTINCT device_hostname) <= 3

    What a hit looks like. Rare scripts containing MacSync core logic. Silence suggests no scripted theft was captured.

  6. Exfiltration staging file

    Query · enrichment

    Find the creation of the specific /tmp/osalogging.zip archive used to stage stolen loot.

    reads hb_file_activitysql
    SELECT device_hostname, file_path, activity_name, time FROM hb_file_activity WHERE LOWER(file_path) = '/tmp/osalogging.zip' AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days')

    What a hit looks like. Records of the staging zip file being created or modified. Silence means the file was not created or has already been removed.

  7. Triage infection evidence

    Agent triage

    Synthesize the lead and follow-on script/file activity into a final verdict.

  8. Route based on infection status

    Decision

    Direct confirmed infections to response and others to documentation.

  9. Isolate and remediate host

    Response action

    Halt data exfiltration and remove the malware's active components.

  10. Analyst final review

    Analyst task

    Manually verify the findings and confirm remediation success.

  11. Close out hunt

    Analyst task

    Finalize the hunt and document the negative result.

Coverage

Scenario coverage

StageCoveredHow, or why not
ClickFix Malvertising Lure
T1566.002 · T1204.002 · T1059.004
Yes curl-to-shell-lead
Background ZSH Loader
T1027 · T1140 · T1059.004
Yes macsync-script-logic
Dynamic AppleScript Stealer
T1059.002 · T1555.001 · T1548.004
Yes macsync-script-logic, staging-file-activity
Mach-O RAT and Persistence
T1543.001 · T1071.001 · T1573.002
Out of scope Belongs to another part of the 'MacSync Stealer: How a Google Search for Claude Led to a macOS Infostealer' series.
Screen Recording Permission Capture
T1113 · T1548.004
Out of scope Belongs to another part of the 'MacSync Stealer: How a Google Search for Claude Led to a macOS Infostealer' series.
Crypto Wallet Trojanization
T1539 · T1552 · T1491
Out of scope Belongs to another part of the 'MacSync Stealer: How a Google Search for Claude Led to a macOS Infostealer' series.

Blind spots

  • Needs hb_process_activity with at least 30 days of command-line history. If the malvertising event happened more than 14 days ago, the primary lead query will return zero results despite an active infection. It would answer Whether the initial curl pipe command was executed outside the telemetry retention window.. Remediation: Increase retention for hb_process_activity on macOS endpoints to 30 days.
  • Needs hb_script_activity with full AppleScript and Shell block logging enabled. By default, many macOS systems do not log script block content. Without this, the background logic of the stealer is invisible. It would answer Whether the in-memory daemon_function and osascript logic can be observed.. Remediation: Deploy MDM profiles to enable comprehensive shell and script block logging.

Parameters & data

Parameters

ParameterTypeDefaultWhat it is
ai_keywordslist[string]claude, anthropic, chatgpt, claude codeKeywords to identify potential target hosts running AI software.
lookback_daysnumber14Days of history to examine.
scope_hostslist[host]Optional list of hosts to narrow the hunt based on the scoping step.

Telemetry

SourceCategoryTelemetry
Endpoint telemetry (hb_ surfaces)endpointendpoint

Source

Download hunt.md Definition (JSON) An open hunt.md file; it runs anywhere that reads the format.
---
analysis: "A static detection rule for 'curl piped to shell' creates excessive noise\
  \ in developer environments. This hunt uses a gated flow to first isolate suspicious\
  \ one-liners and then corroborate them with rare in-memory script logic and exfiltration\
  \ staging files\u2014a multi-surface pivot that a single process rule cannot perform."
blind_spots:
- id: process-history-retention
  owner: SOC Infrastructure
  question: Whether the initial curl pipe command was executed outside the telemetry
    retention window.
  remediation: Increase retention for hb_process_activity on macOS endpoints to 30
    days.
  requires: hb_process_activity with at least 30 days of command-line history
  risk: If the malvertising event happened more than 14 days ago, the primary lead
    query will return zero results despite an active infection.
  stage: initial-access-clickfix-lure
- id: script-logging-disabled
  owner: Mac Platform Team
  question: Whether the in-memory daemon_function and osascript logic can be observed.
  remediation: Deploy MDM profiles to enable comprehensive shell and script block
    logging.
  requires: hb_script_activity with full AppleScript and Shell block logging enabled
  risk: By default, many macOS systems do not log script block content. Without this,
    the background logic of the stealer is invisible.
  stage: background-zsh-loader
coverage:
- stage: initial-access-clickfix-lure
  status: covered
  steps:
  - curl-to-shell-lead
- stage: background-zsh-loader
  status: covered
  steps:
  - macsync-script-logic
- stage: dynamic-applescript-theft
  status: covered
  steps:
  - macsync-script-logic
  - staging-file-activity
- reason: 'Belongs to another part of the ''MacSync Stealer: How a Google Search for
    Claude Led to a macOS Infostealer'' series.'
  stage: persistent-macho-rat
  status: out_of_scope
- reason: 'Belongs to another part of the ''MacSync Stealer: How a Google Search for
    Claude Led to a macOS Infostealer'' series.'
  stage: screen-capture-helper
  status: out_of_scope
- reason: 'Belongs to another part of the ''MacSync Stealer: How a Google Search for
    Claude Led to a macOS Infostealer'' series.'
  stage: wallet-app-trojanization
  status: out_of_scope
guardrails:
  claims: no_unsupported
  evidence: citation_required
  missing_data: not_benign
  telemetry: untrusted
hunt:
  applicability: campaign-specific
  handoff: keep-as-periodic-hunt
  justification: MacSync Stealer targets highly valuable developer credentials and
    crypto assets via legitimate AI domains; identifying the initial scripted execution
    is the only way to stop the theft before session cookies are exfiltrated.
  methodology: model-assisted
  trigger: intel-report
hypothesis: An attacker has deployed MacSync Stealer on a macOS host by tricking a
  user into executing a curl-to-zsh one-liner, which then runs in-memory scripts to
  harvest credentials and keychains.
labels:
- hunt
- attack.t1566.002
- attack.t1204.002
- attack.t1059.004
- attack.t1027
- attack.t1140
- attack.t1059.002
- attack.t1555.001
- attack.t1548.004
name: MacSync Scripted Execution and Credential Theft
parameters:
  ai_keywords:
    default:
    - claude
    - anthropic
    - chatgpt
    - claude code
    description: Keywords to identify potential target hosts running AI software.
    from:
      kind: article
      observed: '2026-08-17'
      ref: huntress-macsync
    type: list[string]
  lookback_days:
    default: '14'
    description: Days of history to examine.
    from:
      kind: manual
      observed: '2026-08-17'
      ref: hunt-standard
    type: number
  scope_hosts:
    default: []
    description: Optional list of hosts to narrow the hunt based on the scoping step.
    from:
      kind: manual
      observed: '2026-08-17'
      ref: analyst-input
    type: list[host]
provenance:
  authors:
  - name: Huntbase hunt generation
    org: huntbase.io
  generated:
    by: huntbase-hunt-generation
    from: https://www.huntress.com/blog/fake-claude-macsync
    gates:
    - dry-run
    - lint
    model: hb_google/gemini-3-flash-preview
rationale: Focus on macOS workstations used by developers or researchers who are likely
  to experiment with AI tools. Use the software inventory to identify targets that
  have recently installed or searched for AI assistance tools.
references:
- name: 'Huntress - MacSync Stealer: How a Google Search for Claude Led to a macOS
    Infostealer'
  url: https://www.huntress.com/blog/fake-claude-macsync
related:
- hunt: macsync-persistence-macho-rat
  reason: This hunt focuses on the initial delivery and in-memory theft; long-term
    persistence via Mach-O RATs and LaunchAgents is a separate stage of the kill chain.
  relation: out-of-scope-alternative
scenario:
  stages:
  - name: ClickFix Malvertising Lure
    observables:
    - curl -sL [URL] | zsh
    - claude.ai/share/
    - Google Ads sponsored search for 'Claude Code'
    - Display name 'Apple Support'
    slug: initial-access-clickfix-lure
    tactic: initial-access
    techniques:
    - T1566.002
    - T1204.002
    - T1059.004
  - name: Background ZSH Loader
    observables:
    - daemon_function
    - Base64 encoded gzip heredoc
    - /tmp/osalogging.zip
    slug: background-zsh-loader
    tactic: execution
    techniques:
    - T1027
    - T1140
    - T1059.004
  - name: Dynamic AppleScript Stealer
    observables:
    - osascript in-memory execution
    - Chromium Safe Storage AES key extraction
    - TCC prompt for Full Disk Access
    - User password phishing prompt
    - Extraction of login keychain secrets
    slug: dynamic-applescript-theft
    tactic: credential-access
    techniques:
    - T1059.002
    - T1555.001
    - T1548.004
  - name: Mach-O RAT and Persistence
    observables:
    - 85.206.161.241:8443
    - WebSocket over TLS
    - LaunchAgent plist creation in Home folder
    - .mpwd credential file
    - .zshrc modification
    slug: persistent-macho-rat
    tactic: persistence
    techniques:
    - T1543.001
    - T1071.001
    - T1573.002
  - name: Screen Recording Permission Capture
    observables:
    - Capture agent binary with blank icon
    - --tcc-only command line flag
    - -o [path] screenshot output
    - TCC Screen Recording prompt
    slug: screen-capture-helper
    tactic: collection
    techniques:
    - T1113
    - T1548.004
  - name: Crypto Wallet Trojanization
    observables:
    - Modification of 60+ wallet extensions
    - Trojanized Ledger Wallet app
    - Fake recovery phrase phishing HTML
    - Targeting of 21 desktop wallet apps
    slug: wallet-app-trojanization
    tactic: impact
    techniques:
    - T1539
    - T1552
    - T1491
  summary: A malvertising campaign for 'Claude Code' lures users to a legitimate shared
    conversation on claude.ai that instructs them to run a curl one-liner. This executes
    a multi-stage infection chain involving a background zsh loader, a dynamic AppleScript
    stealer that harvests credentials and keychain data, and a persistent Mach-O RAT.
    The attack concludes by gaining screen recording permissions and trojanizing crypto
    wallet applications to phish for recovery phrases.
series:
  index: 1
  slug: macsync-stealer-how-a-google-search-for-claude-led-to-a-macos-infostealer
  title: 'MacSync Stealer: How a Google Search for Claude Led to a macOS Infostealer'
  total: 2
severity: high
targets:
  analyst:
    name: Tier-2 analyst
    role: analyst
  endpoint:
    category: endpoint
    name: Endpoint telemetry (hb_ surfaces)
    telemetry:
    - endpoint
  hunter:
    agent: true
    name: Hunt agent
tlp: clear
type: investigation
---


# MacSync Scripted Execution and Credential Theft

This hunt identifies the early stages of a MacSync Stealer infection by looking for the initial scripted delivery and the subsequent in-memory AppleScript execution used for credential theft. It uses a gated approach, first identifying suspicious curl-to-shell patterns before performing a fan-out investigation for in-memory script logic and exfiltration staging files. The hunt focuses on developer environments where AI tools like Claude are common lures.

## scoping-ai-software
<!-- Identify hosts with AI software -->
Find macOS hosts running AI-related tools that match the malvertising campaign lures.

```sqlite target=endpoint role=scoping params=(ai_keywords=ai_keywords)
~~~yaml
expected: A list of hostnames to focus the hunt on. Silence means no known AI software
  matches were found.
reads:
- device_hostname
- package_name
- vendor_name
silence: not_evidence_of_absence
source: hb_software_inventory
verified: dry-run
verified_at: '2026-09-20'
~~~
SELECT device_hostname, package_name, vendor_name FROM hb_software_inventory WHERE (instr(',' || '{{ai_keywords}}' || ',', ',' || LOWER(package_name) || ',') > 0 OR instr(',' || '{{ai_keywords}}' || ',', ',' || LOWER(vendor_name) || ',') > 0)
```

## curl-to-shell-lead
<!-- Suspicious curl-to-shell lead -->
Identify the primary ClickFix delivery mechanism where curl pipes content directly to a shell interpreter.

```sqlite target=endpoint role=detection-candidate params=(lookback_days=lookback_days, scope_hosts=scope_hosts)
~~~yaml
expected: Process events showing one-liner scripted execution. Silence proof that
  no such command ran within the retention window.
reads:
- device_hostname
- process_name
- process_cmd_line
- time
silence: not_evidence_of_absence
source: hb_process_activity
verified: dry-run
verified_at: '2026-09-20'
~~~
SELECT device_hostname, process_name, process_cmd_line, time FROM hb_process_activity WHERE (LOWER(process_cmd_line) LIKE '%curl %' AND (LOWER(process_cmd_line) LIKE '%|%zsh%' OR LOWER(process_cmd_line) LIKE '%|%sh%')) AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days')
```

## assess-curl-lead
<!-- Assess lead suspicion -->
```agent target=hunter
cite: required
context:
- curl-to-shell-lead
max_iterations: 3
objective: Judge whether the curl-to-shell commands are consistent with malvertising
  ClickFix lures, noting any suspicious parent processes or arguments.
success_criteria: A verdict of malicious | suspicious | benign citing specific process
  command lines.
tools:
- endpoint
```

## gate-on-curl
<!-- Gate on suspicious execution -->
if~: "the assess-curl-lead verdict is suspicious or malicious for at least one host" (confidence: high, judge=hunter)
then: → parallel-investigation
indeterminate: → analyst-final-review
unavailable: → analyst-final-review (blind_spot: process-history-retention)
else: → close-out-benign

## parallel-investigation
<!-- Parallel evidence gathering -->
parallel:
- → macsync-script-logic
- → staging-file-activity
join: → triage-macsync

## macsync-script-logic
<!-- MacSync in-memory script logic -->
Identify the rare background daemon functions and AppleScript keychain theft logic.

```sqlite target=endpoint role=baseline params=(lookback_days=lookback_days, scope_hosts=scope_hosts)
~~~yaml
baseline:
  compare: first_seen
  window: '{{lookback_days}}d'
expected: Rare scripts containing MacSync core logic. Silence suggests no scripted
  theft was captured.
prevalence:
  by: device_hostname
  key:
  - script_content
  rare_below: 3
reads:
- device_hostname
- script_content
- time
silence: not_evidence_of_absence
source: hb_script_activity
verified: dry-run
verified_at: '2026-09-20'
~~~
SELECT device_hostname, script_content, time FROM hb_script_activity WHERE (LOWER(script_content) LIKE '%daemon_function%' OR LOWER(script_content) LIKE '%osascript%') AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days') GROUP BY script_content HAVING COUNT(DISTINCT device_hostname) <= 3
```

## staging-file-activity
<!-- Exfiltration staging file -->
Find the creation of the specific /tmp/osalogging.zip archive used to stage stolen loot.

```sqlite target=endpoint role=enrichment params=(lookback_days=lookback_days, scope_hosts=scope_hosts)
~~~yaml
expected: Records of the staging zip file being created or modified. Silence means
  the file was not created or has already been removed.
reads:
- device_hostname
- file_path
- activity_name
- time
silence: not_evidence_of_absence
source: hb_file_activity
verified: dry-run
verified_at: '2026-09-20'
~~~
SELECT device_hostname, file_path, activity_name, time FROM hb_file_activity WHERE LOWER(file_path) = '/tmp/osalogging.zip' AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days')
```

## triage-macsync
<!-- Triage infection evidence -->
```agent target=hunter
cite: required
context:
- assess-curl-lead
- macsync-script-logic
- staging-file-activity
max_iterations: 6
objective: Analyze the combined results of the curl lead, the rare daemon script logic,
  and the staging file creation to confirm a successful MacSync infection.
success_criteria: A verdict of malicious | suspicious | benign citing relevant telemetry
  across all steps.
tools:
- endpoint
```

## route-infection
<!-- Route based on infection status -->
if~: "the triage-macsync verdict is malicious for at least one host" (confidence: high, judge=hunter)
then: → isolate-and-remediate
indeterminate: → analyst-final-review
unavailable: → analyst-final-review (blind_spot: script-logging-disabled)
else: → close-out-benign

## isolate-and-remediate
<!-- Isolate and remediate host -->
```action target=endpoint
~~~yaml
approval: required
~~~
Isolate the endpoint from the network. Kill any active zsh processes with daemon_function logic. Remove the staging file at /tmp/osalogging.zip. Prompt the user for an immediate password reset and session revocation.
```
→ analyst-final-review

## analyst-final-review
<!-- Analyst final review -->
```manual target=analyst
Review the telemetry for the affected hosts. Confirm if the user actually clicked 'Allow' on the TCC prompts mentioned in the report. Check for any follow-on RAT persistence that may have survived the cleanup.
```
→ close-out-benign

## close-out-benign
<!-- Close out hunt -->
```manual target=analyst
Log the examined hosts and the time window. Note any visibility gaps in script or process logging for future remediation.
```
→ end

Run it

Take this hunt into your environment.

Open it in Huntbase to run every step against your own connections, with Scout weighing the evidence and your analysts in command. Or take the open hunt.md file anywhere that reads the format.

Machine-drafted by huntbase-hunt-generation using hb_google/gemini-3-flash-preview, gated by dry-run, lint, then reviewed by a person.