mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-06-16 07:53:18 +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,54 @@
|
||||
# API Reference: Implementing API Security Posture Management
|
||||
|
||||
## API Discovery from Traffic
|
||||
|
||||
```python
|
||||
import re
|
||||
# Normalize paths: /users/123 -> /users/{id}
|
||||
normalized = re.sub(r"/\d+", "/{id}", path)
|
||||
normalized = re.sub(r"/[0-9a-f-]{8,}", "/{id}", normalized)
|
||||
```
|
||||
|
||||
## API Sensitivity Classification
|
||||
|
||||
| Category | Patterns | Sensitivity |
|
||||
|----------|----------|-------------|
|
||||
| PII | `/users`, `/profile`, `/account` | HIGH |
|
||||
| Financial | `/payments`, `/billing` | HIGH |
|
||||
| Auth | `/login`, `/token`, `/oauth` | HIGH |
|
||||
| Admin | `/admin`, `/config` | HIGH |
|
||||
| Health | `/health`, `/status` | LOW |
|
||||
|
||||
## Risk Scoring Model
|
||||
|
||||
| Factor | Points | Description |
|
||||
|--------|--------|-------------|
|
||||
| High sensitivity data | +30 | PII, financial, auth |
|
||||
| High error rate (>10%) | +20 | Possible abuse |
|
||||
| State-changing methods | +10 | PUT, DELETE, PATCH |
|
||||
| High consumer count | +10 | Large attack surface |
|
||||
| Auth endpoint | +15 | Credential target |
|
||||
|
||||
## 42Crunch API Audit
|
||||
|
||||
```bash
|
||||
# CI/CD integration
|
||||
curl -X POST https://platform.42crunch.com/api/v1/apis \
|
||||
-H "X-API-KEY: $API_KEY" \
|
||||
-F "file=@openapi.yaml"
|
||||
```
|
||||
|
||||
## Salt Security API
|
||||
|
||||
```python
|
||||
import requests
|
||||
headers = {"Authorization": "Bearer <token>"}
|
||||
# Discover shadow APIs
|
||||
resp = requests.get("https://api.salt.security/v1/apis", headers=headers)
|
||||
```
|
||||
|
||||
### References
|
||||
|
||||
- OWASP API Security Top 10: https://owasp.org/API-Security/
|
||||
- 42Crunch: https://42crunch.com/
|
||||
- Salt Security: https://salt.security/
|
||||
@@ -0,0 +1,154 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Agent for API Security Posture Management - discovery, classification, and risk scoring."""
|
||||
|
||||
import json
|
||||
import argparse
|
||||
import re
|
||||
from datetime import datetime
|
||||
from collections import Counter, defaultdict
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def discover_apis_from_traffic(log_path):
|
||||
"""Discover APIs from network traffic logs."""
|
||||
apis = defaultdict(lambda: {"methods": set(), "consumers": set(), "count": 0,
|
||||
"status_codes": Counter()})
|
||||
with open(log_path) as f:
|
||||
for line in f:
|
||||
try:
|
||||
entry = json.loads(line)
|
||||
except json.JSONDecodeError:
|
||||
continue
|
||||
path = entry.get("path", entry.get("endpoint", ""))
|
||||
method = entry.get("method", entry.get("http_method", ""))
|
||||
ip = entry.get("client_ip", "")
|
||||
status = entry.get("status_code", entry.get("status", 200))
|
||||
normalized = re.sub(r"/[0-9a-f-]{8,}", "/{id}", path)
|
||||
normalized = re.sub(r"/\d+", "/{id}", normalized)
|
||||
apis[normalized]["methods"].add(method)
|
||||
apis[normalized]["consumers"].add(ip)
|
||||
apis[normalized]["count"] += 1
|
||||
apis[normalized]["status_codes"][int(status)] += 1
|
||||
result = []
|
||||
for path, info in sorted(apis.items(), key=lambda x: -x[1]["count"]):
|
||||
result.append({
|
||||
"path": path,
|
||||
"methods": sorted(info["methods"]),
|
||||
"unique_consumers": len(info["consumers"]),
|
||||
"total_requests": info["count"],
|
||||
"error_rate": round(
|
||||
sum(v for k, v in info["status_codes"].items() if k >= 400) / info["count"], 3),
|
||||
})
|
||||
return result
|
||||
|
||||
|
||||
def classify_api_sensitivity(apis):
|
||||
"""Classify APIs by data sensitivity level."""
|
||||
sensitive_patterns = {
|
||||
"PII": [r"/users?(/|$)", r"/customers?(/|$)", r"/profile", r"/account"],
|
||||
"Financial": [r"/payments?", r"/billing", r"/invoices?", r"/transactions?"],
|
||||
"Auth": [r"/auth", r"/login", r"/token", r"/oauth", r"/password"],
|
||||
"Admin": [r"/admin", r"/management", r"/config", r"/settings"],
|
||||
"Health": [r"/health", r"/status", r"/metrics", r"/ping"],
|
||||
}
|
||||
classified = []
|
||||
for api in apis:
|
||||
path = api["path"]
|
||||
categories = []
|
||||
for category, patterns in sensitive_patterns.items():
|
||||
if any(re.search(p, path, re.IGNORECASE) for p in patterns):
|
||||
categories.append(category)
|
||||
sensitivity = "HIGH" if any(c in categories for c in ["PII", "Financial", "Auth", "Admin"]) \
|
||||
else "LOW" if "Health" in categories else "MEDIUM"
|
||||
classified.append({**api, "categories": categories, "sensitivity": sensitivity})
|
||||
return classified
|
||||
|
||||
|
||||
def score_api_risk(apis):
|
||||
"""Calculate risk score for each API endpoint."""
|
||||
scored = []
|
||||
for api in apis:
|
||||
risk_score = 0
|
||||
factors = []
|
||||
if api.get("sensitivity") == "HIGH":
|
||||
risk_score += 30
|
||||
factors.append("high_sensitivity_data")
|
||||
if api.get("error_rate", 0) > 0.1:
|
||||
risk_score += 20
|
||||
factors.append("high_error_rate")
|
||||
if api.get("unique_consumers", 0) > 100:
|
||||
risk_score += 10
|
||||
factors.append("high_consumer_count")
|
||||
if "Auth" in api.get("categories", []):
|
||||
risk_score += 15
|
||||
factors.append("authentication_endpoint")
|
||||
methods = api.get("methods", [])
|
||||
if any(m in methods for m in ["DELETE", "PUT", "PATCH"]):
|
||||
risk_score += 10
|
||||
factors.append("state_changing_methods")
|
||||
severity = "CRITICAL" if risk_score >= 50 else "HIGH" if risk_score >= 30 else "MEDIUM"
|
||||
scored.append({**api, "risk_score": risk_score, "risk_factors": factors,
|
||||
"risk_level": severity})
|
||||
return sorted(scored, key=lambda x: x["risk_score"], reverse=True)
|
||||
|
||||
|
||||
def check_api_security_controls(apis, spec_path=None):
|
||||
"""Check security controls for discovered APIs."""
|
||||
findings = []
|
||||
spec_paths = set()
|
||||
if spec_path:
|
||||
try:
|
||||
import yaml
|
||||
with open(spec_path) as f:
|
||||
spec = yaml.safe_load(f) if spec_path.endswith((".yaml", ".yml")) else json.load(f)
|
||||
spec_paths = set(spec.get("paths", {}).keys())
|
||||
except Exception:
|
||||
pass
|
||||
for api in apis:
|
||||
if spec_paths and api["path"] not in spec_paths:
|
||||
findings.append({
|
||||
"path": api["path"], "issue": "undocumented_api",
|
||||
"severity": "HIGH", "recommendation": "Add to OpenAPI spec or deprecate",
|
||||
})
|
||||
if api.get("sensitivity") == "HIGH" and api.get("error_rate", 0) > 0.05:
|
||||
findings.append({
|
||||
"path": api["path"], "issue": "sensitive_endpoint_high_errors",
|
||||
"severity": "HIGH",
|
||||
})
|
||||
return findings
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="API Security Posture Management Agent")
|
||||
parser.add_argument("--log", help="API traffic log (JSON lines)")
|
||||
parser.add_argument("--spec", help="OpenAPI spec for comparison")
|
||||
parser.add_argument("--output", default="api_posture_report.json")
|
||||
parser.add_argument("--action", choices=["discover", "classify", "score", "audit", "full"],
|
||||
default="full")
|
||||
args = parser.parse_args()
|
||||
|
||||
report = {"generated_at": datetime.utcnow().isoformat(), "findings": {}}
|
||||
|
||||
if args.log:
|
||||
apis = discover_apis_from_traffic(args.log)
|
||||
report["findings"]["discovered_apis"] = len(apis)
|
||||
print(f"[+] Discovered {len(apis)} API endpoints")
|
||||
|
||||
if args.action in ("classify", "full"):
|
||||
apis = classify_api_sensitivity(apis)
|
||||
if args.action in ("score", "full"):
|
||||
apis = score_api_risk(apis)
|
||||
report["findings"]["api_inventory"] = apis[:200]
|
||||
|
||||
if args.action in ("audit", "full"):
|
||||
f = check_api_security_controls(apis, args.spec)
|
||||
report["findings"]["security_gaps"] = f
|
||||
print(f"[+] Security gaps: {len(f)}")
|
||||
|
||||
with open(args.output, "w") as fout:
|
||||
json.dump(report, fout, indent=2, default=str)
|
||||
print(f"[+] Report saved to {args.output}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user