Anatomy of a Failed Nation-State Attack: PinpinRAT Analysis

Anatomy of a Failed Nation-State Attack: PinpinRAT Analysis

A sophisticated phishing campaign targeting developers via fake job interviews has been uncovered, utilizing a multi-stage dropper to install a remote-access trojan (RAT) dubbed PinpinRAT. The attack leverages a fake-interview scam, where attackers pose as venture capitalists to lure developers into cloning a malicious repository and running build commands, which triggers a chain of obfuscated payloads that bypasses standard antivirus detection.

The Attack Vector: Social Engineering

The attack begins with a highly targeted social engineering effort. Attackers use fabricated personas—posing as representatives from defunct or fake venture capital firms (e.g., "Lua Ventures")—and reach out to developers via email and LinkedIn.

To build trust, the attackers:

  • Use legitimate-looking LinkedIn profiles with impressive but vague credentials.
  • Name-drop early-stage companies to justify the need for advisory work.
  • Conduct actual voice calls with the target, often using excuses like "traveling" to explain away inconsistencies in their accent or camera usage.
  • Target developers based on their public contributions, such as packages published to crates.io.

Technical Breakdown of the PinpinRAT Dropper

The malicious payload is delivered via a TypeScript repository themed as a ferry-ticketing application called "Ticket Harbor." The infection chain is designed to be silent and stealthy, utilizing several layers of obfuscation:

1. Initial Execution

The trap is sprung when the developer runs a typecheck or build command. The process follows this sequence:

  • Postinstall Hooks: Four separate postinstall hooks execute patch-package. One of these hooks runs git update-index --skip-worktree on the patch files, which prevents the modified files from appearing in git status.
  • Payload Injection: A file named typescript+5.9.2.patch injects a self-executing, XOR-decrypted base64 blob into typescript.js and _tsc.js. This stub avoids eval() to bypass malware detection.

2. Second-Stage Loading

The initial stub reads a hidden chunk of data appended to an image file (operators/3.png). This data contains a small embedded WebAssembly (WASM) stub in a custom wAsm chunk. The WASM stub then spawns a detached, silent Node.js process that carries a 1.68 MB obfuscated second-stage payload.

3. Persistence and Cleanup

The malware employs three layers of cleanup to avoid detection:

  • The git skip-worktree trick hides the patches.
  • The dropper rewrites the patch files to delete its own injected lines after the first execution.
  • The second-stage temporary directory self-deletes upon execution.

PinpinRAT Capabilities

PinpinRAT is a full-featured remote-access trojan. It uses RSA-2048 for key exchange and AES-256-CBC for session encryption, ensuring all traffic is encrypted with an HMAC-SHA256 integrity tag.

Upon startup, the RAT harvests the following host fingerprint:

  • Primary and all network interface IP addresses.
  • Username, hostname, and OS details (release, platform, architecture).
  • Process PID and full process.argv.
  • Node.js version.

The attacker can issue the following commands to the compromised host:

  • env: Exfiltrate all environment variables.
  • upload: Read and exfiltrate arbitrary files.
  • download: Write attacker-supplied bytes to any path.
  • spawn: Execute arbitrary processes with shell expansion.
  • ls, cd, pwd, cp, mv: Full filesystem manipulation.
  • dns: Use the host as a resolver for arbitrary names (potentially for DNS tunneling).
  • dismantle: Self-removal of the malware.

Indicators of Compromise (IoCs)

If a system is suspected of being infected, the following indicators should be checked:

  • C2 Server: 89.124.107.161:80
  • Windows Scheduled Task: PinpinWrappedJs
  • macOS Process Masquerade: com.apple.WebKit.Networking
  • Environment Variables: NODT_PAYLOAD_PATH, NODT_PAYLOAD_ARGS
  • PNG Chunk Guard: WASMPACK (wAsm)
  • Anchor Strings: 12ff4b51, ticket-harbor-tsc-shim-anchor (found in typescript.js)
  • Artifact Directories:
    • macOS: ~/Library/Caches/runtime-cache/.cache-<randomhex>/
    • Linux: /tmp/.cache-<randomhex>/
    • Windows: %TEMP%\.cache-<randomhex>\

Expert Analysis and Mitigations

Community discussion suggests this attack pattern is highly reminiscent of the Lazarus Group, known for targeting developers via LinkedIn and job interview scams.

To mitigate these risks, developers should adopt the following security practices:

  • Use Ephemeral Environments: Never run untrusted code from a job interview or external source on a personal or corporate machine. Use disposable virtual machines (VMs) or sandbox containers.
  • Use Restricted Runtimes: Utilize tools like Deno's network blocking/whitelisting or Bun's --ignore-scripts flag to prevent malicious postinstall hooks from executing.
  • Use Supply Chain Tools: Employ package managers like pnpm that have made strides in supply chain security.
  • Skepticism of LLM-generated Content: Be aware that attackers are now using LLMs to create highly convincing, professional-sounding phishing emails and LinkedIn profiles.

Sources