macOS.Gaslight — North Korea-Aligned Rust Backdoor & Infostealer

aarch64 ad-hoc-signed Rust implant that masquerades inside Apple's LaunchAgent namespace, exfils over Telegram Bot API, and embeds a prompt-injection blob aimed at LLM-assisted triage. Reported ~2026-06-25.
Threat
macOS.Gaslight (sibling: BONZAI)
Severity
NATION-STATE · ACTIVE
Type
Backdoor / Infostealer (Rust)
Platform
macOS (Apple Silicon arm64 + x86_64)
Attribution
DPRK-aligned (high confidence)
Version
v0.3 · 2026-06-29
Author
HuntPack
Confidence
High (4 corroborating sources)
01

Executive Summary

macOS.Gaslight is a Rust-based macOS backdoor and infostealer attributed with high confidence to North Korea-aligned actors and first reported around 2026-06-25 by SentinelOne Labs. The implant ships as an ad-hoc-signed aarch64 Mach-O, persists as a LaunchAgent whose label com.apple.system.services.activity deliberately impersonates Apple's own namespace, and uses the Telegram Bot API (getUpdates polling) wrapped in AES-GCM over certificate-pinned TLS as its command-and-control channel. Operators drive it with a small verb set — help, id, shell, kill, upload, stop (and an apparent 7th, focus).

The codename "Gaslight" comes from its analyst-deception payload: a 3.5 KB blob of 38 fabricated "system" messages delimited by {{DATA}} tokens, designed to mislead an LLM that ingests the sample during triage. This is a defense-evasion technique aimed at the analyst's tooling, not the sandbox — treat any AI-assisted verdict on this family as untrusted and corroborate with raw telemetry.

The infostealer stage base64-decodes a Python script that downloads a standalone CPython 3.10.18 runtime (from astral-sh/python-build-standalone) into user space and runs it to harvest browser data (Chrome, Brave, Firefox, Safari), terminal histories, the installed-apps list, running processes (ps aux), the system profile (system_profiler), and login.keychain-db, archiving everything to temp/collected_data.zip for exfil.

Defender priority: CrowdStrike Falcon covers macOS. The two highest-fidelity, lowest-FP catches are (1) a LaunchAgent plist written with the com.apple.system.services.activity label outside an Apple-signed installer, and (2) a non-Apple process reading login.keychain-db together with ps aux / system_profiler in a tight window. Hunt those first; the listed SHA256 hashes are exact-match backstops.

02

Source Review & Web Hunter Notes

TierSourceKey FindingCarry Fwd
1 · PrimarySentinelOne Labs — "macOS Gaslight Rust backdoor turns prompt injection on the analyst"Full technical teardown: Rust aarch64 implant, ad-hoc signing identifier, LaunchAgent label, Telegram C2, AES-GCM/cert-pinning, runtime config params, Python infostealer + CPython 3.10.18 staging, keychain harvest, 38-message prompt-injection blob, operator verbs, hashes.Yes
2 · Corrob.The Hacker News — "New Gaslight macOS Malware Uses Prompt Injection"Confirms DPRK attribution, prompt-injection-on-analyst angle, Telegram C2, infostealer scope.Partial
2 · Corrob.Infosecurity Magazine — "macOS Gaslight Rust Backdoor"Corroborates Rust backdoor + infostealer split, sibling "BONZAI" sample, collection targets.Partial
2 · Corrob.CyberPress — "Gaslight Backdoor Misleads Analysts"Reinforces deception payload, operator command set, persistence label.Partial

Web-hunter note: Four sources, one primary vendor teardown plus three corroborating outlets — high confidence. Per the cited intel, the runtime config params (tg_room_id, aes_key, main_base_url, main_upload_url) and bot tokens are NOT embedded in the sample (supplied at runtime; tokens self-redacted as file/token:redacted), so there is no static C2 string or bot token to IOC. Network detection anchors on the Telegram API host. No victim/sector names are reproduced here.

03

Hunt Brief & Attack Chain

Hunt hypotheses (fidelity-ordered)

  1. H1 (high): A LaunchAgent plist carrying the label com.apple.system.services.activity is created by a non-Apple process — Gaslight persistence masquerading in Apple's namespace.
  2. H2 (high): A non-Apple process reads login.keychain-db and, in a tight window, also runs ps aux and system_profiler — the infostealer collection burst.
  3. H3 (high): A standalone python3 / cpython-3.10.18 binary executes from a user-writable path (not /usr/bin) — the downloaded CPython runtime that runs the stealer.
  4. H4 (medium): A shell pipeline base64 -d / base64 --decode feeds decoded content into python3 — staged deobfuscation of the infostealer (T1140).
  5. H5 (medium): A macOS host makes outbound connections to api.telegram.org from a non-browser, non-messaging process — Telegram Bot API C2 polling.
  6. H6 (high): Any process whose image SHA256 matches one of the four listed Gaslight/BONZAI/script hashes — exact-match backstop.

Attack chain

StepBehaviorTelemetryHunt Angle
1 · DeliveryBash installer script drops ad-hoc-signed aarch64 Rust Mach-OProcessRollup2, file writeInstaller script hash; ad-hoc signing identifier
2 · PersistenceLaunchAgent plist label com.apple.system.services.activityFile write to ~/Library/LaunchAgentsH1 — Apple-namespace label from non-Apple writer
3 · Anti-analysis3.5 KB / 38-message prompt-injection blob; dlsym API resolution; IOPMAssertionCreateWithName (no-sleep)Limited EDR signal (in-binary)Distrust LLM verdicts; hash/string hunt
4 · Collectionbase64-decoded Python pulls CPython 3.10.18; harvests browsers, histories, apps, ps aux, system_profiler, keychainProcessRollup2, file readH2/H3/H4 — keychain read + recon burst + standalone python
5 · C2 / ExfilTelegram Bot API getUpdates loop; AES-GCM over pinned TLS; upload collected_data.zipNetworkConnectIP4, DnsRequestH5 — api.telegram.org from non-browser process
04

Consolidated IOC Table

TypeValueConfActionContext
SHA2566328567511d88fdc2ae0939c5ef17b7a63d2a833881900de018a4f12f4982525highdetectPrimary Gaslight Rust implant sample
SHA25677b4fd46994992f0e57302cfe76ed23c0d90101381d2b89fc2ddf5c4536e77cahighdetectSibling "BONZAI" sample
SHA256baabf249c77bc54c54ab0e66e15af798bd28aa5b4683554456a8b73ab8741239highdetectPython infostealer payload script
SHA256b3c56d689414343589f38394d19ba2fe9a518133281200faa0556ba4e4136394highdetectBash installer script
Signing IDendpoint-macos-aarch64-5555494492fc075f441637fb9d894913dde3a2eahighhuntAd-hoc signing identifier of the implant
Persistence labelcom.apple.system.services.activityhighhuntLaunchAgent label masquerading in Apple namespace
Domainapi.telegram.orgmediumhuntTelegram Bot API C2 (legitimate host — context-dependent)
Artifact pathtemp/collected_data.zipmediumhuntStaged collection archive
Runtime stringcpython-3.10.18 (PY_VERSION=3.10.18, BUILD_DATE=20250708)mediumhuntDownloaded standalone CPython used to run the stealer
Config paramstg_room_id, aes_key, main_base_url, main_upload_urlmediumpivotRuntime-supplied config keys (NOT embedded in sample)

Note: No bot token or C2 URL is published — they are self-redacted (file/token:redacted) and supplied at runtime. api.telegram.org is a legitimate host; alert only on the behavioral combination (non-browser/non-messaging process), never on the domain alone.

05

Affected Surface & Telemetry Matrix

SurfaceRequired TelemetryPriorityGap Risk
macOS endpoint — persistenceFalcon macOS file-write events to ~/Library/LaunchAgents (FileCreate/Rename on macOS sensor)P1⚠ macOS plist write fields vary by sensor version — validate in tenant
macOS endpoint — process execProcessRollup2 / SyntheticProcessRollup2 with CommandLine, ImageFileName, SHA256HashDataP1Low
macOS endpoint — keychain readFile-open telemetry on login.keychain-db (macOS sensor)P1⚠ keychain file-read events may not be emitted by default — validate
Network — C2NetworkConnectIP4 + DnsRequest for api.telegram.orgP2TLS-pinned; DNS/host visibility only, no payload
Collection runtimeProcessRollup2 for standalone python3 / cpython-3.10.18 from user-space pathsP2Low
06

ATT&CK Mapping

TacticTechniqueObserved BehaviorDetection / Control
PersistenceT1547.015 — Login Items / LaunchAgentLaunchAgent plist label com.apple.system.services.activityQ1 · H1
Credential AccessT1555 / T1056.004 — keychain harvestReads login.keychain-dbQ2 · H2
CollectionT1005 — Data from Local SystemBrowsers, histories, apps list, ps aux, system_profiler → collected_data.zipQ2 · Q3
Defense EvasionT1140 — Deobfuscate/Decodebase64-decoded Python staging; dlsym runtime API resolutionQ4
ExecutionT1059.006 — PythonDownloaded standalone CPython 3.10.18 runs the stealerQ3
ExfiltrationT1041 — Exfil over C2 ChannelTelegram Bot API getUpdates loop, AES-GCM over pinned TLSQ5
Defense EvasionT1622 / anti-analysis3.5 KB / 38-message prompt-injection blob targeting LLM triageQ6 · hash/string hunt
07

Native Audit-Log Hunts (non-CQL)

Direct host checks that complement the Falcon CQL queries — run on suspect macOS endpoints or fold into an MDM/osquery sweep.

1 · Hunt the masquerading LaunchAgent (read-only)

grep -lR "com.apple.system.services.activity" \
  ~/Library/LaunchAgents /Library/LaunchAgents 2>/dev/null
# Legitimate Apple LaunchAgents live under /System/Library/LaunchAgents and are SIP-protected;
# a plist with this label under a user/Library path is suspicious.

2 · osquery — non-Apple LaunchAgents referencing the label

SELECT name, path, program, program_arguments
FROM launchd
WHERE name LIKE '%com.apple.system.services.activity%'
  AND path NOT LIKE '/System/Library/%';

3 · Find a downloaded standalone CPython runtime in user space

find ~ /Users/Shared /tmp /var/folders -type d -name "cpython-3.10.18*" 2>/dev/null
# astral-sh/python-build-standalone runtime staged outside a developer toolchain is anomalous.

4 · Spot the staged collection archive

find ~ /tmp /var/folders -type f -name "collected_data.zip" 2>/dev/null

Reminder: Do not paste the live sample into an LLM triage tool — the 38-message prompt-injection blob is designed to corrupt AI-assisted verdicts. Corroborate against raw telemetry.

08

CrowdStrike LogScale CQL Hunt Queries

Pick your tenant's cloud first — every "Open in Falcon" button below uses this selection.

All queries target macOS telemetry. Falcon's macOS plist-write and keychain-read field names vary by sensor build — fields flagged below should be validated in your tenant before promotion.

Q1 · LaunchAgent persistence — Apple-namespace label masquerade
CONF HIGHFP LOWCOST LOW

Looks for: a file written to a LaunchAgents directory whose path/name carries the masquerading label com.apple.system.services.activity. Legitimate Apple agents with that string live under SIP-protected /System/Library and are not written by user processes. FP: low — the exact label outside /System/Library is anomalous; exclude approved MDM agents if any reuse the string.

// HUNT: macOS LaunchAgent masquerading as com.apple.system.services.activity
// MITRE: T1547.015
// CONF: high  FP: low  COST: low | REQUIRES: macOS file-write telemetry (LaunchAgents)
// FALSE POSITIVES: approved MDM/EDR agents that reuse the label (rare)
// TUNING: exclude known-good ImageFileName installers if any legitimately write this label
// NOTE: macOS plist-write field set varies by sensor build - validate TargetFileName emission in tenant
#event_simpleName=/NewExecutableWritten|FileRename/
| TargetFileName=/LaunchAgents\/.*com\.apple\.system\.services\.activity.*\.plist$/i
| TargetFileName!=/^\/System\/Library\//
| table([ComputerName, UserName, ImageFileName, TargetFileName, SHA256HashData], limit=200)
Q2 · Keychain harvest + recon burst (ps aux / system_profiler)
CONF HIGHFP MEDCOST MED

Looks for: process execution on macOS that references login.keychain-db, system_profiler, or ps aux in the command line — the infostealer collection burst. Group by host so a single host hitting multiple of these stands out. FP: medium — admins and security tooling run system_profiler/ps aux legitimately; the keychain-db reference is the high-signal discriminator. TUNING: exclude approved asset-inventory and backup agents by ImageFileName.

// HUNT: macOS infostealer collection - keychain + recon command burst
// MITRE: T1555 / T1056.004 / T1005
// CONF: high  FP: medium  COST: medium | REQUIRES: ProcessRollup2 (macOS) CommandLine
// FALSE POSITIVES: admin/IT scripts running system_profiler or ps aux; backup tools touching keychain
// TUNING: exclude approved inventory/backup agents by ImageFileName
#event_simpleName=/ProcessRollup2|SyntheticProcessRollup2/
| CommandLine=/login\.keychain-db|system_profiler|ps\s+aux/i
| table([ComputerName, UserName, ImageFileName, ParentBaseFileName, CommandLine], limit=200)
Q3 · Standalone CPython 3.10.18 runtime executing from user space
CONF HIGHFP MEDCOST LOW

Looks for: a Python interpreter image path containing cpython-3.10.18 (the astral-sh python-build-standalone runtime the stealer downloads), executing from a user-writable location rather than a system path. FP: medium — developers legitimately use python-build-standalone; the discriminator is execution context (paired with Q2/Q5 on the same host) and the exact pinned version. TUNING: exclude developer build roots (e.g. /Users/<user>/.pyenv, project venvs) per environment.

// HUNT: macOS downloaded standalone CPython 3.10.18 running the stealer
// MITRE: T1059.006
// CONF: high  FP: medium  COST: low | REQUIRES: ProcessRollup2 (macOS) ImageFileName
// FALSE POSITIVES: developers using python-build-standalone / pyenv
// TUNING: exclude known dev build roots (.pyenv, project venvs) by path
#event_simpleName=/ProcessRollup2|SyntheticProcessRollup2/
| ImageFileName=/cpython-3\.10\.18.*\/(bin\/)?python3?$/i
| ImageFileName!=/\/\.pyenv\//
| table([ComputerName, UserName, ImageFileName, ParentBaseFileName, CommandLine, SHA256HashData], limit=200)
Q4 · base64-decoded content piped into Python
CONF MEDFP MEDCOST LOW

Looks for: a command line that both decodes base64 (base64 -d / --decode) and invokes python3 — the staged deobfuscation the installer uses to launch the infostealer. FP: medium — some legitimate installers and CI scripts decode-and-run; pair with Q3/Q5 and review the parent process. TUNING: exclude approved CI/build agents by ParentBaseFileName.

// HUNT: macOS base64-decode piped into python (staged deobfuscation)
// MITRE: T1140 / T1059.006
// CONF: medium  FP: medium  COST: low | REQUIRES: ProcessRollup2 (macOS) CommandLine
// FALSE POSITIVES: legitimate installers/CI that decode-and-run
// TUNING: exclude approved CI/build agents by ParentBaseFileName
#event_simpleName=/ProcessRollup2|SyntheticProcessRollup2/
| CommandLine=/base64\s+(-d|--decode)/i
| CommandLine=/python3?/i
| table([ComputerName, UserName, ParentBaseFileName, ImageFileName, CommandLine], limit=200)
Q5 · Telegram Bot API C2 from a non-browser process
CONF MEDFP MEDCOST MED

Looks for: DNS resolution of api.telegram.org on macOS where the requesting process is not a browser or known messaging client — Gaslight's getUpdates polling loop. FP: medium — Telegram desktop and some dev tools legitimately resolve this host; the discriminator is the process context. TUNING: exclude browsers and approved messaging clients by ContextBaseFileName.

// HUNT: macOS Telegram Bot API C2 from non-browser process
// MITRE: T1041 / T1102
// CONF: medium  FP: medium  COST: medium | REQUIRES: DnsRequest (macOS)
// FALSE POSITIVES: Telegram desktop client; dev tooling using the Bot API
// TUNING: exclude browsers + approved messaging clients by ContextBaseFileName
#event_simpleName=DnsRequest
| DomainName=/^api\.telegram\.org$/i
| ContextBaseFileName!=/^(Telegram|Safari|Google Chrome|firefox|com\.apple\.WebKit|Brave Browser)/i
| table([ComputerName, DomainName, ContextBaseFileName, ContextProcessId], limit=200)
Q6 · Known Gaslight / BONZAI / script SHA256 (exact-match backstop)
CONF HIGHFP LOWCOST LOW

Looks for: any process whose image SHA256 matches one of the four published Gaslight/BONZAI/payload-script hashes. Zero-FP exact-match backstop — promote straight to a block IOC. FP: low.

// HUNT: macOS Gaslight known-bad SHA256 (exact match)
// MITRE: T1204 / multiple
// CONF: high  FP: low  COST: low | REQUIRES: ProcessRollup2 (macOS) SHA256HashData
// FALSE POSITIVES: none (exact hash match)
#event_simpleName=/ProcessRollup2|SyntheticProcessRollup2/
| SHA256HashData=/^(6328567511d88fdc2ae0939c5ef17b7a63d2a833881900de018a4f12f4982525|77b4fd46994992f0e57302cfe76ed23c0d90101381d2b89fc2ddf5c4536e77ca|baabf249c77bc54c54ab0e66e15af798bd28aa5b4683554456a8b73ab8741239|b3c56d689414343589f38394d19ba2fe9a518133281200faa0556ba4e4136394)$/i
| table([ComputerName, UserName, ImageFileName, CommandLine, SHA256HashData], limit=200)
09

CrowdStrike Custom IOA Recommendations

IOA NamePlatform / TypePatternActionExclusions
Gaslight — Apple-namespace LaunchAgent masquerademacOS · File Writeplist written to LaunchAgents path with label com.apple.system.services.activityDetect → Block (high conf)Approved MDM agents reusing the label
Gaslight — keychain + recon burstmacOS · ProcessCommandLine references login.keychain-db AND system_profiler/ps aux on same host in short windowDetectApproved inventory/backup agents
Gaslight — standalone CPython 3.10.18 from user spacemacOS · ProcessImageFileName matches cpython-3.10.18 outside dev rootsDetectpyenv / project venvs
Gaslight — base64-decode → pythonmacOS · ProcessCommandLine has base64 -d/--decode AND python3DetectApproved CI/build agents

Promotion path: Q1 and Q6 are clean enough for Detect-and-Block IOAs / IOC import today. Q2–Q5 should run as scheduled-search hunts first, baseline benign triggers for 7–14 days, then promote with the noted exclusions.

10

Machine-Readable IOC Appendix

One-click blocks for SOC ingestion. All atomic indicators below trace to the cited SentinelOne Labs teardown (and corroborating outlets) — no values were invented.

Falcon IOC Management CSVbulk import
type,value,action,severity,expiration,description,tags
sha256,6328567511d88fdc2ae0939c5ef17b7a63d2a833881900de018a4f12f4982525,prevent,critical,2026-12-27,Gaslight Rust implant,campaign:Gaslight
sha256,77b4fd46994992f0e57302cfe76ed23c0d90101381d2b89fc2ddf5c4536e77ca,prevent,critical,2026-12-27,Gaslight BONZAI sample,campaign:Gaslight
sha256,baabf249c77bc54c54ab0e66e15af798bd28aa5b4683554456a8b73ab8741239,prevent,high,2026-12-27,Gaslight Python infostealer,campaign:Gaslight
sha256,b3c56d689414343589f38394d19ba2fe9a518133281200faa0556ba4e4136394,prevent,high,2026-12-27,Gaslight bash installer,campaign:Gaslight
domain,api.telegram.org,detect,medium,2026-09-27,Telegram Bot API C2 (context-only),campaign:Gaslight
Behavioral Signatureshunt logic
LaunchAgent label   : com.apple.system.services.activity (non-/System/Library writer)
Ad-hoc signing ID   : endpoint-macos-aarch64-5555494492fc075f441637fb9d894913dde3a2ea
Collection archive  : temp/collected_data.zip
Runtime CPython     : cpython-3.10.18 (PY_VERSION=3.10.18, BUILD_DATE=20250708)
Recon burst         : login.keychain-db + system_profiler + ps aux
C2 pattern          : api.telegram.org getUpdates polling, AES-GCM over pinned TLS
Runtime config keys : tg_room_id, aes_key, main_base_url, main_upload_url (not embedded)
Anti-analysis       : 3.5KB / 38-message {{DATA}}-delimited prompt-injection blob; dlsym; IOPMAssertionCreateWithName
Named Malware / Toolingtracking
Family       : macOS.Gaslight (Rust backdoor + infostealer)
Sibling      : BONZAI
Platform     : macOS aarch64 (ARM64) + x86_64, ad-hoc signed
Attribution  : North Korea-aligned (high confidence)
C2 transport : Telegram Bot API
Operator cmds: help, id, shell, kill, upload, stop, focus(7th)
Reported     : ~2026-06-25 (SentinelOne Labs)
macOS Hardening / Audit Checklistprevent
[ ] Block the 4 SHA256 via Falcon IOC Management (prevent)
[ ] Alert on non-Apple writers of com.apple.system.services.activity LaunchAgent
[ ] Restrict keychain access; enforce Gatekeeper + require notarization (block ad-hoc signed)
[ ] MDM allowlist LaunchAgents; flag user-Library plists with com.apple.* labels
[ ] Egress policy / DNS logging for api.telegram.org from managed macOS fleet
[ ] Analyst policy: never feed live samples to LLM triage tools (prompt-injection blob)
11

Detection Validation Gates

GateCheckPass Criteria
1 · Telemetry readymacOS sensors emit ProcessRollup2 + DnsRequest; confirm plist-write & keychain-read field availabilityQ1/Q2 fields populate on a test macOS host
2 · Benign baselineRun Q2–Q5 over 7–14 days; catalog admin/dev triggersFP sources enumerated and excluded
3 · Positive testIn a lab: write a benign plist with the target label; run system_profiler+ps aux; resolve api.telegram.org from a scriptQ1/Q2/Q5 fire as expected
4 · PromotionPromote Q1/Q6 to Detect+Block; Q2–Q5 to scheduled-search alerts with exclusionsNo FP in baseline window post-tuning

⚠ Tenant-validation: Falcon macOS field emission for LaunchAgent plist writes and login.keychain-db reads varies by sensor build. Validate that TargetFileName populates for Q1 and that keychain file access is captured before relying on Q2's keychain leg.

12

Hardening — Tiered & Deployable

Immediate (this week)
  • Block the 4 SHA256 via Falcon IOC Management (prevent). MITRE M1040
  • Enforce Gatekeeper + notarization via MDM so ad-hoc-signed binaries (like the Gaslight implant) are blocked from execution. MITRE M1038 · Apple Platform Security
  • Alert on non-Apple writers of LaunchAgents carrying com.apple.* labels (Q1 / IOA). MITRE M1047
Near term (1–4 weeks)
  • MDM-manage LaunchAgents: inventory ~/Library/LaunchAgents across the fleet and flag any plist with an Apple-namespace label outside /System/Library. CIS Apple macOS Benchmark §2 (LaunchAgents)
  • Egress / DNS control for the managed macOS fleet: log and review api.telegram.org resolutions; block from servers/non-user endpoints where Telegram has no business case. MITRE M1037
  • Keychain access policy: monitor and restrict programmatic reads of login.keychain-db; require user presence for keychain unlock. MITRE M1041 · ⚠ best-practice, validate keychain telemetry
Strategic (1–3 months)
  • Application allowlisting on managed macOS (MDM-deployed, signed-binary allowlist) to stop unsigned/ad-hoc Rust implants and user-space CPython runtimes. MITRE M1038 · CIS macOS
  • Analyst tooling policy: codify that live malware samples are never submitted to LLM-assisted triage; route through isolated, non-AI static analysis to neutralize the prompt-injection payload. ⚠ best-practice, no formal benchmark
  • Browser data protection: enforce encrypted profiles / disable plaintext credential storage where supported to blunt the infostealer's browser-harvest stage. MITRE M1027
13

Deployable Playbooks

1 · Fleet sweep — masquerading LaunchAgent (MDM / SSH read-only check)

#!/bin/bash
# Detect Gaslight LaunchAgent persistence across user + /Library scopes (read-only).
LABEL="com.apple.system.services.activity"
for d in /Library/LaunchAgents /Users/*/Library/LaunchAgents; do
  [ -d "$d" ] || continue
  grep -lR "$LABEL" "$d" 2>/dev/null
done
# Any hit OUTSIDE /System/Library is suspicious - legitimate Apple agents are SIP-protected.

2 · Falcon IOC Management — block the published hashes

# Import the CSV from Section 10 (type,value,action,severity,expiration,description,tags)
# via Falcon console: Endpoint security > IOC Management > Add indicators > Upload CSV.
# All four sha256 set to action=prevent. Re-confirm expiration on review (+6mo from 2026-06-27).

3 · MDM configuration profile — require notarization (block ad-hoc signed)

# Gatekeeper assessment must be enabled; deploy via your MDM as a custom profile or
# enforce with the com.apple.systempolicy.control payload. Verify on an endpoint:
spctl --status                 # expect: assessments enabled
spctl -a -vv /path/to/suspect  # ad-hoc signed binaries report "rejected" / no notarization

4 · osquery scheduled pack — staged stealer artifacts

{
  "schedule": {
    "gaslight_cpython": {
      "query": "SELECT path FROM file WHERE path LIKE '/Users/%/cpython-3.10.18%';",
      "interval": 3600
    },
    "gaslight_archive": {
      "query": "SELECT path, size FROM file WHERE filename = 'collected_data.zip';",
      "interval": 3600
    }
  }
}
14

Containment Runbook

PhaseActionsOwnerEvidence to capture
IsolateNetwork-contain the host in Falcon. Do not submit the live sample to any LLM triage tool. Preserve the LaunchAgent plist and collected_data.zip.SOC L2plist path+contents, implant hash, archive, RTR process list
EradicateRemove the masquerading LaunchAgent and implant binary; delete the user-space cpython-3.10.18 runtime and staged archive; kill running implant/python processes.SOC L2 / EndpointRemoved file paths, killed PIDs
Credential resetAssume login.keychain-db + browser credentials are stolen: rotate the user's keychain-stored secrets, browser-saved passwords, SSH keys, and any tokens; force re-auth.IAM / ITReset ticket IDs, rotated secret inventory
RecoverRe-image if implant integrity uncertain. Re-enroll in MDM with notarization enforcement. Sweep fleet with Q1/Q6 + Section 13 scripts.Endpoint / SOCSweep results, clean-state confirmation
Hunt-backPivot on the ad-hoc signing identifier and api.telegram.org context across the fleet; check for lateral movement and additional DPRK tooling.Threat HuntPivot query results, scope determination
15

Detection Coverage Map

TechniqueBehaviorCQLIOACoverage
T1547.015LaunchAgent masquerade labelQ1YesGood
T1555 / T1056.004login.keychain-db harvestQ2YesPartial — keychain read telemetry tenant-dependent
T1005Recon burst (ps aux / system_profiler)Q2YesGood
T1059.006Standalone CPython 3.10.18 executionQ3YesGood
T1140base64 → python deobfuscationQ4YesPartial — FP from CI/installers
T1041 / T1102Telegram Bot API C2Q5NoPartial — TLS-pinned; host/DNS visibility only
T1204 / multipleKnown-bad SHA256Q6YesGood
T1622 / anti-analysisPrompt-injection blob, dlsym, IOPMAssertion no-sleepNoGAP — in-binary; covered only by hash/string + analyst policy

Validation: 6 CQL queries cover 7 of 8 mapped behaviors. Residual gap: the anti-analysis tradecraft (prompt-injection blob, dlsym dynamic resolution, IOPMAssertion sleep-prevention) generates little discrete EDR telemetry and is addressed by the hash backstop (Q6) plus the analyst-tooling policy in Section 12. Validate Q1's TargetFileName emission and Q2's keychain-read leg in your tenant before promoting to Block.

16

Hunt Summary Ticket

TITLE      : macOS.Gaslight - DPRK Rust backdoor / infostealer (anti-AI prompt injection)
SEVERITY   : Critical (nation-state, active, credential theft)
SCOPE      : macOS fleet (Apple Silicon arm64 + x86_64)
HYPOTHESIS : Gaslight persists as a com.apple.* LaunchAgent masquerade, harvests
             login.keychain-db + browser data via a downloaded CPython 3.10.18,
             and exfils over the Telegram Bot API.
QUERIES    : Q1 LaunchAgent masquerade | Q2 keychain+recon burst | Q3 standalone CPython
             Q4 base64->python | Q5 Telegram C2 | Q6 known SHA256 backstop
DO FIRST   : Q1 + Q6 (high conf, low FP) -> block 4 hashes; sweep fleet for the LaunchAgent label
FINDINGS   : <populate from hunt>
GAPS       : Anti-analysis tradecraft (prompt-injection blob/dlsym/IOPMAssertion) = hash + policy only;
             keychain-read + plist-write telemetry tenant-dependent
ACTIONS    : Block hashes | enforce notarization (block ad-hoc) | rotate keychain/browser creds | never LLM-triage live sample
OWNER      : HuntPack
VERSION    : v0.1 - 2026-06-27
17

Changelog

v0.32026-07-24CQL correctness pass. All 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.
v0.22026-06-29CQL syntax review (crowdstrike-logscale-v3): removed invalid FileCreateInfo event (Q1).
v0.12026-06-27Initial HuntPack — 6 CQL queries, 4 IOA recommendations, tiered macOS hardening, containment runbook. Built from SentinelOne Labs teardown + 3 corroborating sources. All atomic IOCs traced to cited intel.
18

References

TierSourceUsed ForAccess Date
1 · PrimarySentinelOne Labs — macOS Gaslight Rust backdoorFull technical teardown, hashes, TTPs, IOCs2026-06-27
2 · Corrob.The Hacker News — Gaslight prompt injectionAttribution, C2, infostealer scope2026-06-27
2 · Corrob.Infosecurity Magazine — macOS Gaslight Rust BackdoorBONZAI sibling, collection targets2026-06-27
2 · Corrob.CyberPress — Gaslight backdoor misleads analystsDeception payload, operator commands, persistence2026-06-27

Generated 2026-06-27 · HuntPack v0.1 · Defensive content only (hunt / detect / harden). All atomic IOCs trace to the cited sources; no indicators were fabricated.