The browser handoff
A familiar checkbox, followed by Terminal
The captured page called itself TrueCheck and presented a clean identity-verification card. A checked “I’m not a robot” box led into four steps: open Spotlight, launch Terminal, paste a token and press Return. The surrounding language promised a secure session and claimed that personal data would never be stored.
Those instructions moved the visitor from a website into a command interpreter. The command observed during the investigation decoded to a request for hxxps://paravbt1[.]zionschoolseymour[.]org/update.sh, with the response passed directly to Bash. Calling that text a token concealed what the action would do.

This is the direct-shell form of the ClickFix / TermFix technique: a browser prompt recruits the visitor to execute attacker-supplied text. The screenshot documents the lure. The recovered scripts explain the machinery investigated behind the command.
Research scope
Where the evidence connects—and where it stops
The analysis record is dated 18 September 2026. It combines the observed command, static deobfuscation, controlled retrieval of module responses and protocol reconstruction. The recovered payloads were retrieved as data and analyzed without execution.
When the original delivery URL was revisited, Cloudflare protection prevented recovery of its payload. The analyzed update.sh came from a same-family specimen. Its relationship to the later chain is consistent with the findings, but byte-for-byte identity with the original download remains unproven.
| Evidence | What it supports |
|---|---|
| Captured TrueCheck page and observed command | The macOS Terminal lure and initial delivery URL. |
| Recovered update.sh | A same-family first stage; the original hosted object was unavailable. |
| Embedded installer and resolver | Decoded directly from that recovered specimen, including its campaign token. |
| bmodule, smodule, lmodule and ledger responses | Recovered from the C2 resolved during analysis; behavior established through examination of those responses. |
| Essential macOS Stealer / Build: NITRO2 | A self-identifying string in the full stealer, rather than an independently established actor attribution. |
The findings describe capabilities in the recovered code. They do not establish that every collection routine succeeded on a particular victim, or identify who operated the infrastructure.

Execution and persistence
A shell bootstrap installs an AppleScript foothold
The recovered first stage is a 17,813-byte, single-line shell script. It contains a Base64-encoded AppleScript installer and invokes osascript on the decoded content. That installer creates ~/Library/LaunchAgents/com.aumshoyxjpylzfbc.plist and loads it with launchctl.
The property list sets both RunAtLoad and KeepAlive to true. Its program arguments invoke Bash, which ultimately decodes and executes an embedded AppleScript resolver. The resulting user-level persistence can restart the chain across login sessions.
The resolver reads a fixed Polygon contract through eth_call, ABI-decodes a returned string and uses it as the current command-and-control hostname. Multiple public RPC services provide fallback paths for the same lookup. That's a deliberate split: the foothold on the machine stays fixed, while the hostname serving it tasks can move.
During the recorded analysis, that lookup returned namanami[.]top. The contract, selector and service endpoints appear in the infrastructure section at the end of this article. They describe the observed configuration at that time.
bmodule
A password prompt becomes part of the backdoor
The 32,934-byte bmodule fingerprints the Mac, resolves its destination, obtains the local username and seeks a usable account password. It uses IOPlatformUUID as the host identifier, with fallback queries through ioreg and system_profiler.
Getting a usable password isn't left to chance. The code checks for a stored value in ~/.passphrase and validates candidates through dscl . authonly. When it needs a credential, it displays a fake System Preferences dialog with a hidden-answer field and repeats the request until validation succeeds. The prompt asks for a password “for continue.”
The initial server check submits the literal body check and expects success. Enrollment includes the host UUID, username, embedded txid token and a connect flag. A newconnect response leads to a write of ~/.txid and a tccutil reset All call. The code then polls for tasks approximately every 60 seconds.
| Task | Requested module | Execution path and role |
|---|---|---|
| runloader | smodule | AppleScript execution of the full NITRO2 stealer. |
| runlight | lmodule | AppleScript execution of the reduced stealer. |
| replacer | ledger | Shell execution of the server response; the recovered response was a no-op. |
| openshell | shell | Shell execution of arbitrary content supplied by the server. |
The 34-byte ledger response redirected output and contained no subsequent commands. Its role in this capture was inert. The surrounding task handler still accepts replacement shell content from the server, so the observed stub describes one response, not a fixed limit on that slot.
smodule and lmodule
Two collection profiles share the same foundation
The full module carries the string Essential macOS Stealer / Build: NITRO2. At 204,196 bytes, it covers browser data, Keychain material, cryptocurrency wallets, Telegram, notes and selected local files. It reuses the password captured by the backdoor.
Chromium-family targets include Chrome, Brave, Edge, Vivaldi, Opera and OperaGX, Yandex, Chromium and several Chrome release channels. Collection routines address cookies, login databases, history, Web Data, IndexedDB and extension storage. Firefox targets include cookies.sqlite, key4.db, logins.json and profile databases.
Native wallet targets include Exodus, Electrum, Atomic, Guarda, Coinomi, Sparrow, Wasabi, Bitcoin Core, Monero, Ledger Live, Trezor Suite and TON Keeper. A separate extension-ID mapping covers browser wallets such as MetaMask, Phantom, Rabby and Coinbase Wallet. These are collection targets identified in code; successful theft depends on the files and access available on the host.
| Collection capability | smodule | lmodule |
|---|---|---|
| Chromium and Firefox profile data | Present | Present |
| Browser Safe Storage secrets | Present | Present |
| login.keychain-db | Present | Present |
| Native wallets and wallet extensions | Present | Present |
| Telegram Desktop tdata | Present | Present |
| Apple Notes titles and plaintext | Present | Not observed |
| Safari Cookies.binarycookies helper | Present | Not observed |
| Desktop / Documents recursive file grabber | Present | Not observed |
The full build invokes the macOS security utility to request browser Safe Storage secrets and includes a fallback path for login.keychain-db. Its local file grabber targets files under 250 KB with a combined 5 MB cap. It also gathers system-profile information and obtains the public IP through api[.]ipify[.]org, a legitimate service.
The recovered lmodule is 173,169 bytes. It retains the common browser, wallet, Keychain and Telegram routines while omitting the broader features marked above in this examined build. Its SHA-256 was not preserved in the supplied analysis record.
Data leaving the host
Archive size changes the upload route
Both modules stage collected material beneath /tmp and use ditto to create a ZIP-compatible archive. The upload is multipart form data with three fields: txid, file and uuid.
| Condition | Destination | Timeout |
|---|---|---|
| Archive at or below 90 MiB | hxxps://namanami[.]top/upload.php | 90 seconds |
| Primary upload throws an error | hxxp://62[.]60[.]226[.]50/upload.php | 3,000 seconds |
| Archive above 90 MiB | hxxp://62[.]60[.]226[.]50/upload.php | 3,000 seconds |
The direct-IP endpoint serves both as an error fallback and as the route for larger archives. Its HTTP scheme also makes the transport distinction relevant when reviewing network evidence.
Upload output is redirected to /tmp/updstat.txt. No cleanup routine was observed after the upload block in the examined module tails. The staging directories, archives and status file are therefore useful forensic leads, although their presence or absence alone cannot prove whether an upload completed.
Defender value
Follow the sequence across process, file and network evidence
The strongest hunting opportunities combine several observations. A user opening Terminal is common. A subsequent chain of decoded AppleScript, new LaunchAgent persistence, password validation, browser-secret access and recurring task requests is much more distinctive.
| Signal | Investigation value |
|---|---|
| New LaunchAgent plus Bash / osascript execution | Correlate the plist creation, load event and process ancestry. RunAtLoad and KeepAlive describe restart behavior. |
| Unexpected dscl authentication checks | Look for password-validation attempts associated with the script chain and fake dialog. |
| tccutil reset All after enrollment | A supporting sequence marker; this reset does not itself grant privacy permissions. |
| Browser Safe Storage and Keychain access | Correlate with archive creation and outbound uploads rather than treating every security utility call as malicious. |
| Polygon contract plus selector | A stable configuration lookup within this specimen even when the returned hostname changes. |
| check / connect / task requests and module verbs | Protocol-level leads where suitable network visibility is available. |
| Multipart upload.php with txid, file and uuid | Correlate with /tmp staging, ditto and the direct-IP fallback. |
For an affected host, response priorities are isolation and evidence preservation: the LaunchAgent, execution history, state files, staged archives and relevant network records. Treat ~/.passphrase and collection archives as sensitive evidence. Browser sessions, the local account credential, Keychain contents and wallets all fall within the exposure assessment suggested by the recovered capabilities.
The architectural finding is durable: persistence retrieves an endpoint, the backdoor accepts tasks, and separate modules perform collection. That division gives the operator room to change the destination and delivered behavior while retaining the local foothold.
Reference material
Recovered samples and local artifacts
Network indicators throughout this article are defanged and non-clickable. Hashes, contract values and local artifact names are preserved for exact matching. No runnable delivery command or encoded payload is included.
| Component | SHA-256 from the analysis record | Size |
|---|---|---|
| update.sh · same-family pivot | 79126547a08a785eb408f9a89660b7954ffc8ec124d8c6173851cf6609b35b28 | 17,813 bytes |
| Embedded installer | 31dc215220db6e5564730c1c909865ae1301e44c7ecc33973901401b0793144d | 13,332 bytes decoded |
| Embedded resolver | c236a4db85d709e89184752f65102349f6a272befd57741cf35b9236028daf08 | Approximately 9.3 KB |
| bmodule | a9383cea53d6c6c3e4a764d23fbd0c1ccf7c010f20624860fed85faf8de71136 | 32,934 bytes |
| smodule | 90b8ec24440b653a13a252b798a6c007b72bf8bc7dd1ad82bf3258edede03c17 | 204,196 bytes |
| lmodule | Hash not retained in the analysis record | 173,169 bytes |
| ledger response | ef94799c12f00235920699106e27d9a45595549845724f3c9dede02aa5b96a06 | 34 bytes |
| Local artifact | Meaning |
|---|---|
| ~/Library/LaunchAgents/com.aumshoyxjpylzfbc.plist | User-level persistence |
| ~/.passphrase | Captured password or nopassphrase marker; sensitive |
| ~/.txid | Campaign token state |
| /tmp/updstat.txt | Upload output |
| /tmp/0efbf27cd4868e7ec13f359f802e3f6e1789747680/ | Full-module staging; sibling .zip archive |
| /tmp/60f00fcbb7084d81530cb1c646a89df81789749401/ | Reduced-module staging; sibling .zip archive |
C2 and infrastructure
A contract lookup separates the foothold from its destination
The resolver queries the contract below with selector 0x2686ecea at the latest block, then ABI-decodes the returned hostname. Here, txid is the campaign’s token field; its name alone does not establish a blockchain transaction identifier.
| Role | Indicator |
|---|---|
| Captured lure | truecheck-identityconfirmationv1[.]pages[.]dev |
| Observed initial delivery | hxxps://paravbt1[.]zionschoolseymour[.]org/update.sh |
| C2 resolved during analysis | namanami[.]top |
| Fallback / large-upload IP | 62[.]60[.]226[.]50 |
| Polygon contract | 0xA3a603F8a454a9c905b4c579Bb72628F7C15C2A0 |
| Function selector | 0x2686ecea |
| Campaign txid token | 962d87b1d1f7791ede110c2fd8061dc7 |
| Protocol phase | Recorded fields or response |
|---|---|
| Health check | check → success |
| Enrollment | uuid, username, txid, connect → connected or newconnect |
| Polling | uuid, username, txid, task → notasks or a task verb |
| Module selection | smodule / lmodule / ledger / shell |
| Upload | Multipart fields: txid, file, uuid |
The embedded RPC fallbacks are polygon[.]drpc[.]org, polygon[.]publicnode[.]com, polygon-mainnet[.]gateway[.]tatum[.]io and tenderly[.]rpc[.]polygon[.]community. These are public infrastructure services used by the resolver; their presence in this chain does not make the services themselves malicious. The same distinction applies to the IP-discovery service.
For hunting, the contract-and-selector pair, task verbs and upload-field combination provide useful continuity across a changing hostname. Attribution and connections to other operations would require additional evidence beyond the recovered chain described here.