Skip to content

Remove obfuscated RCE payload from postcss.config.js and restore .gitignore - #1

Draft
kevpay wants to merge 1 commit into
mainfrom
claude/citizenwallet-malicious-cleanup-bubc6e
Draft

Remove obfuscated RCE payload from postcss.config.js and restore .gitignore#1
kevpay wants to merge 1 commit into
mainfrom
claude/citizenwallet-malicious-cleanup-bubc6e

Conversation

@kevpay

@kevpay kevpay commented Aug 28, 2026

Copy link
Copy Markdown

Summary

postcss.config.js carried an obfuscated JavaScript payload appended after the config, hidden behind a long run of spaces on the closing line so it sits off-screen in an editor. .gitignore was rewritten by the same activity to delete the .env entry and add config.bat.

What the payload does

  • Resolves its C2 endpoint from the Ethereum blockchain (EtherHiding), reading the host from recent transactions of a hardcoded attacker-controlled address via public RPC endpoints (1rpc.io, ethereum-rpc.publicnode.com, eth.drpc.org, public.blastapi.io) and a Blockscout txlist API.
  • Fetches a second stage over HTTP(S) with gzip/deflate/brotli decoding, then runs it two ways: eval() in-process, and a detached spawn(node, ['-e', ...]) with stdio: 'ignore' and windowsHide, unref()'d so it outlives the parent.

postcss.config.js executes on every build and dev server start.

Provenance — worth a close look

This repo shows the campaign most clearly. An older payload variant arrived in 0e5eedc (2025-04-15). Commit 8ed3af6, titled "remove Polin Rider" (2026-05-27), did not remove it — the file goes into that commit carrying the old variant and comes out carrying a newer variant with blockchain-based C2. The cleanup intent was real; the payload was rewritten into the file at commit time.

That points at the committing machine rather than CI, and it means file-level cleanup alone will not hold until that machine is dealt with.

Scope note

This PR cleans the current tip only; the payload remains reachable in history. Ten other org repositories carry the same campaign. Any credentials reachable from an affected machine or CI run should be treated as compromised.


Generated by Claude Code

…ignore

postcss.config.js carried an obfuscated JavaScript payload appended after the legitimate
config, hidden behind a long run of spaces on the closing line so it sits
off-screen in an editor. Restored to its pre-tampering content.

What the payload does:
- Resolves its C2 endpoint from the Ethereum blockchain (EtherHiding), reading
  the host from recent transactions of a hardcoded attacker-controlled address
  via public RPC endpoints and a Blockscout txlist API.
- Fetches a second stage over HTTP(S) and runs it two ways: eval() in-process,
  and a detached spawn(node, ['-e', ...]) with stdio 'ignore' and windowsHide,
  unref'd so it outlives the parent.

postcss.config.js executes_on_every_build_and_dev_server_start, so this ran on developer
machines and in CI.

.gitignore was rewritten by the same commit: line endings converted, the .env
entry deleted, and a config.bat entry added. Removing .env from .gitignore
stages local secrets to become committable. Restored to its pre-tampering
revision.

The payload first arrived in 0e5eedc_(2025-04-15),_and_was_replaced_with_a_newer_variant_by_8ed3af6_("remove_Polin_Rider",_2026-05-27).
@kevpay
kevpay force-pushed the claude/citizenwallet-malicious-cleanup-bubc6e branch from 99e565b to dc0792a Compare September 1, 2026 09:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants