Malware repo analysis
Skill chenwei791129/agent-skills/skills/malware-repo-analysis
Use when analyzing a third-party git repository for trojans, backdoors, data exfiltration, supply chain attacks, or other malicious code — NOT for finding code vulnerabilities or CVEs. Trigger on: "analyze this repo", "check for malware", "is this safe to use", "supply chain risk", "suspicious package".From its SKILL.md
npx -y skills add chenwei791129/agent-skills --skill malware-repo-analysisAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
12.2 KB, ~3.4k tokens by cl100k_base, as published. Nobody here has run it
Malware Repository Analysis
Overview
Malicious code hides in execution entry points, not business logic. Your job is to find anomalies — abnormal network calls, abnormal execution timing, abnormal obfuscation — not to validate correct logic.
Never conclude "safe." Conclude "no indicators found." Sophisticated attacks (logic bombs, time-triggered backdoors) are invisible to static analysis.
Agent Teams Architecture
Run all phases in parallel using a coordinated Agent Team:
Team Lead (you)
├── analyst-metadata (Phase 1+2: Repo metadata + git history)
├── analyst-entrypoints (Phase 3: Execution entry points — HIGH PRIORITY)
├── analyst-sourcecode (Phase 4a-4g: Source code pattern scan)
├── analyst-deps (Phase 5+6: Dependencies + binary files)
└── analyst-tests (Phase 7: Test + documentation files)
- Team Lead: Creates team, spawns analysts, monitors for critical findings, synthesizes final report.
- Analysts:
general-purposeagents. Each owns one analysis domain. Reports findings via SendMessage.
Workflow
Step 1 — Initial Setup
Before spawning:
- Confirm the repo is accessible locally (or clone it)
- Identify the language/ecosystem (npm, PyPI, Go, Cargo, etc.)
- Note the
{repo-path}and{repo-slug}for team naming
Step 2 — Create Team and Tasks
TeamCreate:
team_name: "malware-{repo-slug}"
description: "Malware analysis for {repo}"
Create one task per analyst using TaskCreate.
Step 3 — Spawn All Analysts in Parallel
Launch all 5 analysts in a single message with run_in_background: true and subagent_type: "general-purpose".
Analyst prompt template:
You are a malware analysis agent on team "{team-name}". Your name is "{analyst-name}".
## Your Task
{paste the relevant phase section verbatim from the skill below}
## Repo Path
{absolute path to cloned repo}
## Instructions
1. Read team config at ~/.claude/teams/{team-name}/config.json to find teammates
2. Claim your task: TaskUpdate (owner={analyst-name}, status=in_progress)
3. Run ALL checks in your assigned phase — do not skip any
4. Mark task complete: TaskUpdate (status=completed)
5. Send findings to team lead via SendMessage
## Output Format
### {Phase Name} Findings
**Red Flags Found:**
| File | Line | Pattern | Description |
|------|------|---------|-------------|
(or "None")
**Suspicious Indicators:**
- (items requiring human review, or "None")
**Notes:**
- (anything unusual that doesn't clearly qualify as above)
Paste the relevant Phase section(s) from below into each analyst's prompt.
Step 4 — Monitor for Critical Findings
If analyst-entrypoints sends a red flag, alert the user immediately — do not wait for other analysts. Entry point red flags are highest-risk.
Step 5 — Synthesize and Cleanup
After all analysts complete:
- Aggregate findings into Risk Assessment Output format (see below)
- Decide if Phase 8 (Dynamic Confirmation) is warranted
- Shut down analysts: SendMessage to each with
type: "shutdown_request"
Analysis Phases
Phase 1+2 — Metadata & Git History [analyst-metadata]
Phase 1 — Repository Metadata (5 min)
Before reading code, establish trust context:
- Account age vs. activity spike (new account + sudden commits = red flag)
- Repo creation date vs. claimed maturity
- Package name vs. repo name mismatch
- Typosquatting: compare against popular packages (reqests, lodahs, coolor)
- Stars/forks ratio abnormalities (bought stars = uniform geographic distribution)
- Verified vs. unverified publisher on registries (npm, PyPI, crates.io)
Phase 2 — Git History Anomalies
git log --oneline --all # volume and time distribution
git log --diff-filter=A --name-only -- '*.sh' '*.py' '*.js' '*.rb' # when scripts were added
git log --all --full-history -- '.git/hooks/*' # git hook modifications
git show <suspicious-commit> --stat # what actually changed
Red flags:
- "Fix typo" commit that modifies crypto or network logic
- Large code dump in a single commit (unreviable "explosion commit")
- Force-push that erases history
- Deleted files re-added with slight modifications
- Commits at unusual times (3am in maintainer's timezone, consistently)
Phase 3 — Execution Entry Points [analyst-entrypoints] ⚠️ HIGH PRIORITY
These run without user consent. Read every line.
| Entry Point | Files to Check |
|---|---|
| Package lifecycle | package.json (preinstall/postinstall/prepare), setup.py/setup.cfg, pyproject.toml [tool.setuptools], Gemfile, build.gradle, pom.xml |
| CI/CD pipelines | .github/workflows/*.yml, .circleci/config.yml, .gitlab-ci.yml, Jenkinsfile, .travis.yml, bitbucket-pipelines.yml |
| Build systems | Makefile, CMakeLists.txt, Dockerfile, docker-compose.yml, Vagrantfile |
| Install scripts | install.sh, bootstrap.sh, configure, pre-commit, .husky/* |
| Git hooks | .git/hooks/*, .githooks/*, any hook config in package.json |
| Editor configs | .editorconfig hooks, .vscode/tasks.json, .vscode/launch.json |
grep -rn "curl\|wget\|fetch\|Invoke-WebRequest\|WebClient" --include="*.yml" --include="*.yaml" --include="*.sh" .
grep -rn "| bash\|| sh\|pipe.*shell\|exec.*curl" .
grep -rn "base64\s*-d\|base64\s*--decode\|atob\|fromBase64" .
Phase 4 — Source Code Pattern Scan [analyst-sourcecode]
Run against all source files, regardless of language.
4a. Dynamic Code Execution
grep -rn "\beval\b\|\bexec\b\|\bexecfile\b" .
grep -rn "Function(" --include="*.js" --include="*.ts" .
grep -rn "reflect\.Value\|unsafe\.Pointer" --include="*.go" .
grep -rn "Runtime\.exec\|ProcessBuilder\|ScriptEngine" --include="*.java" .
grep -rn "require\s*(\s*[^'\"]" --include="*.js" . # dynamic require
4b. Network / Exfiltration
grep -rn "http[s]\?://\|ftp://\|ws[s]\?://" . # hardcoded URLs
grep -rn "socket\|connect\|bind\|listen" .
grep -rn "dns\.\|DNS\.\|nslookup\|dig " . # DNS exfiltration
grep -rn "smtp\|sendmail\|mailer\|email.*send" . # email exfiltration
Combine with 4c — network + credentials = exfiltration.
4c. Credential & Environment Harvesting
grep -rn "process\.env\|os\.environ\|getenv\|ENV\[" .
grep -rn "\.ssh/\|\.aws/\|\.gnupg/\|\.netrc\|\.npmrc" .
grep -rn "AWS_\|GITHUB_TOKEN\|SECRET\|API_KEY\|PASSWORD\|PRIVATE_KEY" .
grep -rn "id_rsa\|id_ed25519\|\.pem\|\.p12\|\.pfx" .
4d. Obfuscation Indicators
grep -rn "base64\|btoa\|atob\|fromCharCode\|charCodeAt" .
grep -rn "\\\\x[0-9a-fA-F]\{2\}\|\\\\u[0-9a-fA-F]\{4\}" . # hex/unicode escape
awk 'length > 500' $(find . -name "*.js" -o -name "*.py") # suspiciously long lines
grep -rn "split.*reverse.*join\|split.*map.*join" --include="*.js" . # string reversal
4e. Persistence Mechanisms
grep -rn "crontab\|/etc/cron\|launchd\|systemd\|rc\.d\|init\.d" .
grep -rn "HKEY_\|Registry\|StartupFolder\|Run.*Registry" . # Windows registry
grep -rn "~/.bashrc\|~/.profile\|~/.zshrc\|/etc/profile" .
grep -rn "chmod.*\+x\|chown\|setuid\|setgid" .
4f. Reverse Shell / Bind Shell
grep -rn "bash -i\|sh -i\|nc -e\|ncat.*-e\|mkfifo\|/dev/tcp" .
grep -rn "pty\.spawn\|pty\.openpty\|pty\.fork" . # Python PTY
grep -rn "powershell.*-enc\|cmd.*\/c\|wscript\|cscript" . # Windows shells
4g. Anti-Analysis / Sandbox Detection
grep -rn "CI\|TRAVIS\|GITHUB_ACTIONS\|CIRCLECI\|JENKINS" . # skip payload in CI?
grep -rn "isDebuggerPresent\|ptrace\|PTRACE_TRACEME" .
grep -rn "vmware\|virtualbox\|sandbox\|/proc/cpuinfo" .
grep -rn "time\.sleep\|setTimeout.*\d\{5,\}" . # long sleep before payload
Phase 5+6 — Dependencies & Binary Files [analyst-deps]
Phase 5 — Dependency Analysis
# Surface-level: look for typosquatting and unusual dependencies
cat package.json | grep -i "dependencies" -A 100
cat requirements*.txt
cat go.mod
cat Cargo.toml
Red flags:
- A math library depending on
axios/requests(no plausible reason) - Check: does this dependency make sense for the library's stated purpose?
Registry vs. source discrepancy: Check if the published package contains files NOT in git. Attackers sometimes inject malicious code at publish time.
# npm: compare published vs source
npm pack --dry-run # what gets published
diff <(npm pack --dry-run 2>&1) <(git ls-files)
Phase 6 — Binary & Non-Source Files
Legitimate libraries rarely need pre-compiled binaries in git.
find . -type f \( -name "*.exe" -o -name "*.dll" -o -name "*.so" -o -name "*.dylib" \) -not -path "./.git/*"
find . -type f \( -name "*.bin" -o -name "*.dat" \) -size +10k -not -path "./.git/*"
file $(find . -type f -not -path "./.git/*") | grep -v "text\|empty\|directory" # unexpected binary type
Phase 7 — Test & Documentation Files [analyst-tests]
Do NOT skip. Tests run during npm test, pytest, go test, cargo test. A posttest hook can also execute.
grep -rn "http\|curl\|fetch\|socket" $(find . -name "*test*" -o -name "*spec*") 2>/dev/null
grep -rn "exec\|eval\|spawn" $(find . -name "*test*" -o -name "*spec*") 2>/dev/null
README with curl ... | bash install instructions should be flagged even if the command looks legitimate.
Phase 8 — Dynamic Confirmation [Team Lead decision]
Only run if Phases 3–6 found indicators. This phase is NOT parallelized.
In an isolated sandbox (no internet, or with full traffic capture):
# Linux: trace syscalls
strace -e trace=network,openat,execve -f ./install.sh 2>&1 | tee trace.log
# Capture all DNS + TCP
tcpdump -i any -w capture.pcap &
# ... run install/build ...
kill %1
strings capture.pcap | grep -E "[a-z0-9.-]+\.(com|net|io|xyz)"
Risk Assessment Output
Structure findings as:
## Malware Analysis Report
### Verdict
[ ] No indicators found
[ ] Suspicious — requires manual review
[ ] High confidence malicious
### Findings
| Severity | File | Line | Pattern | Description |
|---|---|---|---|---|
### Analysis Gaps
- Dynamic analysis not performed (static only)
- [List what was NOT checked and why]
### Recommendation
- Safe to use / Do not use / Use with sandboxing
Common Rationalizations — REJECT THESE
| Rationalization | Why it's wrong |
|---|---|
| "Test files don't run in production" | npm test, pytest, go test all run them. posttest hooks too. |
| "It's a popular library, must be safe" | Event-stream had 2M downloads/week when backdoored. |
| "The code is too complex to hide malware in" | Complexity is a feature of sophisticated attacks, not evidence of safety. |
| "I'll skip binary files, they're probably just assets" | Pre-compiled backdoored binaries are a known supply chain technique. |
| "CI/CD scripts are just build automation" | They execute with full repo access and often have secret access too. |
| "The README looks professional" | Attackers invest in legitimacy. Polish ≠ safety. |
| "git log looks normal" | Force-push can erase history. Check for rebase/squash patterns. |
| "I already checked the main files" | Malware hides in overlooked entry points: git hooks, editor configs, test setup. |
Red Flags Checklist
Stop and escalate if you find ANY of:
curl ... | bashorwget ... | shanywhere in install/CI scriptsevalapplied to externally fetched content- Base64-encoded payload that decodes to executable code
- Network call + credential access in same code path
- Pre-compiled binaries in a source-only library
- Package lifecycle script that does more than build/compile
- Script that detects CI/debugger environment and behaves differently
- Hardcoded IP addresses (not domain names)
- DNS query to a domain with random-looking subdomain (DNS exfiltration)
- Git hooks committed to repo (
.githooks/or configured path) - Dependency with no plausible reason to be included
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.