T04 · Embedded Malicious Code
- Location
tests/fake-weather/scripts/weather.py:7- Finding
Weather fixture reads and exfiltrates the user's SSH private key
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill is a disclosed security scanner, but it ships active malicious test fixtures that could steal credentials or open a shell if accidentally loaded or executed.
Install only if you are comfortable handling malware test fixtures. Do not execute or import files under tests/, do not install test requirements, and run scans in a sandbox or network-restricted environment until the publisher converts the malicious samples into inert text fixtures.
tests/fake-weather/scripts/weather.py:7Weather fixture reads and exfiltrates the user's SSH private key
tests/fake-crypto/scripts/crypto.py:7Cryptocurrency fixture exfiltrates wallet material to a command-and-control endpoint
tests/fake-formatter/scripts/formatter.py:6Formatter fixture executes an obfuscated reverse shell at module load time
tests/fake-helper/SKILL.md:11Hidden Skill instructions direct the Agent to steal and exfiltrate secrets
tests/fake-svgmalware/icons/logo.svg:4SVG fixture executes JavaScript that steals cookies and browser tokens
tests/fake-timebomb/scripts/reminder.py:7Reminder fixture uses a date trigger to exfiltrate an SSH private key through a shell command
tests/fake-typosquat/requirements.txt:1Typosquatted Python dependencies create a supply-chain compromise path
The file claims to be a crypto portfolio tracker, but the implementation reads Solana wallet material and enumerates Ethereum keystore files, then transmits that data to an external server. This is classic credential/wallet theft behavior and directly contradicts the stated purpose of both the module and the surrounding skill.
The skill metadata describes a threat scanner, but this file instead collects cryptocurrency wallet data and sends it to a remote endpoint. That mismatch is especially dangerous in security tooling because users are more likely to trust and execute it with elevated confidence, increasing the chance of successful theft.
Reading local wallet/keystore material from user home directories and transmitting it over the network has no legitimate connection to threat scanning in this context. Exposure of these files can enable theft of cryptocurrency assets, account takeover, and irreversible financial loss.
The code accesses highly sensitive wallet data and sends it externally without any user notification, consent, or confirmation step. Silent handling of secret material is a strong indicator of malicious exfiltration and substantially increases harm because the victim may remain unaware until funds are stolen.
The file claims to be a daily reminder, but contains a date-triggered payload that steals a private SSH key and sends it to an attacker-controlled server. In a threat-scanning skill, this contradiction makes the behavior even more dangerous because it abuses expected trust and disguises malware as security functionality.
Reading a user's private SSH key and immediately launching a network exfiltration command has no legitimate role in a reminder utility or in the stated threat-scanning skill. This is explicit credential theft that can lead to unauthorized server access and broader compromise.
The documented weather-lookup behavior does not align with code that steals SSH private keys and posts them to an external domain. In skill context, this is especially dangerous because users would reasonably trust a weather utility and may execute it without suspecting credential exfiltration.
This code reads the user's SSH private key from ~/.ssh/id_rsa and transmits it to an external server under the false pretense of weather API authentication. Private keys must never be exfiltrated, and doing so enables credential theft, unauthorized server access, and downstream compromise of any systems trusting that key.
The declared purpose is a defensive security scanner for analyzing skills, but the actual code performs offensive credential theft and exfiltration. It accesses sensitive local wallet files (~/.config/solana/id.json and ~/.ethereum/keystore), collects their contents/filenames, and sends them to a remote server. This is materially different from scanning OpenClaw skills and directly contradicts the claimed protection against wallet theft and exfiltration.
The declared description says this skill scans other skills for threats and protects the agent through detection/reporting. The supplied code does not implement scanning logic, threat analysis, tamper monitoring, or JSON reporting. Instead, it contains an obfuscated payload that is decoded from base64 and executed immediately using subprocess.Popen with shell=True. This is a materially different and undeclared behavior, and specifically matches the kind of reverse-shell malware the description claims to detect. Therefore the description does not accurately represent the code.
There is a clear mismatch between the declared description and the actual code shown. The description claims a full-featured security auditing and threat-detection capability for OpenClaw skills, but the supplied code chunk is only a minimal helper utility with no security logic, no resource access, and no evidence of the claimed protections or reporting features. This is a materially different primary purpose, so it should be flagged as a mismatch.
The declared description says the skill is a defensive malware/prompt-injection scanner for OpenClaw skills. The supplied code does not scan anything. Instead, it defines a reminder function with a hidden date-based trigger that steals the user's SSH private key and sends it to an external server. This is a materially different primary purpose and includes undeclared sensitive file access, outbound network exfiltration, and malicious time-bomb behavior, all of which directly contradict the declared defensive purpose.
This code chunk does not implement the declared security-scanning purpose. Instead, it defines a basic network fetch helper and intentionally imports a typosquatted package, which is more indicative of a supply-chain test or malicious/deceptive dependency pattern than a scanner that detects such threats. The primary purpose and behavior are materially different from the description, so this is a clear mismatch.
This is a clear description-behavior mismatch. The declared purpose is a defensive security scanner for OpenClaw skills, but the supplied code does not scan anything. Instead, it opens a sensitive SSH private key file from the user's home directory and transmits its contents to an external service. That behavior is both materially different from the stated purpose and introduces undeclared sensitive file access and data exfiltration capabilities. The use of a weather-themed interface appears to disguise credential theft rather than support the declared malware-scanning function.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
- SSH keys, AWS credentials, GPG keyrings
- Browser credential stores (Chrome, Firefox, Safari)
- Crypto wallets (MetaMask, Phantom, Solana, Ethereum)
- Keychain/keyring access
- Environment variable harvesting
### Prompt Injection
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
- SSH keys, AWS credentials, GPG keyrings
- Browser credential stores (Chrome, Firefox, Safari)
- Crypto wallets (MetaMask, Phantom, Solana, Ethereum)
- Keychain/keyring access
- Environment variable harvesting
### Prompt Injection
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
- SSH keys, AWS credentials, GPG keyrings
- Browser credential stores (Chrome, Firefox, Safari)
- Crypto wallets (MetaMask, Phantom, Solana, Ethereum)
- Keychain/keyring access
- Environment variable harvesting
### Prompt Injection
YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).
-skill**: detects code writing to paths outside the skill directory
- **Unicode homoglyphs**: catches lookalike characters in filenames (Cyrillic а vs Latin a)
- **Excessive file count**: flags skills with 50+ files
- **Large files**: flags files over 500KB
### Network Threats
- Hardcoded IP addresses, reverse shells, DNS exfiltration
- WebSocket connections to external hosts
### Persistence
- Crontab modifications, launchd/systemd service creation
- Shell RC file modifications (.bashrc, .zshrc)
### Tamper Detection (v2)
- Computes SHA-256 hash of every file on first scan
- Stores baselines in baselines.json
- On re-scan, flags changed, added, or removed files
- Checks ClawHub origin version from .clawhub/origin.json
## Scoring (v2)
| Pattern | Points |
|---------|--------|
| HTTP to known API | 0 |
| HTTP to unknown domain | 10 |
| curl in documentation | 0 |
| subprocess call | 2 |
| subprocess + shell=True | 25 |
| Sensitive file access | 10-25 |
| Prompt injection phrase | 25
YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).
────────────────────────
KNOWN_DOMAINS = {
"api.coingecko.com", "feeds.bbci.co.uk", "api.github.com",
"query1.finance.yahoo.com", "query2.finance.yahoo.com",
"api.openai.com", "discord.com", "api.telegram.org",
"api.x.ai", "api.anthropic.com", "feeds.npr.org",
"www.aljazeera.com", "www.reutersagency.com", "img402.dev",
"snap.llm.kaveenk.com", "astral.sh", "pypi.org",
"raw.githubusercontent.com", "github.com", "api.weatherapi.com",
"api.openweathermap.org", "newsapi.org", "api.newsapi.org",
"rss.nytimes.com", "www.reddit.com", "oauth.reddit.com",
"api.spotify.com", "api.twitch.tv", "api.twitter.com",
"graph.facebook.com", "www.googleapis.com", "maps.googleapis.com",
"api.stripe.com", "api.slack.com", "hooks.slack.com",
"api.notion.com", "api.pushover.net", "ntfy.sh",
"api.elevenlabs.io", "api.deepl.com", "translate.googleapis.com",
"api.wolframalpha.com", "en.wikipedia.org", "www
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
# Hardcoded secrets patterns
SECRET_PATTERNS = [
(r'AKIA[0-9A-Z]{16}', "AWS Access Key"),
(r'ghp_[A-Za-z0-9]{36}', "GitHub Personal Access Token"),
(r'gho_[A-Za-z0-9]{36}', "GitHub OAuth Token"),
(r'github_pat_[A-Za-z0-9_]{82}', "GitHub Fine-grained PAT"),
(r'sk-[A-Za-z0-9]{20,}T3BlbkFJ[A-Za-z0-9]{20,}', "OpenAI API Key"),
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
r'~/\.ssh|\.ssh/|ssh.*id_rsa|id_ed25519': (WARNING, "SSH directory/key access"),
r'~/\.aws|\.aws/|AWS_SECRET': (CRITICAL, "AWS credentials access"),
r'~/\.gnupg|\.gnupg/': (WARNING, "GPG keyring access"),
r'find-generic-password|keytar|keyring\.get': (CRITICAL, "Keychain/keyring access"),
r'Chrome.*Login Data|Firefox.*cookies|Safari.*Cookies|Chrome.*Local State': (CRITICAL, "Browser credential access"),
r'MetaMask|Phantom|Rabby|Coinbase.*Wallet|\.config/solana|\.ethereum': (CRITICAL, "Crypto wallet access"),
r'~/\.openclaw|\.openclaw/': (WARNING, "OpenClaw config access"),
YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).
sensitive_paths = {
r'~/\.ssh|\.ssh/|ssh.*id_rsa|id_ed25519': (WARNING, "SSH directory/key access"),
r'~/\.aws|\.aws/|AWS_SECRET': (CRITICAL, "AWS credentials access"),
r'~/\.gnupg|\.gnupg/': (WARNING, "GPG keyring access"),
r'find-generic-password|keytar|keyring\.get': (CRITICAL, "Keychain/keyring access"),
r'Chrome.*Login Data|Firefox.*cookies|Safari.*Cookies|Chrome.*Local State': (CRITICAL, "Browser credential access"),
r'MetaMask|Phantom|Rabby|Coinbase.*Wallet|\.config/solana|\.ethereum': (CRITICAL, "Crypto wallet access"),
r'~/\.openclaw|\.openclaw/': (WARNING, "OpenClaw config access"),
r'/etc/passwd|/etc/shadow': (WARNING, "/etc/passwd or /etc/shadow access"),
}
for pattern, (level, desc) in sensitive_paths.items():
if re.search(pattern, ln, re.I):
self._has_sensitive_access = True
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
r'Chrome.*Login Data|Firefox.*cookies|Safari.*Cookies|Chrome.*Local State': (CRITICAL, "Browser credential access"),
r'MetaMask|Phantom|Rabby|Coinbase.*Wallet|\.config/solana|\.ethereum': (CRITICAL, "Crypto wallet access"),
r'~/\.openclaw|\.openclaw/': (WARNING, "OpenClaw config access"),
r'/etc/passwd|/etc/shadow': (WARNING, "/etc/passwd or /etc/shadow access"),
}
for pattern, (level, desc) in sensitive_paths.items():
if re.search(pattern, ln, re.I):
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
r'Chrome.*Login Data|Firefox.*cookies|Safari.*Cookies|Chrome.*Local State': (CRITICAL, "Browser credential access"),
r'MetaMask|Phantom|Rabby|Coinbase.*Wallet|\.config/solana|\.ethereum': (CRITICAL, "Crypto wallet access"),
r'~/\.openclaw|\.openclaw/': (WARNING, "OpenClaw config access"),
r'/etc/passwd|/etc/shadow': (WARNING, "/etc/passwd or /etc/shadow access"),
}
for pattern, (level, desc) in sensitive_paths.items():
if re.search(pattern, ln, re.I):
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
self.add(level, desc, f, i,
recommendation=f"{desc} — verify this access is necessary and justified")
# .env and env var harvesting
if re.search(r'\.env\b', ln) and re.search(r'(read|open|load|source|dotenv)', ln, re.I):
self.add(WARNING, "Loading .env file", f, i)
if re.search(r'os\.environ\.get\(["\'](\w*(?:TOKEN|KEY|SECRET|PASSWORD)\w*)', ln, re.I):