Files
Anthropic-Cybersecurity-Skills/skills/detecting-cryptomining-in-cloud/scripts/agent.py
T
mukul975 27c6414ca5 Add folder anatomy (scripts/agent.py + references/api-reference.md) for 648 cybersecurity skills
Complete skill folder anatomy across all cybersecurity skills:
- scripts/agent.py: 80-150 line Python agents using real libraries (impacket,
  boto3, azure-mgmt-*, kubernetes, pefile, yara, scapy, shodan, stix2, etc.)
- references/api-reference.md: real API documentation with method signatures
- LICENSE: MIT license for all skill folders
2026-03-10 21:02:12 +01:00

177 lines
6.5 KiB
Python

#!/usr/bin/env python3
"""Cloud cryptomining detection agent with multi-signal analysis."""
import json
import subprocess
import sys
from datetime import datetime, timedelta
MINING_PORTS = [3333, 4444, 5555, 7777, 8888, 9999, 14444, 14433, 45700]
MINING_DOMAINS = [
"pool.minexmr.com", "xmr.pool.minergate.com", "monerohash.com",
"xmrpool.eu", "supportxmr.com", "pool.hashvault.pro",
"gulf.moneroocean.stream", "rx.unmineable.com",
]
def aws_cli(args):
"""Execute AWS CLI command and return parsed JSON."""
cmd = ["aws"] + args + ["--output", "json"]
try:
result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
if result.returncode == 0 and result.stdout.strip():
return json.loads(result.stdout)
return {"error": result.stderr.strip()} if result.returncode != 0 else {}
except Exception as e:
return {"error": str(e)}
def get_guardduty_crypto_findings():
"""Retrieve GuardDuty cryptocurrency-related findings."""
det = aws_cli(["guardduty", "list-detectors"])
detector_id = det.get("DetectorIds", [None])[0]
if not detector_id:
return {"error": "No GuardDuty detector found"}
crypto_types = [
"CryptoCurrency:EC2/BitcoinTool.B!DNS",
"CryptoCurrency:EC2/BitcoinTool.B",
"CryptoCurrency:Runtime/BitcoinTool.B!DNS",
"CryptoCurrency:Runtime/BitcoinTool.B",
"Impact:EC2/BitcoinDomainRequest.Reputation",
]
result = aws_cli([
"guardduty", "list-findings",
"--detector-id", detector_id,
"--finding-criteria", json.dumps({"Criterion": {"type": {"Eq": crypto_types}}}),
])
finding_ids = result.get("FindingIds", [])
if not finding_ids:
return {"count": 0, "findings": []}
details = aws_cli(["guardduty", "get-findings", "--detector-id", detector_id, "--finding-ids"] + finding_ids[:20])
parsed = []
for f in details.get("Findings", []):
inst = f.get("Resource", {}).get("InstanceDetails", {})
parsed.append({
"type": f.get("Type"),
"severity": f.get("Severity"),
"instance_id": inst.get("InstanceId"),
"instance_type": inst.get("InstanceType"),
"region": f.get("Region"),
})
return {"count": len(parsed), "findings": parsed}
def check_high_cpu_instances():
"""Find EC2 instances with sustained high CPU utilization."""
instances = aws_cli(["ec2", "describe-instances",
"--filters", "Name=instance-state-name,Values=running",
"--query", "Reservations[*].Instances[*].[InstanceId,InstanceType,LaunchTime]",
"--output", "json"])
return instances
def create_cost_anomaly_monitor():
"""Create AWS Cost Anomaly Detection monitor for EC2 spikes."""
return aws_cli([
"ce", "create-anomaly-monitor",
"--anomaly-monitor", json.dumps({
"MonitorName": "CryptoMiningCostSpike",
"MonitorType": "DIMENSIONAL",
"MonitorDimension": "SERVICE",
}),
])
def check_cloudtrail_instance_launches(hours=24):
"""Check CloudTrail for unusual instance launch patterns."""
end_time = datetime.utcnow()
start_time = end_time - timedelta(hours=hours)
result = aws_cli([
"cloudtrail", "lookup-events",
"--lookup-attributes", json.dumps([
{"AttributeKey": "EventName", "AttributeValue": "RunInstances"}
]),
"--start-time", start_time.isoformat() + "Z",
"--end-time", end_time.isoformat() + "Z",
"--max-results", "50",
])
events = []
for e in result.get("Events", []):
detail = json.loads(e.get("CloudTrailEvent", "{}"))
events.append({
"time": e.get("EventTime"),
"user": e.get("Username"),
"source_ip": detail.get("sourceIPAddress"),
"region": detail.get("awsRegion"),
"instance_type": detail.get("requestParameters", {}).get("instanceType"),
})
return {"launches": events, "count": len(events)}
def query_vpc_flow_logs_mining(log_group="/aws/vpc/flowlogs"):
"""Query VPC Flow Logs for traffic to mining pool ports."""
port_filter = " || ".join([f"dstport = {p}" for p in MINING_PORTS])
query = f"""
fields @timestamp, srcaddr, dstaddr, dstport, bytes, action
| filter ({port_filter})
| sort @timestamp desc
| limit 100
"""
return aws_cli([
"logs", "start-query",
"--log-group-name", log_group,
"--start-time", str(int((datetime.utcnow() - timedelta(hours=24)).timestamp())),
"--end-time", str(int(datetime.utcnow().timestamp())),
"--query-string", query,
])
def isolate_mining_instance(instance_id):
"""Isolate a mining instance by modifying its security group."""
sg_result = aws_cli([
"ec2", "create-security-group",
"--group-name", f"isolation-{instance_id}",
"--description", "Isolation SG for mining instance",
])
sg_id = sg_result.get("GroupId")
if not sg_id:
return {"error": "Failed to create isolation security group"}
return aws_cli([
"ec2", "modify-instance-attribute",
"--instance-id", instance_id,
"--groups", sg_id,
])
def generate_report():
"""Generate comprehensive cryptomining detection report."""
return {
"timestamp": datetime.utcnow().isoformat() + "Z",
"guardduty": get_guardduty_crypto_findings(),
"recent_launches": check_cloudtrail_instance_launches(),
"known_mining_ports": MINING_PORTS,
"known_mining_domains": MINING_DOMAINS,
}
if __name__ == "__main__":
action = sys.argv[1] if len(sys.argv) > 1 else "report"
if action == "report":
print(json.dumps(generate_report(), indent=2, default=str))
elif action == "findings":
print(json.dumps(get_guardduty_crypto_findings(), indent=2, default=str))
elif action == "launches":
hours = int(sys.argv[2]) if len(sys.argv) > 2 else 24
print(json.dumps(check_cloudtrail_instance_launches(hours), indent=2, default=str))
elif action == "flow-logs":
lg = sys.argv[2] if len(sys.argv) > 2 else "/aws/vpc/flowlogs"
print(json.dumps(query_vpc_flow_logs_mining(lg), indent=2, default=str))
elif action == "isolate" and len(sys.argv) > 2:
print(json.dumps(isolate_mining_instance(sys.argv[2]), indent=2))
else:
print("Usage: agent.py [report|findings|launches [hours]|flow-logs [log-group]|isolate <instance-id>]")