mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-07-27 06:31:00 +03:00
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
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025 Anthropic Agent Skills Contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,63 @@
|
||||
# API Reference: Performing Cloud Forensics Investigation
|
||||
|
||||
## AWS CloudTrail API (boto3)
|
||||
|
||||
| Method | Description |
|
||||
|--------|-------------|
|
||||
| `cloudtrail.lookup_events(StartTime, EndTime)` | Query management events by time window |
|
||||
| `cloudtrail.get_trail_status(Name)` | Check if trail is actively logging |
|
||||
| `cloudtrail.describe_trails()` | List configured CloudTrail trails |
|
||||
|
||||
## AWS EC2 API (Forensic Snapshots)
|
||||
|
||||
| Method | Description |
|
||||
|--------|-------------|
|
||||
| `ec2.describe_instances(InstanceIds)` | Get instance details and EBS mappings |
|
||||
| `ec2.create_snapshot(VolumeId, Description)` | Create forensic snapshot of EBS volume |
|
||||
| `ec2.copy_snapshot(SourceSnapshotId, SourceRegion)` | Copy snapshot cross-region for preservation |
|
||||
| `ec2.describe_snapshots(SnapshotIds)` | Check snapshot completion status |
|
||||
|
||||
## AWS IAM API
|
||||
|
||||
| Method | Description |
|
||||
|--------|-------------|
|
||||
| `iam.list_access_keys(UserName)` | List access keys for investigation target |
|
||||
| `iam.get_access_key_last_used(AccessKeyId)` | Determine last key usage |
|
||||
| `iam.list_attached_user_policies(UserName)` | List policies attached to user |
|
||||
|
||||
## AWS S3 API (Log Collection)
|
||||
|
||||
| Method | Description |
|
||||
|--------|-------------|
|
||||
| `s3.list_objects_v2(Bucket, Prefix)` | List CloudTrail log files in S3 |
|
||||
| `s3.get_object(Bucket, Key)` | Download specific log file |
|
||||
|
||||
## Key Libraries
|
||||
|
||||
- **boto3** (`pip install boto3`): AWS SDK for CloudTrail, EC2, IAM, and S3 APIs
|
||||
- **botocore**: Exception handling for AWS API errors
|
||||
- **json** (stdlib): Parse CloudTrail event JSON payloads
|
||||
|
||||
## Configuration
|
||||
|
||||
| Variable | Description |
|
||||
|----------|-------------|
|
||||
| `AWS_PROFILE` | AWS CLI profile with forensic investigation permissions |
|
||||
| `AWS_DEFAULT_REGION` | Default region for API calls |
|
||||
| CloudTrail S3 Bucket | Bucket containing CloudTrail log archives |
|
||||
|
||||
## Required IAM Permissions
|
||||
|
||||
| Permission | Purpose |
|
||||
|------------|---------|
|
||||
| `cloudtrail:LookupEvents` | Query CloudTrail events |
|
||||
| `ec2:DescribeInstances` | Identify volumes for snapshots |
|
||||
| `ec2:CreateSnapshot` | Create forensic disk snapshots |
|
||||
| `iam:List*` | Enumerate IAM configuration |
|
||||
| `s3:GetObject` | Download archived CloudTrail logs |
|
||||
|
||||
## References
|
||||
|
||||
- [AWS CloudTrail API](https://docs.aws.amazon.com/awscloudtrail/latest/APIReference/)
|
||||
- [AWS Incident Response Guide](https://docs.aws.amazon.com/whitepapers/latest/aws-security-incident-response-guide/)
|
||||
- [SANS Cloud Forensics](https://www.sans.org/white-papers/cloud-forensics/)
|
||||
@@ -0,0 +1,223 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Cloud Forensics Investigation Agent
|
||||
Collects and analyzes forensic evidence from AWS cloud environments including
|
||||
CloudTrail logs, EC2 snapshots, and IAM activity for incident response.
|
||||
"""
|
||||
|
||||
import json
|
||||
import sys
|
||||
from datetime import datetime, timezone, timedelta
|
||||
|
||||
import boto3
|
||||
from botocore.exceptions import ClientError
|
||||
|
||||
|
||||
def collect_cloudtrail_events(
|
||||
start_time: datetime, end_time: datetime, region: str = "us-east-1"
|
||||
) -> list[dict]:
|
||||
"""Collect CloudTrail management events for the investigation window."""
|
||||
ct = boto3.client("cloudtrail", region_name=region)
|
||||
events = []
|
||||
|
||||
paginator = ct.get_paginator("lookup_events")
|
||||
for page in paginator.paginate(
|
||||
StartTime=start_time,
|
||||
EndTime=end_time,
|
||||
MaxResults=50,
|
||||
):
|
||||
for event in page.get("Events", []):
|
||||
cloud_event = json.loads(event.get("CloudTrailEvent", "{}"))
|
||||
events.append({
|
||||
"timestamp": str(event.get("EventTime", "")),
|
||||
"event_name": event.get("EventName", ""),
|
||||
"event_source": event.get("EventSource", ""),
|
||||
"username": event.get("Username", ""),
|
||||
"source_ip": cloud_event.get("sourceIPAddress", ""),
|
||||
"user_agent": cloud_event.get("userAgent", ""),
|
||||
"region": cloud_event.get("awsRegion", ""),
|
||||
"error_code": cloud_event.get("errorCode", ""),
|
||||
"error_message": cloud_event.get("errorMessage", ""),
|
||||
"resources": event.get("Resources", []),
|
||||
})
|
||||
|
||||
return events
|
||||
|
||||
|
||||
def identify_suspicious_activity(events: list[dict]) -> list[dict]:
|
||||
"""Identify suspicious CloudTrail events indicating compromise."""
|
||||
suspicious_patterns = {
|
||||
"ConsoleLogin": "Console login detected",
|
||||
"CreateAccessKey": "New access key created",
|
||||
"CreateUser": "New IAM user created",
|
||||
"AttachUserPolicy": "Policy attached to user",
|
||||
"PutBucketPolicy": "S3 bucket policy modified",
|
||||
"AuthorizeSecurityGroupIngress": "Security group opened",
|
||||
"RunInstances": "EC2 instance launched",
|
||||
"CreateKeyPair": "SSH key pair created",
|
||||
"StopLogging": "CloudTrail logging stopped",
|
||||
"DeleteTrail": "CloudTrail trail deleted",
|
||||
"ModifySnapshotAttribute": "Snapshot shared externally",
|
||||
"CreateLoginProfile": "Console password set for user",
|
||||
}
|
||||
|
||||
suspicious = []
|
||||
for event in events:
|
||||
event_name = event["event_name"]
|
||||
if event_name in suspicious_patterns:
|
||||
suspicious.append({
|
||||
**event,
|
||||
"reason": suspicious_patterns[event_name],
|
||||
"severity": "HIGH" if event_name in (
|
||||
"StopLogging", "DeleteTrail", "CreateAccessKey", "AttachUserPolicy"
|
||||
) else "MEDIUM",
|
||||
})
|
||||
|
||||
if event.get("error_code") == "AccessDenied":
|
||||
suspicious.append({
|
||||
**event,
|
||||
"reason": "Access denied - possible reconnaissance",
|
||||
"severity": "LOW",
|
||||
})
|
||||
|
||||
return suspicious
|
||||
|
||||
|
||||
def snapshot_ec2_instance(instance_id: str, region: str = "us-east-1") -> list[dict]:
|
||||
"""Create forensic snapshots of all EBS volumes attached to an instance."""
|
||||
ec2 = boto3.client("ec2", region_name=region)
|
||||
snapshots = []
|
||||
|
||||
try:
|
||||
instance = ec2.describe_instances(InstanceIds=[instance_id])
|
||||
reservations = instance["Reservations"]
|
||||
if not reservations:
|
||||
return [{"error": f"Instance {instance_id} not found"}]
|
||||
|
||||
volumes = []
|
||||
for reservation in reservations:
|
||||
for inst in reservation["Instances"]:
|
||||
for mapping in inst.get("BlockDeviceMappings", []):
|
||||
vol_id = mapping.get("Ebs", {}).get("VolumeId")
|
||||
if vol_id:
|
||||
volumes.append({"volume_id": vol_id, "device": mapping["DeviceName"]})
|
||||
|
||||
for vol in volumes:
|
||||
snap = ec2.create_snapshot(
|
||||
VolumeId=vol["volume_id"],
|
||||
Description=f"Forensic snapshot - {instance_id} - {vol['device']} - "
|
||||
f"{datetime.now(timezone.utc).strftime('%Y%m%d')}",
|
||||
TagSpecifications=[{
|
||||
"ResourceType": "snapshot",
|
||||
"Tags": [
|
||||
{"Key": "Purpose", "Value": "forensics"},
|
||||
{"Key": "SourceInstance", "Value": instance_id},
|
||||
{"Key": "SourceVolume", "Value": vol["volume_id"]},
|
||||
],
|
||||
}],
|
||||
)
|
||||
snapshots.append({
|
||||
"snapshot_id": snap["SnapshotId"],
|
||||
"volume_id": vol["volume_id"],
|
||||
"device": vol["device"],
|
||||
"state": snap["State"],
|
||||
})
|
||||
|
||||
except ClientError as e:
|
||||
snapshots.append({"error": str(e)})
|
||||
|
||||
return snapshots
|
||||
|
||||
|
||||
def collect_iam_activity(username: str) -> dict:
|
||||
"""Collect IAM activity for a specific user."""
|
||||
iam = boto3.client("iam")
|
||||
result = {"user": username, "access_keys": [], "policies": [], "groups": []}
|
||||
|
||||
try:
|
||||
keys = iam.list_access_keys(UserName=username)
|
||||
for key in keys.get("AccessKeyMetadata", []):
|
||||
last_used = iam.get_access_key_last_used(AccessKeyId=key["AccessKeyId"])
|
||||
result["access_keys"].append({
|
||||
"key_id": key["AccessKeyId"],
|
||||
"status": key["Status"],
|
||||
"created": str(key["CreateDate"]),
|
||||
"last_used": str(last_used.get("AccessKeyLastUsed", {}).get("LastUsedDate", "Never")),
|
||||
"last_service": last_used.get("AccessKeyLastUsed", {}).get("ServiceName", "N/A"),
|
||||
})
|
||||
|
||||
policies = iam.list_attached_user_policies(UserName=username)
|
||||
result["policies"] = [p["PolicyArn"] for p in policies["AttachedPolicies"]]
|
||||
|
||||
groups = iam.list_groups_for_user(UserName=username)
|
||||
result["groups"] = [g["GroupName"] for g in groups["Groups"]]
|
||||
|
||||
except ClientError as e:
|
||||
result["error"] = str(e)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def generate_report(events: list, suspicious: list, snapshots: list, iam: dict) -> str:
|
||||
"""Generate cloud forensics investigation report."""
|
||||
lines = [
|
||||
"CLOUD FORENSICS INVESTIGATION REPORT",
|
||||
"=" * 50,
|
||||
f"Date: {datetime.now(timezone.utc).strftime('%Y-%m-%d %H:%M UTC')}",
|
||||
"",
|
||||
f"CloudTrail Events Collected: {len(events)}",
|
||||
f"Suspicious Events: {len(suspicious)}",
|
||||
f"Forensic Snapshots Created: {len(snapshots)}",
|
||||
"",
|
||||
"SUSPICIOUS ACTIVITY:",
|
||||
"-" * 40,
|
||||
]
|
||||
|
||||
for s in suspicious[:15]:
|
||||
lines.append(f" [{s['severity']}] {s['timestamp']} - {s['event_name']}")
|
||||
lines.append(f" User: {s['username']} | IP: {s['source_ip']} | {s['reason']}")
|
||||
|
||||
if snapshots:
|
||||
lines.extend(["", "FORENSIC SNAPSHOTS:"])
|
||||
for snap in snapshots:
|
||||
if "error" not in snap:
|
||||
lines.append(f" {snap['snapshot_id']} (vol: {snap['volume_id']}, device: {snap['device']})")
|
||||
|
||||
if iam.get("access_keys"):
|
||||
lines.extend(["", f"IAM ACTIVITY ({iam['user']}):"])
|
||||
for key in iam["access_keys"]:
|
||||
lines.append(f" Key: {key['key_id']} | Status: {key['status']} | Last Used: {key['last_used']}")
|
||||
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
hours_back = int(sys.argv[1]) if len(sys.argv) > 1 else 24
|
||||
instance_id = sys.argv[2] if len(sys.argv) > 2 else None
|
||||
username = sys.argv[3] if len(sys.argv) > 3 else None
|
||||
|
||||
end_time = datetime.now(timezone.utc)
|
||||
start_time = end_time - timedelta(hours=hours_back)
|
||||
|
||||
print(f"[*] Collecting CloudTrail events ({hours_back}h window)...")
|
||||
events = collect_cloudtrail_events(start_time, end_time)
|
||||
suspicious = identify_suspicious_activity(events)
|
||||
print(f"[*] Found {len(suspicious)} suspicious events")
|
||||
|
||||
snapshots = []
|
||||
if instance_id:
|
||||
print(f"[*] Creating forensic snapshots for {instance_id}...")
|
||||
snapshots = snapshot_ec2_instance(instance_id)
|
||||
|
||||
iam_data = {}
|
||||
if username:
|
||||
print(f"[*] Collecting IAM activity for {username}...")
|
||||
iam_data = collect_iam_activity(username)
|
||||
|
||||
report = generate_report(events, suspicious, snapshots, iam_data)
|
||||
print(report)
|
||||
|
||||
output = f"cloud_forensics_{datetime.now(timezone.utc).strftime('%Y%m%d_%H%M%S')}.json"
|
||||
with open(output, "w") as f:
|
||||
json.dump({"events": events, "suspicious": suspicious, "snapshots": snapshots, "iam": iam_data}, f, indent=2)
|
||||
print(f"\n[*] Results saved to {output}")
|
||||
Reference in New Issue
Block a user