Skip to content

Remove obfuscated RCE payload from tailwind.config.js and restore .gitignore - #70

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

Remove obfuscated RCE payload from tailwind.config.js and restore .gitignore#70
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

tailwind.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: line endings converted, the .env entry deleted, and config.bat added.

The diff is large because the malicious commit also rewrote both files' line endings; the restored files are the pre-tampering revisions.

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.

tailwind.config.js is loaded on every build and dev server start.

Provenance

The payload arrived in 08c7c74 ("fix wrong return value for update profile action", 2025-09-26), a commit whose stated purpose was unrelated to either file it modified. That points at the committing machine rather than CI.

Scope note

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


Generated by Claude Code

…tignore

tailwind.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.

tailwind.config.js is_loaded_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 08c7c74_("fix_wrong_return_value_for_update_profile_action",_2025-09-26).
@kevpay
kevpay force-pushed the claude/citizenwallet-malicious-cleanup-bubc6e branch from 951cfed to a1aa495 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