mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-06-11 13:44:56 +03:00
c47eed6a64
- 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
219 lines
7.8 KiB
Python
219 lines
7.8 KiB
Python
#!/usr/bin/env python3
|
|
"""Ransomware payment wallet blockchain analysis agent.
|
|
|
|
Traces cryptocurrency payment flows from ransomware wallets using public
|
|
blockchain APIs. Identifies transaction patterns, cluster relationships,
|
|
and fund movement to exchanges or mixers.
|
|
"""
|
|
|
|
import json
|
|
import re
|
|
import sys
|
|
|
|
try:
|
|
import requests
|
|
except ImportError:
|
|
print("[!] 'requests' library required: pip install requests")
|
|
sys.exit(1)
|
|
|
|
BLOCKCHAIN_API = "https://blockchain.info"
|
|
BLOCKSTREAM_API = "https://blockstream.info/api"
|
|
|
|
BTC_ADDRESS_REGEX = re.compile(
|
|
r"^(1[a-km-zA-HJ-NP-Z1-9]{25,34}|3[a-km-zA-HJ-NP-Z1-9]{25,34}|bc1[a-z0-9]{39,59})$"
|
|
)
|
|
|
|
KNOWN_RANSOMWARE_WALLETS = {
|
|
"12t9YDPgwueZ9NyMgw519p7AA8isjr6SMw": "WannaCry",
|
|
"13AM4VW2dhxYgXeQepoHkHSQuy6NgaEb94": "WannaCry",
|
|
"115p7UMMngoj1pMvkpHijcRdfJNXj6LrLn": "WannaCry",
|
|
"1Mz7153HMuxXTuR2R1t78mGSdzaAtNbBWX": "DarkSide (Colonial Pipeline)",
|
|
"bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh": "DarkSide",
|
|
}
|
|
|
|
|
|
def validate_btc_address(address):
|
|
"""Validate Bitcoin address format."""
|
|
if BTC_ADDRESS_REGEX.match(address):
|
|
return True
|
|
return False
|
|
|
|
|
|
def query_address_info(address):
|
|
"""Query blockchain.info for address details."""
|
|
url = f"{BLOCKCHAIN_API}/rawaddr/{address}?limit=50"
|
|
resp = requests.get(url, timeout=30)
|
|
resp.raise_for_status()
|
|
data = resp.json()
|
|
return {
|
|
"address": address,
|
|
"total_received_btc": data.get("total_received", 0) / 1e8,
|
|
"total_sent_btc": data.get("total_sent", 0) / 1e8,
|
|
"final_balance_btc": data.get("final_balance", 0) / 1e8,
|
|
"n_tx": data.get("n_tx", 0),
|
|
"transactions": data.get("txs", []),
|
|
}
|
|
|
|
|
|
def query_blockstream_address(address):
|
|
"""Query Blockstream API for address stats (fallback)."""
|
|
url = f"{BLOCKSTREAM_API}/address/{address}"
|
|
resp = requests.get(url, timeout=30)
|
|
resp.raise_for_status()
|
|
data = resp.json()
|
|
chain = data.get("chain_stats", {})
|
|
return {
|
|
"address": address,
|
|
"funded_txo_count": chain.get("funded_txo_count", 0),
|
|
"spent_txo_count": chain.get("spent_txo_count", 0),
|
|
"funded_txo_sum_btc": chain.get("funded_txo_sum", 0) / 1e8,
|
|
"spent_txo_sum_btc": chain.get("spent_txo_sum", 0) / 1e8,
|
|
}
|
|
|
|
|
|
def extract_output_addresses(transactions, source_address):
|
|
"""Extract downstream addresses from transaction outputs."""
|
|
downstream = {}
|
|
for tx in transactions:
|
|
tx_hash = tx.get("hash", "unknown")
|
|
is_outgoing = any(
|
|
inp.get("prev_out", {}).get("addr") == source_address
|
|
for inp in tx.get("inputs", [])
|
|
)
|
|
if not is_outgoing:
|
|
continue
|
|
for out in tx.get("out", []):
|
|
addr = out.get("addr")
|
|
value = out.get("value", 0) / 1e8
|
|
if addr and addr != source_address:
|
|
if addr not in downstream:
|
|
downstream[addr] = {"total_btc": 0, "tx_count": 0, "tx_hashes": []}
|
|
downstream[addr]["total_btc"] += value
|
|
downstream[addr]["tx_count"] += 1
|
|
downstream[addr]["tx_hashes"].append(tx_hash[:16])
|
|
return downstream
|
|
|
|
|
|
def check_known_wallets(address):
|
|
"""Check if address matches known ransomware wallets."""
|
|
if address in KNOWN_RANSOMWARE_WALLETS:
|
|
return {"known": True, "family": KNOWN_RANSOMWARE_WALLETS[address]}
|
|
return {"known": False, "family": None}
|
|
|
|
|
|
def detect_peel_chain(transactions, address):
|
|
"""Detect peel chain pattern in outgoing transactions."""
|
|
outgoing_values = []
|
|
for tx in transactions:
|
|
is_outgoing = any(
|
|
inp.get("prev_out", {}).get("addr") == address
|
|
for inp in tx.get("inputs", [])
|
|
)
|
|
if is_outgoing:
|
|
outputs = [o.get("value", 0) / 1e8 for o in tx.get("out", []) if o.get("addr") != address]
|
|
outgoing_values.extend(outputs)
|
|
|
|
if len(outgoing_values) < 3:
|
|
return {"peel_chain_detected": False, "reason": "Insufficient transactions"}
|
|
|
|
decreasing = sum(1 for i in range(1, len(outgoing_values)) if outgoing_values[i] < outgoing_values[i - 1])
|
|
ratio = decreasing / (len(outgoing_values) - 1) if len(outgoing_values) > 1 else 0
|
|
return {
|
|
"peel_chain_detected": ratio > 0.6,
|
|
"decreasing_ratio": round(ratio, 3),
|
|
"num_outputs": len(outgoing_values),
|
|
}
|
|
|
|
|
|
def analyze_wallet(address):
|
|
"""Full analysis of a ransomware payment wallet."""
|
|
report = {"analysis_type": "Ransomware Payment Wallet Analysis", "address": address}
|
|
|
|
if not validate_btc_address(address):
|
|
report["error"] = f"Invalid Bitcoin address format: {address}"
|
|
return report
|
|
|
|
report["known_wallet_check"] = check_known_wallets(address)
|
|
|
|
try:
|
|
info = query_address_info(address)
|
|
report["wallet_info"] = {
|
|
"total_received_btc": info["total_received_btc"],
|
|
"total_sent_btc": info["total_sent_btc"],
|
|
"final_balance_btc": info["final_balance_btc"],
|
|
"transaction_count": info["n_tx"],
|
|
}
|
|
|
|
downstream = extract_output_addresses(info["transactions"], address)
|
|
report["downstream_addresses"] = {
|
|
"count": len(downstream),
|
|
"top_recipients": sorted(
|
|
[{"address": a, **d} for a, d in downstream.items()],
|
|
key=lambda x: x["total_btc"],
|
|
reverse=True,
|
|
)[:10],
|
|
}
|
|
|
|
for recipient in report["downstream_addresses"]["top_recipients"]:
|
|
match = check_known_wallets(recipient["address"])
|
|
recipient["known_entity"] = match["family"] if match["known"] else "Unknown"
|
|
|
|
report["peel_chain_analysis"] = detect_peel_chain(info["transactions"], address)
|
|
except requests.RequestException as e:
|
|
report["error"] = f"API query failed: {e}"
|
|
try:
|
|
fallback = query_blockstream_address(address)
|
|
report["wallet_info_blockstream"] = fallback
|
|
except requests.RequestException as e2:
|
|
report["fallback_error"] = f"Blockstream fallback also failed: {e2}"
|
|
|
|
return report
|
|
|
|
|
|
if __name__ == "__main__":
|
|
print("=" * 60)
|
|
print("Ransomware Payment Wallet Analysis Agent")
|
|
print("Blockchain tracing, cluster analysis, fund flow mapping")
|
|
print("=" * 60)
|
|
|
|
if len(sys.argv) < 2:
|
|
print("\nUsage:")
|
|
print(" python agent.py <bitcoin_address>")
|
|
print(" python agent.py <bitcoin_address> --deep")
|
|
print("\nExample:")
|
|
print(" python agent.py 12t9YDPgwueZ9NyMgw519p7AA8isjr6SMw")
|
|
sys.exit(0)
|
|
|
|
address = sys.argv[1]
|
|
print(f"\n[*] Analyzing wallet: {address}")
|
|
|
|
report = analyze_wallet(address)
|
|
|
|
known = report.get("known_wallet_check", {})
|
|
if known.get("known"):
|
|
print(f"[!] KNOWN RANSOMWARE WALLET: {known['family']}")
|
|
|
|
info = report.get("wallet_info", {})
|
|
if info:
|
|
print(f"\n--- Wallet Summary ---")
|
|
print(f" Total received: {info.get('total_received_btc', 0):.8f} BTC")
|
|
print(f" Total sent: {info.get('total_sent_btc', 0):.8f} BTC")
|
|
print(f" Balance: {info.get('final_balance_btc', 0):.8f} BTC")
|
|
print(f" Transactions: {info.get('transaction_count', 0)}")
|
|
|
|
ds = report.get("downstream_addresses", {})
|
|
if ds.get("count", 0) > 0:
|
|
print(f"\n--- Top Downstream Recipients ({ds['count']} total) ---")
|
|
for r in ds.get("top_recipients", [])[:5]:
|
|
entity = r.get("known_entity", "Unknown")
|
|
print(f" {r['address'][:20]}... {r['total_btc']:.8f} BTC [{entity}]")
|
|
|
|
peel = report.get("peel_chain_analysis", {})
|
|
if peel.get("peel_chain_detected"):
|
|
print(f"\n[!] Peel chain pattern detected (ratio: {peel['decreasing_ratio']})")
|
|
|
|
if report.get("error"):
|
|
print(f"\n[!] Error: {report['error']}")
|
|
|
|
print(f"\n[*] Full report:\n{json.dumps(report, indent=2, default=str)}")
|