mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-06-11 05:34:55 +03:00
c21af3347e
- 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
122 lines
4.2 KiB
Python
122 lines
4.2 KiB
Python
#!/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()
|