Complete folder anatomy for all 649 cybersecurity skills + update LICENSE to Mahipal

- Add scripts/agent.py and references/api-reference.md to all remaining skills
- Update all 648 LICENSE files: copyright now reads 'Mahipal'
- Add implementing-security-monitoring-with-datadog (new skill with full anatomy)
- All 649 skills now have: SKILL.md, LICENSE, scripts/agent.py, references/api-reference.md
This commit is contained in:
mukul975
2026-03-11 00:22:12 +01:00
parent 27c6414ca5
commit c21af3347e
1244 changed files with 61622 additions and 723 deletions
@@ -1,6 +1,6 @@
MIT License
Copyright (c) 2025 Anthropic Agent Skills Contributors
Copyright (c) 2025 Mahipal
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -0,0 +1,106 @@
# Agentless Vulnerability Scanning - API Reference
## AWS Inspector2 (boto3)
### Enable Inspector
```python
client = boto3.client("inspector2")
client.enable(resourceTypes=["EC2", "ECR", "LAMBDA"],
accountIds=["123456789012"])
```
### Check Account Status
```python
client.batch_get_account_status(accountIds=["123456789012"])
```
### List Coverage
```python
paginator = client.get_paginator("list_coverage")
for page in paginator.paginate(
filterCriteria={"resourceType": [{"comparison": "EQUALS", "value": "AWS_EC2_INSTANCE"}]}
):
for resource in page["coveredResources"]:
print(resource["resourceId"], resource["scanStatus"]["statusCode"])
```
### List Findings
```python
paginator = client.get_paginator("list_findings")
for page in paginator.paginate(
filterCriteria={"severity": [{"comparison": "EQUALS", "value": "CRITICAL"}]}
):
for finding in page["findings"]:
print(finding["title"], finding["severity"])
```
### Finding Fields
| Field | Type | Description |
|-------|------|-------------|
| `findingArn` | string | Unique finding ARN |
| `title` | string | Vulnerability title |
| `severity` | string | CRITICAL, HIGH, MEDIUM, LOW, INFORMATIONAL |
| `status` | string | ACTIVE, SUPPRESSED, CLOSED |
| `type` | string | NETWORK_REACHABILITY or PACKAGE_VULNERABILITY |
| `resources` | array | Affected AWS resources |
| `packageVulnerabilityDetails.vulnerabilityId` | string | CVE ID |
| `packageVulnerabilityDetails.cvss` | array | CVSS scores |
| `packageVulnerabilityDetails.fixedInVersion` | string | Patched version |
## Agentless Scanning via EBS Snapshots
Inspector2 supports agentless scanning by:
1. Creating EBS snapshots of instance volumes
2. Mounting snapshots in Inspector service account
3. Scanning file system for vulnerable packages
4. No agent installation required on target instances
### Create Snapshot (boto3 EC2)
```python
ec2 = boto3.client("ec2")
ec2.create_snapshot(
VolumeId="vol-xxx",
Description="Agentless scan",
TagSpecifications=[{"ResourceType": "snapshot",
"Tags": [{"Key": "Purpose", "Value": "VulnScan"}]}]
)
```
## SSM Inventory (Alternative)
AWS Systems Manager Inventory collects software inventory without custom agents:
```python
ssm = boto3.client("ssm")
ssm.get_inventory(
Filters=[{"Key": "AWS:Application.Name", "Values": ["openssl"]}]
)
```
## Scan Types
| Type | Method | Agent Required |
|------|--------|---------------|
| Inspector Classic | AWS agent | Yes |
| Inspector2 Agent | SSM agent | Yes (auto-installed) |
| Inspector2 Agentless | EBS snapshot | No |
| SSM Inventory | SSM agent | Yes |
## Output Schema
```json
{
"report": "agentless_vulnerability_scanning",
"inspector_status": {"enabled": true},
"total_resources_scanned": 50,
"uncovered_resources": 3,
"total_findings": 125,
"severity_summary": {"CRITICAL": 5, "HIGH": 30, "MEDIUM": 60, "LOW": 30}
}
```
## CLI Usage
```bash
python agent.py --region us-east-1 --severity CRITICAL HIGH --output report.json
```
@@ -0,0 +1,165 @@
#!/usr/bin/env python3
"""Agentless Vulnerability Scanning agent - uses AWS Inspector2 and SSM APIs
via boto3 to perform agentless scans of EC2 instances through EBS snapshot
analysis without requiring installed agents."""
import argparse
import json
import sys
from collections import Counter
from datetime import datetime
from pathlib import Path
try:
import boto3
from botocore.exceptions import ClientError
except ImportError:
print("Install boto3: pip install boto3", file=sys.stderr)
sys.exit(1)
def get_inspector_client(region: str = "us-east-1", profile: str = None):
"""Create AWS Inspector2 client."""
session = boto3.Session(profile_name=profile, region_name=region)
return session.client("inspector2")
def get_ec2_client(region: str = "us-east-1", profile: str = None):
"""Create EC2 client."""
session = boto3.Session(profile_name=profile, region_name=region)
return session.client("ec2")
def check_inspector_status(client) -> dict:
"""Check Inspector2 enablement status."""
try:
response = client.batch_get_account_status(
accountIds=[boto3.client("sts").get_caller_identity()["Account"]]
)
accounts = response.get("accounts", [])
if accounts:
status = accounts[0].get("state", {}).get("status", "UNKNOWN")
return {"enabled": status == "ENABLED", "status": status}
return {"enabled": False, "status": "NO_DATA"}
except ClientError as e:
return {"enabled": False, "error": str(e)}
def list_ec2_scan_coverage(client) -> list[dict]:
"""List EC2 instances and their scan coverage status."""
coverage = []
paginator = client.get_paginator("list_coverage")
for page in paginator.paginate(
filterCriteria={"resourceType": [{"comparison": "EQUALS", "value": "AWS_EC2_INSTANCE"}]}
):
for item in page.get("coveredResources", []):
coverage.append({
"resource_id": item.get("resourceId", ""),
"resource_type": item.get("resourceType", ""),
"scan_status": item.get("scanStatus", {}).get("statusCode", "UNKNOWN"),
"scan_type": item.get("scanType", ""),
"account_id": item.get("accountId", ""),
})
return coverage
def list_findings(client, severity_filter: list[str] = None,
max_results: int = 500) -> list[dict]:
"""List vulnerability findings from Inspector2."""
filter_criteria = {}
if severity_filter:
filter_criteria["severity"] = [
{"comparison": "EQUALS", "value": s} for s in severity_filter
]
findings = []
paginator = client.get_paginator("list_findings")
params = {"filterCriteria": filter_criteria, "maxResults": min(max_results, 100)}
count = 0
for page in paginator.paginate(**params):
for finding in page.get("findings", []):
findings.append({
"finding_arn": finding.get("findingArn", ""),
"title": finding.get("title", ""),
"severity": finding.get("severity", ""),
"status": finding.get("status", ""),
"type": finding.get("type", ""),
"resource_id": finding.get("resources", [{}])[0].get("id", ""),
"resource_type": finding.get("resources", [{}])[0].get("type", ""),
"vulnerability_id": finding.get("packageVulnerabilityDetails", {}).get("vulnerabilityId", ""),
"cvss_score": finding.get("packageVulnerabilityDetails", {}).get("cvss", [{}])[0].get("baseScore", 0),
"fixed_in": finding.get("packageVulnerabilityDetails", {}).get("fixedInVersion", ""),
"first_observed": str(finding.get("firstObservedAt", "")),
})
count += 1
if count >= max_results:
return findings
return findings
def create_ebs_snapshot_scan(ec2_client, instance_id: str) -> dict:
"""Create EBS snapshots for agentless scanning."""
try:
volumes = ec2_client.describe_volumes(
Filters=[{"Name": "attachment.instance-id", "Values": [instance_id]}]
)
snapshots = []
for vol in volumes.get("Volumes", []):
snap = ec2_client.create_snapshot(
VolumeId=vol["VolumeId"],
Description=f"Agentless scan snapshot for {instance_id}",
TagSpecifications=[{
"ResourceType": "snapshot",
"Tags": [{"Key": "Purpose", "Value": "AgentlessVulnScan"},
{"Key": "SourceInstance", "Value": instance_id}]
}]
)
snapshots.append({"volume_id": vol["VolumeId"], "snapshot_id": snap["SnapshotId"]})
return {"instance_id": instance_id, "snapshots": snapshots}
except ClientError as e:
return {"instance_id": instance_id, "error": str(e)}
def generate_report(region: str, profile: str = None,
severity_filter: list[str] = None) -> dict:
"""Run agentless scanning assessment and build report."""
inspector = get_inspector_client(region, profile)
status = check_inspector_status(inspector)
coverage = list_ec2_scan_coverage(inspector)
findings = list_findings(inspector, severity_filter)
severity_counts = Counter(f["severity"] for f in findings)
uncovered = [c for c in coverage if c["scan_status"] != "ACTIVE"]
return {
"report": "agentless_vulnerability_scanning",
"generated_at": datetime.utcnow().isoformat() + "Z",
"region": region,
"inspector_status": status,
"total_resources_scanned": len(coverage),
"uncovered_resources": len(uncovered),
"total_findings": len(findings),
"severity_summary": dict(severity_counts),
"uncovered_resources_list": uncovered[:20],
"findings": findings,
}
def main():
parser = argparse.ArgumentParser(description="Agentless Vulnerability Scanning Agent")
parser.add_argument("--region", default="us-east-1", help="AWS region")
parser.add_argument("--profile", help="AWS CLI profile name")
parser.add_argument("--severity", nargs="+", choices=["CRITICAL", "HIGH", "MEDIUM", "LOW"],
help="Filter by severity")
parser.add_argument("--output", help="Output JSON file path")
args = parser.parse_args()
report = generate_report(args.region, args.profile, args.severity)
output = json.dumps(report, indent=2)
if args.output:
Path(args.output).write_text(output, encoding="utf-8")
print(f"Report written to {args.output}")
else:
print(output)
if __name__ == "__main__":
main()