Study material
concept 8 · malware and supply chain

Malicious code and supply chain

This is where real malware lives: payload encoded to become exec, reverse shells, forensic evasion, Unicode steganography, manifest abuse and the exfiltration chain. The rule that ties it all together: a sensitive source plus an outbound channel, coexisting, is already hostile.

In 30 seconds

A payload is hidden inside an encoded string and executed at runtime (decode → exec); the decoder decodes and rescans it. Commands are assembled in pieces (dynamic command) or reverse shells open a channel back to the attacker. Evasion tries to erase itself (self-clean), wait for a date (time-gated) or use invisible Unicode characters to fool the human reader (Trojan Source). In the manifest, postinstall and build.rs scripts run code at install time. And a credential read plus a network channel in the same file is an exfiltration chain.

Recognized attack classes (obfuscated exec chain, remote callback, Unicode obfuscation, build hook, dormant trigger) and the coexistence principle: a sensitive source plus an outbound channel is already hostile.
Recognized attack classes and the coexistence principle: a sensitive source plus an outbound channel is already hostile.

From scratch: the attack classes

Decode → exec: the real code arrives in base64/hex/charCode and only exists after decoding, to escape static analysis. Reverse shell: the victim connects back to the attacker and hands over a shell. Self-clean: the script deletes itself after running, destroying evidence. Time-gated: the trigger is a date or version, staying dormant until the moment. Unicode steganography / Trojan Source (CVE-2021-42574): bidirectional control characters reorder what the compiler executes versus what the human reads. Manifest abuse: lifecycle hooks (postinstall, preinstall, build.rs) execute at install; add typosquatting and registry redirects. Credential harvest + exfil: read a secret and send it out.

Why it matters

These are the vectors that show up in real supply chain incidents (the ClawHub case, the Shai-Hulud that migrated from postinstall to preinstall to reach more machines, the compromised axios). An AI agent that installs dependencies or pastes code from a package is exactly where this gets in. The coverage had to span from the syntactic trick (Unicode) to the attack's business logic (read a secret, open a socket).

How it correlates

The thread is the coexistence principle: no isolated piece needs to be conclusive if the combination is unambiguous. Decode alone can be legitimate; decode that becomes exec is not. Reading ~/.ssh/id_rsa can be a backup; reading it and sending it via fetch is exfiltration. That is why the decoder in the pipeline rescans the revealed content, and the exfil chain requires source and sink together. This connects directly to corroboration: signals that confirm one another.

Two chains: decode-then-exec is confirmatory and blocks alone; the exfiltration chain needs sensitive source plus network sink together, each innocent alone, convicting combined.
The two canonical chains: decode → exec convicts on its own (confirmatory); exfiltration requires source + sink together.

How Nemesis applies it

The decoder performs the decoding and, in the revealed content, looks for deny-list commands, the classic ClawHub vector:

📄 .nemesis/nemesis-defender/src/scanner/decoder.rs:200-217 · payload decodificado vira sinal decode_exec

for &cmd in DECODED_DENY_COMMANDS {
    if decoded_lower.contains(cmd) {
        violations.push(DefenderViolation {
            visitor: "decode_exec".to_string(),
            evidence: format!("encoded payload contains: \"{}\"", cmd.trim()),
            /* "payload codificado decodifica para comando da deny-list" */ });
    }
}

The byte-scanner separates the dangerous Unicode controls (reordering BiDi, Trojan Source) from the weak ones (invisible marks that appear in legitimate text):

📄 .nemesis/nemesis-defender/src/scanner/byte_scanner.rs:17-46 · BiDi perigoso vs fraco (CVE-2021-42574)

const BIDI_DANGEROUS: &[(u32, &str)] = &[
    (0x202E, "Right-to-Left Override"), (0x2066, "Left-to-Right Isolate"), /* ... */ ];
// sem uso legítimo em código → "unicode_bidi" (confirmatório)
const BIDI_WEAK: &[(u32, &str)] = &[ (0x200E, "LRM"), (0xFE0F, "Variation Selector-16"), /* ... */ ];
// aparecem em i18n/emoji → "unicode_zero_width" (corroborante)

The manifest scanner targets lifecycle hooks that execute (with reference attacks annotated):

📄 .nemesis/nemesis-defender/src/scanner/manifest_scanner.rs:1-12 · postinstall / build.rs

//! package.json: postinstall/preinstall/prepare · Cargo.toml: build.rs
//! Shai-Hulud 2.0 (Nov 2025): postinstall → preinstall (mais alcance)
//! axios: postinstall dropou um RAT cross-platform

And the exfiltration chain only fires with a sensitive source and a network sink coexisting, with an allowlist for public env vars to avoid false positives:

📄 .nemesis/nemesis-defender/src/visitors/exfil_chain.rs:192-247 · SOURCE + SINK = malicioso

let (source_evidence, _) = match source_match { Some(p) => p, None => return Vec::new() };
let (sink_evidence, _)   = match sink_match   { Some(p) => p, None => return Vec::new() };
// fonte + sink presentes → exfil chain confirmado (visitor "exfil_chain")

Decisions and limits

The decoder.rs (which runs the decoding) is distinct from visitors/decode_exec.rs (which detects the pattern decode→exec in the AST): two angles of the same vector, separated on purpose. The public-env allowlist (NEXT_PUBLIC_*, CLIENT_ID) was born of real pain in the project: without it, every route handler with a public token plus fetch turned into Malicious. A real secret is not a public env var.

The weak Unicode controls appear in legitimate text (Arabic, Hebrew, emoji); flagging them alone would produce false positives, so they are classified as corroborating, not confirmatory.

Self-check

Why is decode alone not enough, but decode → exec is?

Because decoding data is common and legitimate; executing what was decoded at runtime is the vector for hiding a command from static analysis. The decoder rescans the revealed content to flag exactly that.

What is the rule of the exfiltration chain?

A sensitive source (credential, secret) plus a network sink coexisting in the same file. An isolated source or an isolated sink does not fire; coexistence is the signal.

What is Trojan Source and why is it confirmatory?

It is the use of bidirectional Unicode controls (CVE-2021-42574) so the compiler executes logic the human reads as something else. These controls have no legitimate use in code, so one occurrence already confirms.

Further reading

Citações verificadas contra o repositório. Voltar ao índice.