Skip to main content

MAL-OBFUS Decode-to-Sink Obfuscation

An encoded blob alone is inert: certificates, data: URIs and base64 assets are normal. The malware signal is code that decodes a blob and feeds the result straight into an execution or dynamic-load sink.

What Vulkro detects​

Every rule needs a sink; entropy alone never fires. const s = atob(dataUrl) or a long literal on its own stays quiet.

  • MAL-OBFUS-001 (High): JS eval(atob(...)), new Function(atob(...)), eval(Buffer.from(<b64>, 'base64').toString(...)); Python exec(base64.b64decode(...)) or an eval over marshal.loads, zlib.decompress, codecs.decode, bytes.fromhex.
  • MAL-OBFUS-002 (High severity, Medium confidence): eval(decodeURIComponent(...)) and the new Function form. decodeURIComponent has benign uses.
  • MAL-OBFUS-003 (Medium): a decode fed to a dynamic-load or network sink: require(atob(...)), import(atob(...)), fetch(atob(...)).
  • MAL-OBFUS-004 (High): a decode fed to another execution sink: child_process.exec and friends, vm.runInThisContext, new vm.Script, string-argument setTimeout / setInterval, new Worker(...).
  • MAL-OBFUS-005 (High or Medium, Medium confidence): decode-then-execute split across statements through a variable. A textual heuristic within one file: no reassignment, scope or alias tracking, and only the identifier as the leading sink argument.
  • MAL-OBFUS-006 (High): eval aliased to a local name and then called, hiding the sink from a naive grep.

How to fix​

  • Decode the literal by hand (never by running it) and read what it does.
  • Replace runtime unpack-and-execute with the code itself or a real module import.

References​

See also: Confidence model.


This page is generated by vulkro rules export <out-dir> from Vulkro's built-in detector catalogue. Edits made by hand are overwritten on the next regeneration.