muaddib-scanner 2.11.32 → 2.11.34
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/package.json +1 -1
- package/{self-scan-v2.11.32.json → self-scan-v2.11.34.json} +1 -1
- package/src/rules/index.js +13 -0
- package/src/scanner/ast-detectors/constants.js +8 -1
- package/src/scanner/ast-detectors/handle-call-expression.js +25 -0
- package/src/scanner/dataflow.js +6 -0
- package/src/scanner/temporal-ast-diff.js +6 -1
package/package.json
CHANGED
package/src/rules/index.js
CHANGED
|
@@ -685,6 +685,19 @@ const RULES = {
|
|
|
685
685
|
references: ['https://attack.mitre.org/techniques/T1036/009/'],
|
|
686
686
|
mitre: 'T1036.009'
|
|
687
687
|
},
|
|
688
|
+
silent_stealth_process: {
|
|
689
|
+
id: 'MUADDIB-AST-092',
|
|
690
|
+
name: 'Silent Stealth Background Process',
|
|
691
|
+
severity: 'CRITICAL',
|
|
692
|
+
confidence: 'high',
|
|
693
|
+
description: 'spawn/fork avec {detached: true, stdio: \'ignore\'} — combinaison qui detache le processus ET silence tous ses I/O. Signal de stealth specifique aux payloads installes via lifecycle (Shai-Hulud) qui doivent survivre a npm install sans laisser de trace dans les logs.',
|
|
694
|
+
references: [
|
|
695
|
+
'https://github.com/DataDog/guarddog/blob/main/guarddog/analyzer/sourcecode/npm-silent-process-execution.yml',
|
|
696
|
+
'https://attack.mitre.org/techniques/T1036/009/',
|
|
697
|
+
'https://attack.mitre.org/techniques/T1564/'
|
|
698
|
+
],
|
|
699
|
+
mitre: 'T1564'
|
|
700
|
+
},
|
|
688
701
|
dangerous_call_function: {
|
|
689
702
|
id: 'MUADDIB-AST-005',
|
|
690
703
|
name: 'new Function() Constructor',
|
|
@@ -16,7 +16,14 @@ const SENSITIVE_STRINGS = [
|
|
|
16
16
|
'The Second Coming',
|
|
17
17
|
'Goldox-T3chs',
|
|
18
18
|
'/etc/passwd',
|
|
19
|
-
'/etc/shadow'
|
|
19
|
+
'/etc/shadow',
|
|
20
|
+
// F5 — guarddog-inspired cloud credential paths (narrow specific forms
|
|
21
|
+
// only, to keep FP rate flat: .pgpass/.netrc/.boto are NOT added here
|
|
22
|
+
// because legitimate JS DB clients reference them. Those still trigger
|
|
23
|
+
// via dataflow SENSITIVE_PATH_PATTERNS when followed by exfil sinks).
|
|
24
|
+
'.aws/credentials',
|
|
25
|
+
'.docker/config.json',
|
|
26
|
+
'.kube/config'
|
|
20
27
|
];
|
|
21
28
|
|
|
22
29
|
// Env vars that are safe and should NOT be flagged (common config/runtime vars)
|
|
@@ -491,6 +491,31 @@ function handleCallExpression(node, ctx) {
|
|
|
491
491
|
message: `${callName}() with {detached: true} — background process survives parent exit (evasion technique).`,
|
|
492
492
|
file: ctx.relFile
|
|
493
493
|
});
|
|
494
|
+
// F6 — silent_stealth_process: detached + stdio:'ignore' = full I/O
|
|
495
|
+
// silence. Combo is a stronger stealth indicator (Shai-Hulud pattern).
|
|
496
|
+
// Emitted ADDITIONALLY (not replacing) so existing compounds that
|
|
497
|
+
// depend on detached_process (detached_credential_exfil, binary_dropper)
|
|
498
|
+
// continue to fire. Inspired by GuardDog's npm-silent-process-execution.yml.
|
|
499
|
+
const hasStdioIgnore = lastArg.properties.some(p => {
|
|
500
|
+
if (p.key?.type !== 'Identifier' || p.key.name !== 'stdio') return false;
|
|
501
|
+
// stdio: 'ignore'
|
|
502
|
+
if (p.value?.type === 'Literal' && p.value.value === 'ignore') return true;
|
|
503
|
+
// stdio: ['ignore', 'ignore', 'ignore'] — array form, all elements 'ignore'
|
|
504
|
+
if (p.value?.type === 'ArrayExpression' && p.value.elements.length > 0) {
|
|
505
|
+
return p.value.elements.every(el =>
|
|
506
|
+
el?.type === 'Literal' && el.value === 'ignore'
|
|
507
|
+
);
|
|
508
|
+
}
|
|
509
|
+
return false;
|
|
510
|
+
});
|
|
511
|
+
if (hasStdioIgnore) {
|
|
512
|
+
ctx.threats.push({
|
|
513
|
+
type: 'silent_stealth_process',
|
|
514
|
+
severity: 'CRITICAL',
|
|
515
|
+
message: `${callName}() with {detached: true, stdio: 'ignore'} — fully detached silent background process (stealth payload pattern).`,
|
|
516
|
+
file: ctx.relFile
|
|
517
|
+
});
|
|
518
|
+
}
|
|
494
519
|
}
|
|
495
520
|
}
|
|
496
521
|
}
|
package/src/scanner/dataflow.js
CHANGED
|
@@ -1075,6 +1075,12 @@ const SENSITIVE_PATH_PATTERNS = [
|
|
|
1075
1075
|
'.atomic', '.metamask', '.ledger-live', '.trezor',
|
|
1076
1076
|
'.bitcoin', '.monero', '.gnupg',
|
|
1077
1077
|
'_cacache', '.cache/yarn', '.cache/pip',
|
|
1078
|
+
// F5 — guarddog-inspired cloud/DB/HTTP auth file coverage. Substring
|
|
1079
|
+
// match means '.docker/config' catches '.docker/config.json'. Narrow
|
|
1080
|
+
// patterns (.pgpass/.netrc/.boto) are unique filenames — FP-safe.
|
|
1081
|
+
'.docker/config', '.kube/config',
|
|
1082
|
+
'.pgpass', '.netrc', '.boto',
|
|
1083
|
+
'.azure/', '.gcloud/', '.config/gcloud/',
|
|
1078
1084
|
// P6: Removed discord, leveldb — data directories, not credential paths.
|
|
1079
1085
|
// _cacache/.cache kept — real cache poisoning vectors (T1195.002).
|
|
1080
1086
|
'/proc/mem', '/proc/self', // v2.10.11: runner secret extraction from process memory (TeamPCP Trivy stealer)
|
|
@@ -16,7 +16,12 @@ const METADATA_TIMEOUT = 10_000;
|
|
|
16
16
|
|
|
17
17
|
const SENSITIVE_PATHS = [
|
|
18
18
|
'/etc/passwd', '/etc/shadow', '.env', '.npmrc', '.ssh',
|
|
19
|
-
'.aws/credentials', '.bash_history', '.gitconfig'
|
|
19
|
+
'.aws/credentials', '.bash_history', '.gitconfig',
|
|
20
|
+
// F5 — guarddog-inspired cloud/DB/HTTP auth files (newly-introduced
|
|
21
|
+
// access to any of these via a version bump is a strong temporal signal).
|
|
22
|
+
'.docker/config', '.kube/config',
|
|
23
|
+
'.pgpass', '.netrc', '.boto',
|
|
24
|
+
'.azure/credentials', '.gcloud/credentials'
|
|
20
25
|
];
|
|
21
26
|
|
|
22
27
|
// Severity mapping for each pattern
|