mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-08-26 19:29:41 +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:
@@ -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,84 @@
|
||||
# API Reference: Race Condition Vulnerability Testing
|
||||
|
||||
## Types of Race Conditions
|
||||
|
||||
| Type | Description | Example |
|
||||
|------|-------------|---------|
|
||||
| TOCTOU | Time-of-check to time-of-use | Balance check then debit |
|
||||
| Double-spend | Multiple withdrawals before balance update | Gift card reuse |
|
||||
| Limit bypass | Concurrent requests bypass rate limits | Coupon reuse |
|
||||
| State mutation | Concurrent writes corrupt state | Inventory overselling |
|
||||
|
||||
## Python Threading for Concurrent Requests
|
||||
|
||||
### Barrier Synchronization
|
||||
```python
|
||||
import threading
|
||||
barrier = threading.Barrier(10)
|
||||
|
||||
def worker():
|
||||
barrier.wait() # All threads release simultaneously
|
||||
requests.post(url, json=data)
|
||||
|
||||
threads = [threading.Thread(target=worker) for _ in range(10)]
|
||||
for t in threads: t.start()
|
||||
for t in threads: t.join()
|
||||
```
|
||||
|
||||
## Turbo Intruder (Burp Suite)
|
||||
|
||||
### Race Condition Script
|
||||
```python
|
||||
def queueRequests(target, wordlists):
|
||||
engine = RequestEngine(endpoint=target.endpoint,
|
||||
concurrentConnections=30,
|
||||
requestsPerConnection=100,
|
||||
pipeline=False)
|
||||
for i in range(30):
|
||||
engine.queue(target.req)
|
||||
|
||||
def handleResponse(req, interesting):
|
||||
table.add(req)
|
||||
```
|
||||
|
||||
## HTTP/2 Single-Packet Attack
|
||||
|
||||
### Concept
|
||||
Send multiple requests in a single TCP packet using HTTP/2 multiplexing
|
||||
to eliminate network jitter and maximize race window.
|
||||
|
||||
### curl Example
|
||||
```bash
|
||||
# Send 10 requests simultaneously via HTTP/2
|
||||
for i in $(seq 1 10); do
|
||||
curl -X POST https://target/api/redeem \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"coupon": "SAVE50"}' &
|
||||
done
|
||||
wait
|
||||
```
|
||||
|
||||
## Analysis Indicators
|
||||
|
||||
| Indicator | Meaning |
|
||||
|-----------|---------|
|
||||
| Multiple 200 responses | Operation executed multiple times |
|
||||
| Different response bodies | State changed between requests |
|
||||
| Mixed status codes | Inconsistent handling |
|
||||
|
||||
## Common Vulnerable Operations
|
||||
|
||||
| Operation | Impact |
|
||||
|-----------|--------|
|
||||
| Coupon/voucher redemption | Financial loss |
|
||||
| Money transfer | Double-spend |
|
||||
| Like/vote submission | Manipulation |
|
||||
| Account creation | Duplicate accounts |
|
||||
| File upload | Overwrite race |
|
||||
|
||||
## Remediation
|
||||
1. Use database-level locking (`SELECT ... FOR UPDATE`)
|
||||
2. Implement idempotency keys
|
||||
3. Use atomic operations (e.g., `UPDATE balance = balance - X WHERE balance >= X`)
|
||||
4. Apply distributed locks (Redis SETNX)
|
||||
5. Implement optimistic concurrency (version fields)
|
||||
@@ -0,0 +1,121 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Agent for testing race condition (TOCTOU) vulnerabilities in web applications."""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import sys
|
||||
import threading
|
||||
import time
|
||||
from datetime import datetime, timezone
|
||||
|
||||
try:
|
||||
import requests
|
||||
HAS_REQUESTS = True
|
||||
except ImportError:
|
||||
HAS_REQUESTS = False
|
||||
|
||||
|
||||
def send_concurrent_requests(url, method, data, headers, count, results_list):
|
||||
"""Send multiple identical requests concurrently to trigger race conditions."""
|
||||
if not HAS_REQUESTS:
|
||||
return
|
||||
barrier = threading.Barrier(count)
|
||||
|
||||
def worker(idx):
|
||||
try:
|
||||
barrier.wait(timeout=5)
|
||||
if method == "POST":
|
||||
resp = requests.post(url, json=data, headers=headers, timeout=15, verify=False)
|
||||
elif method == "PUT":
|
||||
resp = requests.put(url, json=data, headers=headers, timeout=15, verify=False)
|
||||
else:
|
||||
resp = requests.get(url, headers=headers, timeout=15, verify=False)
|
||||
results_list.append({
|
||||
"thread": idx,
|
||||
"status_code": resp.status_code,
|
||||
"response_length": len(resp.content),
|
||||
"response_preview": resp.text[:200],
|
||||
"elapsed": resp.elapsed.total_seconds(),
|
||||
})
|
||||
except Exception as e:
|
||||
results_list.append({"thread": idx, "error": str(e)[:100]})
|
||||
|
||||
threads = []
|
||||
for i in range(count):
|
||||
t = threading.Thread(target=worker, args=(i,))
|
||||
threads.append(t)
|
||||
t.start()
|
||||
for t in threads:
|
||||
t.join(timeout=20)
|
||||
|
||||
|
||||
def analyze_results(results):
|
||||
"""Analyze concurrent request results for race condition indicators."""
|
||||
indicators = []
|
||||
success_count = sum(1 for r in results if r.get("status_code") == 200)
|
||||
if success_count > 1:
|
||||
indicators.append(f"{success_count} successful responses (expected 1 for idempotent operations)")
|
||||
|
||||
response_bodies = [r.get("response_preview", "") for r in results if r.get("status_code") == 200]
|
||||
unique_bodies = set(response_bodies)
|
||||
if len(unique_bodies) > 1:
|
||||
indicators.append(f"Different response bodies across concurrent requests: {len(unique_bodies)} unique")
|
||||
|
||||
status_codes = [r.get("status_code") for r in results if r.get("status_code")]
|
||||
if len(set(status_codes)) > 1:
|
||||
indicators.append(f"Mixed status codes: {set(status_codes)}")
|
||||
|
||||
return indicators
|
||||
|
||||
|
||||
def test_race_condition(url, method, data, token, concurrency):
|
||||
"""Execute race condition test."""
|
||||
headers = {"Authorization": f"Bearer {token}"} if token else {}
|
||||
headers["Content-Type"] = "application/json"
|
||||
results = []
|
||||
send_concurrent_requests(url, method, data, headers, concurrency, results)
|
||||
indicators = analyze_results(results)
|
||||
return {
|
||||
"url": url,
|
||||
"method": method,
|
||||
"concurrency": concurrency,
|
||||
"responses": results,
|
||||
"race_indicators": indicators,
|
||||
"potential_race": len(indicators) > 0,
|
||||
}
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Test race condition vulnerabilities (authorized testing only)"
|
||||
)
|
||||
parser.add_argument("--url", required=True, help="Target URL")
|
||||
parser.add_argument("--method", default="POST", choices=["GET", "POST", "PUT"])
|
||||
parser.add_argument("--data", default="{}", help="JSON payload")
|
||||
parser.add_argument("--token", help="Bearer token")
|
||||
parser.add_argument("--concurrency", type=int, default=10, help="Concurrent requests")
|
||||
parser.add_argument("--output", "-o", help="Output JSON report")
|
||||
args = parser.parse_args()
|
||||
|
||||
print("[*] Race Condition Testing Agent")
|
||||
print("[!] For authorized security testing only")
|
||||
data = json.loads(args.data)
|
||||
result = test_race_condition(args.url, args.method, data, args.token, args.concurrency)
|
||||
|
||||
report = {
|
||||
"timestamp": datetime.now(timezone.utc).isoformat(),
|
||||
"test_result": result,
|
||||
"risk_level": "HIGH" if result["potential_race"] else "LOW",
|
||||
}
|
||||
print(f"[*] Race condition detected: {result['potential_race']}")
|
||||
|
||||
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