mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-06-11 13:44:56 +03:00
27c6414ca5
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
187 lines
6.8 KiB
Python
187 lines
6.8 KiB
Python
#!/usr/bin/env python3
|
|
"""Agent for cloud workload protection on AWS EC2 instances."""
|
|
|
|
import os
|
|
import json
|
|
import time
|
|
import argparse
|
|
from datetime import datetime
|
|
|
|
import boto3
|
|
from botocore.exceptions import ClientError
|
|
|
|
|
|
def get_running_instances(session, filters=None):
|
|
"""List all running EC2 instances."""
|
|
ec2 = session.client("ec2")
|
|
params = {"Filters": [{"Name": "instance-state-name", "Values": ["running"]}]}
|
|
if filters:
|
|
params["Filters"].extend(filters)
|
|
instances = []
|
|
paginator = ec2.get_paginator("describe_instances")
|
|
for page in paginator.paginate(**params):
|
|
for res in page["Reservations"]:
|
|
for inst in res["Instances"]:
|
|
instances.append({
|
|
"instance_id": inst["InstanceId"],
|
|
"type": inst["InstanceType"],
|
|
"ip": inst.get("PrivateIpAddress", ""),
|
|
"launch_time": str(inst["LaunchTime"]),
|
|
})
|
|
return instances
|
|
|
|
|
|
def run_ssm_command(session, instance_ids, commands):
|
|
"""Execute commands on instances via SSM Run Command."""
|
|
ssm = session.client("ssm")
|
|
resp = ssm.send_command(
|
|
InstanceIds=instance_ids,
|
|
DocumentName="AWS-RunShellScript",
|
|
Parameters={"commands": commands},
|
|
TimeoutSeconds=60,
|
|
)
|
|
command_id = resp["Command"]["CommandId"]
|
|
time.sleep(5)
|
|
results = {}
|
|
for iid in instance_ids:
|
|
try:
|
|
output = ssm.get_command_invocation(CommandId=command_id, InstanceId=iid)
|
|
results[iid] = {
|
|
"status": output["Status"],
|
|
"stdout": output.get("StandardOutputContent", ""),
|
|
"stderr": output.get("StandardErrorContent", ""),
|
|
}
|
|
except ClientError as e:
|
|
results[iid] = {"status": "Error", "error": str(e)}
|
|
return results
|
|
|
|
|
|
def scan_for_cryptominers(session, instance_ids):
|
|
"""Detect cryptomining processes on instances."""
|
|
commands = [
|
|
"ps aux | grep -iE 'xmrig|minerd|cryptonight|stratum|nicehash' | grep -v grep",
|
|
"find /tmp /var/tmp /dev/shm -name '*.sh' -o -name 'config.json' 2>/dev/null | head -20",
|
|
]
|
|
results = run_ssm_command(session, instance_ids, commands)
|
|
findings = []
|
|
for iid, result in results.items():
|
|
if result.get("stdout", "").strip():
|
|
findings.append({
|
|
"instance_id": iid,
|
|
"type": "cryptominer",
|
|
"severity": "CRITICAL",
|
|
"output": result["stdout"].strip(),
|
|
})
|
|
return findings
|
|
|
|
|
|
def scan_for_reverse_shells(session, instance_ids):
|
|
"""Detect potential reverse shell connections."""
|
|
commands = [
|
|
"ss -tlnp 2>/dev/null | grep ESTAB | grep -vE ':443|:80|:22|:8089'",
|
|
"ls -la /dev/tcp 2>/dev/null; ls -la /proc/*/fd 2>/dev/null | grep socket | head -20",
|
|
]
|
|
results = run_ssm_command(session, instance_ids, commands)
|
|
findings = []
|
|
for iid, result in results.items():
|
|
if result.get("stdout", "").strip():
|
|
findings.append({
|
|
"instance_id": iid,
|
|
"type": "suspicious_connections",
|
|
"severity": "HIGH",
|
|
"output": result["stdout"].strip(),
|
|
})
|
|
return findings
|
|
|
|
|
|
def check_file_integrity(session, instance_ids):
|
|
"""Check integrity of critical system files."""
|
|
commands = [
|
|
"rpm -Va 2>/dev/null | grep -E '^..5' | head -20 || "
|
|
"debsums -c 2>/dev/null | head -20",
|
|
"find /usr/bin /usr/sbin -newer /var/log/lastlog -type f 2>/dev/null | head -20",
|
|
]
|
|
results = run_ssm_command(session, instance_ids, commands)
|
|
findings = []
|
|
for iid, result in results.items():
|
|
if result.get("stdout", "").strip():
|
|
findings.append({
|
|
"instance_id": iid,
|
|
"type": "file_integrity",
|
|
"severity": "MEDIUM",
|
|
"modified_files": result["stdout"].strip().splitlines(),
|
|
})
|
|
return findings
|
|
|
|
|
|
def check_cpu_anomaly(session, instance_ids):
|
|
"""Detect CPU usage anomalies via CloudWatch."""
|
|
cw = session.client("cloudwatch")
|
|
anomalies = []
|
|
for iid in instance_ids:
|
|
resp = cw.get_metric_statistics(
|
|
Namespace="AWS/EC2",
|
|
MetricName="CPUUtilization",
|
|
Dimensions=[{"Name": "InstanceId", "Value": iid}],
|
|
StartTime=datetime.utcnow().replace(hour=0, minute=0),
|
|
EndTime=datetime.utcnow(),
|
|
Period=300,
|
|
Statistics=["Average"],
|
|
)
|
|
for dp in resp.get("Datapoints", []):
|
|
if dp["Average"] > 90:
|
|
anomalies.append({
|
|
"instance_id": iid,
|
|
"cpu_avg": round(dp["Average"], 1),
|
|
"timestamp": str(dp["Timestamp"]),
|
|
"severity": "HIGH",
|
|
})
|
|
return anomalies
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description="Cloud Workload Protection Agent")
|
|
parser.add_argument("--profile", default=os.getenv("AWS_PROFILE"))
|
|
parser.add_argument("--region", default=os.getenv("AWS_DEFAULT_REGION", "us-east-1"))
|
|
parser.add_argument("--output", default="cwp_report.json")
|
|
parser.add_argument("--action", choices=[
|
|
"list", "cryptominer", "reverse_shell", "integrity", "cpu", "full_scan"
|
|
], default="full_scan")
|
|
args = parser.parse_args()
|
|
|
|
session = boto3.Session(profile_name=args.profile, region_name=args.region)
|
|
report = {"generated_at": datetime.utcnow().isoformat(), "findings": {}}
|
|
|
|
instances = get_running_instances(session)
|
|
instance_ids = [i["instance_id"] for i in instances]
|
|
report["instances"] = instances
|
|
print(f"[+] Running instances: {len(instances)}")
|
|
|
|
if args.action in ("cryptominer", "full_scan") and instance_ids:
|
|
findings = scan_for_cryptominers(session, instance_ids)
|
|
report["findings"]["cryptominers"] = findings
|
|
print(f"[+] Cryptominer detections: {len(findings)}")
|
|
|
|
if args.action in ("reverse_shell", "full_scan") and instance_ids:
|
|
findings = scan_for_reverse_shells(session, instance_ids)
|
|
report["findings"]["reverse_shells"] = findings
|
|
print(f"[+] Suspicious connections: {len(findings)}")
|
|
|
|
if args.action in ("integrity", "full_scan") and instance_ids:
|
|
findings = check_file_integrity(session, instance_ids)
|
|
report["findings"]["file_integrity"] = findings
|
|
print(f"[+] File integrity issues: {len(findings)}")
|
|
|
|
if args.action in ("cpu", "full_scan") and instance_ids:
|
|
anomalies = check_cpu_anomaly(session, instance_ids)
|
|
report["findings"]["cpu_anomalies"] = anomalies
|
|
print(f"[+] CPU anomalies: {len(anomalies)}")
|
|
|
|
with open(args.output, "w") as f:
|
|
json.dump(report, f, indent=2, default=str)
|
|
print(f"[+] Report saved to {args.output}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|