Files
T
mukul975 c47eed6a64 Production hardening: security fixes, code quality, 724 skills complete
- Fix 25 shell=True subprocess calls with list-based commands
- Fix 49 verify=False in defensive skills (env-var override)
- Add timeout to 231 HTTP/subprocess/socket calls
- Fix 6 SQL injection patterns with whitelist validation
- Replace 8 __import__() with standard imports
- Remove 701 unused imports across 442 files
- Add authorized-testing disclaimers to all offensive skills
- Complete 11 incomplete skill directories
- Expand 10 stub SKILL.md files with full content
- Fix 2 YAML parse errors in frontmatter
- Fix 5 pre-existing syntax errors
- Convert 22 hardcoded paths/ports to environment variables
- Back up 21 redundant skill pairs to .bak
- Fix 2 global declaration errors
- 724/724 skills with full folder anatomy (SKILL.md + agent.py + api-reference.md + LICENSE)
- 0 compile errors across all 724 agent.py files
2026-03-19 13:26:49 +01:00

165 lines
5.6 KiB
Python

#!/usr/bin/env python3
"""Supply chain malware artifact analysis agent.
Analyzes software supply chain compromise indicators including package
integrity, build pipeline artifacts, dependency confusion, and trojanized updates.
"""
import os
import sys
import json
import hashlib
import re
import subprocess
from datetime import datetime
try:
import requests
HAS_REQUESTS = True
except ImportError:
HAS_REQUESTS = False
def compute_hash(filepath):
hashes = {}
for algo in ("md5", "sha1", "sha256"):
h = hashlib.new(algo)
with open(filepath, "rb") as f:
for chunk in iter(lambda: f.read(65536), b""):
h.update(chunk)
hashes[algo] = h.hexdigest()
return hashes
def check_npm_package(package_name):
if not HAS_REQUESTS:
return {"error": "requests not installed"}
url = f"https://registry.npmjs.org/{package_name}"
try:
resp = requests.get(url, timeout=15)
resp.raise_for_status()
data = resp.json()
latest = data.get("dist-tags", {}).get("latest", "")
versions = list(data.get("versions", {}).keys())
maintainers = data.get("maintainers", [])
return {
"name": package_name, "latest": latest,
"version_count": len(versions),
"maintainers": [m.get("name") for m in maintainers],
}
except requests.RequestException as e:
return {"error": str(e)}
def check_pypi_package(package_name):
if not HAS_REQUESTS:
return {"error": "requests not installed"}
url = f"https://pypi.org/pypi/{package_name}/json"
try:
resp = requests.get(url, timeout=15)
resp.raise_for_status()
data = resp.json()
info = data.get("info", {})
return {
"name": info.get("name"), "version": info.get("version"),
"author": info.get("author"),
"release_count": len(data.get("releases", {})),
}
except requests.RequestException as e:
return {"error": str(e)}
def detect_typosquat_packages(target_name):
permutations = set()
for i in range(len(target_name)):
permutations.add(target_name[:i] + target_name[i+1:])
for i in range(len(target_name) - 1):
swapped = list(target_name)
swapped[i], swapped[i+1] = swapped[i+1], swapped[i]
permutations.add("".join(swapped))
permutations.add(target_name.replace("-", "_"))
permutations.add(target_name.replace("_", "-"))
permutations.discard(target_name)
return sorted(permutations)
def analyze_package_scripts(package_json_path):
with open(package_json_path, "r") as f:
pkg = json.load(f)
findings = []
scripts = pkg.get("scripts", {})
for hook in ["preinstall", "postinstall", "preuninstall"]:
if hook in scripts:
cmd = scripts[hook]
findings.append({
"type": "install_hook", "hook": hook, "command": cmd[:200],
"severity": "HIGH" if any(s in cmd.lower() for s in
["curl", "wget", "eval", "exec", "base64"]) else "MEDIUM",
})
deps = {**pkg.get("dependencies", {}), **pkg.get("devDependencies", {})}
for dep, ver in deps.items():
if ver.startswith("http") or ver.startswith("git"):
findings.append({
"type": "url_dependency", "package": dep,
"source": ver[:200], "severity": "HIGH",
})
return {"name": pkg.get("name"), "findings": findings}
def analyze_python_setup(setup_py_path):
with open(setup_py_path, "r") as f:
content = f.read()
findings = []
patterns = [
(r"os\.system\(", "os.system() execution"),
(r"subprocess\.", "subprocess execution"),
(r"exec\(", "exec() code execution"),
(r"eval\(", "eval() code execution"),
(r"base64\.b64decode", "Base64 decoding"),
(r"socket\.", "Network socket usage"),
]
for pattern, description in patterns:
if re.search(pattern, content):
findings.append({
"type": "suspicious_setup_code",
"pattern": description, "severity": "HIGH",
})
return {"file": setup_py_path, "findings": findings}
if __name__ == "__main__":
print("=" * 60)
print("Supply Chain Malware Artifact Analysis Agent")
print("Package integrity, typosquat detection, install hook analysis")
print("=" * 60)
target = sys.argv[1] if len(sys.argv) > 1 else None
if not target:
print("\n[DEMO] Usage:")
print(" python agent.py <package.json> # Analyze npm package")
print(" python agent.py npm:<package_name> # Check npm registry")
print(" python agent.py pypi:<package_name> # Check PyPI registry")
sys.exit(0)
if target.startswith("npm:"):
pkg_name = target[4:]
print(f"\n[*] Checking npm: {pkg_name}")
info = check_npm_package(pkg_name)
typos = detect_typosquat_packages(pkg_name)
print(json.dumps(info, indent=2))
print(f"\n Potential typosquats: {typos[:10]}")
elif target.startswith("pypi:"):
pkg_name = target[5:]
print(f"\n[*] Checking PyPI: {pkg_name}")
info = check_pypi_package(pkg_name)
print(json.dumps(info, indent=2))
elif os.path.exists(target):
basename = os.path.basename(target)
if basename == "package.json":
result = analyze_package_scripts(target)
elif basename == "setup.py":
result = analyze_python_setup(target)
else:
result = {"file": target, "hashes": compute_hash(target)}
print(json.dumps(result, indent=2))