mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-06-12 22:24:56 +03:00
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:
@@ -0,0 +1,130 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Agent for testing Broken Function Level Authorization (BFLA) in APIs."""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import sys
|
||||
from datetime import datetime, timezone
|
||||
|
||||
try:
|
||||
import requests
|
||||
HAS_REQUESTS = True
|
||||
except ImportError:
|
||||
HAS_REQUESTS = False
|
||||
|
||||
|
||||
ADMIN_ENDPOINTS = [
|
||||
"/admin", "/admin/users", "/admin/settings", "/admin/config",
|
||||
"/api/admin/users", "/api/v1/admin", "/api/internal",
|
||||
"/manage", "/management", "/dashboard/admin",
|
||||
"/api/users/all", "/api/config", "/api/debug",
|
||||
]
|
||||
|
||||
HTTP_METHODS = ["GET", "POST", "PUT", "DELETE", "PATCH"]
|
||||
|
||||
|
||||
def test_endpoint_access(base_url, endpoint, token, method="GET"):
|
||||
"""Test if an endpoint is accessible with given credentials."""
|
||||
if not HAS_REQUESTS:
|
||||
return None
|
||||
url = f"{base_url.rstrip('/')}{endpoint}"
|
||||
headers = {"Authorization": f"Bearer {token}"} if token else {}
|
||||
try:
|
||||
resp = requests.request(method, url, headers=headers, timeout=10, verify=False)
|
||||
return {
|
||||
"endpoint": endpoint,
|
||||
"method": method,
|
||||
"status_code": resp.status_code,
|
||||
"response_size": len(resp.content),
|
||||
"accessible": resp.status_code < 400,
|
||||
}
|
||||
except requests.RequestException:
|
||||
return None
|
||||
|
||||
|
||||
def test_method_switching(base_url, endpoint, token):
|
||||
"""Test if changing HTTP method bypasses authorization."""
|
||||
results = []
|
||||
for method in HTTP_METHODS:
|
||||
result = test_endpoint_access(base_url, endpoint, token, method)
|
||||
if result and result["accessible"]:
|
||||
results.append(result)
|
||||
return results
|
||||
|
||||
|
||||
def test_privilege_escalation(base_url, low_priv_token, endpoints=None):
|
||||
"""Test if low-privilege user can access admin endpoints."""
|
||||
findings = []
|
||||
test_endpoints = endpoints or ADMIN_ENDPOINTS
|
||||
for ep in test_endpoints:
|
||||
result = test_endpoint_access(base_url, ep, low_priv_token)
|
||||
if result and result["accessible"]:
|
||||
findings.append({
|
||||
"vulnerability": "BFLA",
|
||||
"endpoint": ep,
|
||||
"status_code": result["status_code"],
|
||||
"response_size": result["response_size"],
|
||||
"severity": "HIGH",
|
||||
})
|
||||
return findings
|
||||
|
||||
|
||||
def test_idor_via_function(base_url, token, user_id, target_user_id):
|
||||
"""Test function-level auth by accessing another user's admin functions."""
|
||||
findings = []
|
||||
endpoints = [
|
||||
f"/api/users/{target_user_id}",
|
||||
f"/api/users/{target_user_id}/settings",
|
||||
f"/api/users/{target_user_id}/role",
|
||||
]
|
||||
for ep in endpoints:
|
||||
for method in ["GET", "PUT", "DELETE"]:
|
||||
result = test_endpoint_access(base_url, ep, token, method)
|
||||
if result and result["accessible"]:
|
||||
findings.append({
|
||||
"vulnerability": "BFLA+IDOR",
|
||||
"endpoint": ep,
|
||||
"method": method,
|
||||
"own_user_id": user_id,
|
||||
"target_user_id": target_user_id,
|
||||
})
|
||||
return findings
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Test Broken Function Level Authorization (authorized testing only)"
|
||||
)
|
||||
parser.add_argument("--url", required=True, help="Base API URL")
|
||||
parser.add_argument("--token", help="Low-privilege user JWT token")
|
||||
parser.add_argument("--endpoints", nargs="*", help="Custom admin endpoints to test")
|
||||
parser.add_argument("--user-id", help="Current user ID")
|
||||
parser.add_argument("--target-id", help="Target user ID for IDOR test")
|
||||
parser.add_argument("--output", "-o", help="Output JSON report")
|
||||
args = parser.parse_args()
|
||||
|
||||
print("[*] BFLA Testing Agent")
|
||||
print("[!] For authorized security testing only")
|
||||
report = {"timestamp": datetime.now(timezone.utc).isoformat(), "target": args.url, "findings": []}
|
||||
|
||||
escalation = test_privilege_escalation(args.url, args.token, args.endpoints)
|
||||
report["findings"].extend(escalation)
|
||||
print(f"[*] Privilege escalation findings: {len(escalation)}")
|
||||
|
||||
if args.user_id and args.target_id:
|
||||
idor = test_idor_via_function(args.url, args.token, args.user_id, args.target_id)
|
||||
report["findings"].extend(idor)
|
||||
print(f"[*] IDOR findings: {len(idor)}")
|
||||
|
||||
report["risk_level"] = "CRITICAL" if report["findings"] else "LOW"
|
||||
|
||||
if args.output:
|
||||
with open(args.output, "w") as f:
|
||||
json.dump(report, f, indent=2)
|
||||
print(f"[*] Report saved to {args.output}")
|
||||
else:
|
||||
print(json.dumps(report, indent=2))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user