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.
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
# API Reference: Thick Client Penetration Testing
|
||||
|
||||
## Analysis Tools
|
||||
|
||||
| Tool | Purpose | Target |
|
||||
|------|---------|--------|
|
||||
| dnSpy | .NET decompilation and debugging | .NET Framework/Core apps |
|
||||
| ILSpy | .NET decompilation (read-only) | .NET assemblies |
|
||||
| JD-GUI / JADX | Java decompilation | JAR/APK files |
|
||||
| Ghidra / IDA Pro | Native binary reverse engineering | C/C++ executables |
|
||||
| Procmon | File/registry/network activity monitoring | Any Windows app |
|
||||
| Process Hacker | Process inspection, memory, DLLs | Running processes |
|
||||
| Burp Suite | HTTP/HTTPS traffic interception | Client-server communication |
|
||||
| Echo Mirage | TCP/UDP traffic interception | Non-HTTP protocols |
|
||||
| Frida | Dynamic instrumentation | Any platform |
|
||||
|
||||
## Static Analysis Targets
|
||||
|
||||
| Target | Search Pattern | Risk |
|
||||
|--------|---------------|------|
|
||||
| Hardcoded credentials | `password`, `secret`, `apikey` in strings | Critical |
|
||||
| Connection strings | `jdbc:`, `Server=`, `mongodb://` | Critical |
|
||||
| SQL queries | `SELECT`, `INSERT`, `UPDATE` | Medium |
|
||||
| URLs and endpoints | `http://`, `https://` | Info |
|
||||
| Disabled SSL validation | `ServerCertificateValidationCallback` | High |
|
||||
|
||||
## DLL Hijacking Detection
|
||||
|
||||
| Step | Tool | Action |
|
||||
|------|------|--------|
|
||||
| 1 | Procmon | Filter: `Result = NAME NOT FOUND`, `Path ends with .dll` |
|
||||
| 2 | Check | Verify if DLL search path includes writable directories |
|
||||
| 3 | Validate | Test with benign DLL in writable directory |
|
||||
|
||||
## Local Storage Locations
|
||||
|
||||
| Location | Type | Risk |
|
||||
|----------|------|------|
|
||||
| `%APPDATA%\<app>` | Config, SQLite | Credential storage |
|
||||
| `%LOCALAPPDATA%\<app>` | Cache, logs | Data leakage |
|
||||
| `HKCU\Software\<app>` | Registry settings | Stored credentials |
|
||||
| App install directory | Config files | Hardcoded secrets |
|
||||
|
||||
## Python Libraries
|
||||
|
||||
| Library | Version | Purpose |
|
||||
|---------|---------|---------|
|
||||
| `sqlite3` | stdlib | Audit local SQLite databases |
|
||||
| `re` | stdlib | Pattern matching for credentials/URLs |
|
||||
| `subprocess` | stdlib | Execute system analysis tools |
|
||||
| `pathlib` | stdlib | File system traversal |
|
||||
|
||||
## References
|
||||
|
||||
- OWASP Thick Client Top 10: https://owasp.org/www-project-thick-client-top-10/
|
||||
- dnSpy: https://github.com/dnSpy/dnSpy
|
||||
- Procmon: https://learn.microsoft.com/en-us/sysinternals/downloads/procmon
|
||||
- Frida: https://frida.re/docs/home/
|
||||
@@ -0,0 +1,203 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Agent for thick client application penetration testing.
|
||||
|
||||
Performs static analysis (strings extraction, .NET detection),
|
||||
dynamic analysis (process monitoring, DLL search order checks),
|
||||
local storage auditing, and API traffic interception assessment.
|
||||
"""
|
||||
|
||||
import subprocess
|
||||
import json
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
import sqlite3
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
class ThickClientPentestAgent:
|
||||
"""Performs security assessment of thick/fat client applications."""
|
||||
|
||||
def __init__(self, app_path, output_dir="./thick_client_pentest"):
|
||||
self.app_path = Path(app_path)
|
||||
self.output_dir = Path(output_dir)
|
||||
self.output_dir.mkdir(parents=True, exist_ok=True)
|
||||
self.findings = []
|
||||
|
||||
def extract_strings(self, min_length=6):
|
||||
"""Extract readable strings from binary for credential/URL discovery."""
|
||||
patterns = {
|
||||
"url": re.compile(r'https?://[^\s"\'<>]{5,200}'),
|
||||
"email": re.compile(r'[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}'),
|
||||
"ip_addr": re.compile(r'\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b'),
|
||||
"password_hint": re.compile(
|
||||
r'(?i)(password|passwd|pwd|secret|api.?key|token|'
|
||||
r'connectionstring|jdbc|bearer)', re.IGNORECASE),
|
||||
"sql_query": re.compile(r'(?i)(SELECT|INSERT|UPDATE|DELETE)\s+', re.IGNORECASE),
|
||||
}
|
||||
results = {k: [] for k in patterns}
|
||||
try:
|
||||
with open(self.app_path, "rb") as f:
|
||||
data = f.read()
|
||||
text = data.decode("ascii", errors="ignore")
|
||||
for name, pattern in patterns.items():
|
||||
matches = pattern.findall(text)
|
||||
results[name] = list(set(matches))[:50]
|
||||
|
||||
if results["password_hint"]:
|
||||
self.findings.append({
|
||||
"type": "Credential Reference in Binary",
|
||||
"severity": "Medium",
|
||||
"details": f"Found {len(results['password_hint'])} credential-related strings",
|
||||
})
|
||||
if results["sql_query"]:
|
||||
self.findings.append({
|
||||
"type": "SQL Queries in Binary",
|
||||
"severity": "Medium",
|
||||
"details": "Embedded SQL may be vulnerable to injection",
|
||||
})
|
||||
except (OSError, PermissionError) as exc:
|
||||
results["error"] = str(exc)
|
||||
return results
|
||||
|
||||
def detect_framework(self):
|
||||
"""Detect the application framework (.NET, Java, Electron, C++)."""
|
||||
try:
|
||||
with open(self.app_path, "rb") as f:
|
||||
header = f.read(4096)
|
||||
|
||||
if b"BSJB" in header or b".NET" in header or b"mscorlib" in header:
|
||||
return {"framework": ".NET", "decompiler": "dnSpy / ILSpy"}
|
||||
if b"PK" in header[:4]:
|
||||
return {"framework": "Java (JAR)", "decompiler": "JD-GUI / JADX"}
|
||||
if b"asar" in header or b"electron" in header:
|
||||
return {"framework": "Electron", "tool": "asar extract"}
|
||||
return {"framework": "Native (C/C++)", "decompiler": "Ghidra / IDA Pro"}
|
||||
except OSError as exc:
|
||||
return {"error": str(exc)}
|
||||
|
||||
def check_local_storage(self, app_name=None):
|
||||
"""Scan common local storage locations for sensitive data."""
|
||||
app_name = app_name or self.app_path.stem
|
||||
locations = []
|
||||
appdata = os.environ.get("APPDATA", "")
|
||||
localappdata = os.environ.get("LOCALAPPDATA", "")
|
||||
|
||||
search_dirs = [
|
||||
Path(appdata) / app_name if appdata else None,
|
||||
Path(localappdata) / app_name if localappdata else None,
|
||||
self.app_path.parent,
|
||||
]
|
||||
sensitive_exts = {".db", ".sqlite", ".sqlite3", ".json", ".xml",
|
||||
".config", ".ini", ".cfg", ".log"}
|
||||
|
||||
for search_dir in search_dirs:
|
||||
if search_dir is None or not search_dir.exists():
|
||||
continue
|
||||
for root, dirs, files in os.walk(search_dir):
|
||||
for fname in files:
|
||||
fpath = Path(root) / fname
|
||||
if fpath.suffix.lower() in sensitive_exts:
|
||||
size = fpath.stat().st_size
|
||||
locations.append({
|
||||
"path": str(fpath), "type": fpath.suffix,
|
||||
"size_bytes": size,
|
||||
})
|
||||
|
||||
if locations:
|
||||
self.findings.append({
|
||||
"type": "Sensitive Local Files",
|
||||
"severity": "Medium",
|
||||
"details": f"Found {len(locations)} potentially sensitive files",
|
||||
})
|
||||
return locations
|
||||
|
||||
def audit_sqlite_databases(self, db_paths):
|
||||
"""Check local SQLite databases for plaintext credentials."""
|
||||
results = []
|
||||
for db_path in db_paths:
|
||||
try:
|
||||
conn = sqlite3.connect(f"file:{db_path}?mode=ro", uri=True)
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("SELECT name FROM sqlite_master WHERE type='table'")
|
||||
tables = [r[0] for r in cursor.fetchall()]
|
||||
|
||||
sensitive_tables = []
|
||||
for table in tables:
|
||||
lower = table.lower()
|
||||
if any(kw in lower for kw in
|
||||
["user", "account", "credential", "auth",
|
||||
"login", "password", "token", "session"]):
|
||||
cursor.execute(f'SELECT COUNT(*) FROM "{table}"')
|
||||
count = cursor.fetchone()[0]
|
||||
sensitive_tables.append({"table": table, "rows": count})
|
||||
|
||||
if sensitive_tables:
|
||||
self.findings.append({
|
||||
"type": "Sensitive SQLite Database",
|
||||
"severity": "High",
|
||||
"details": f"{db_path}: {sensitive_tables}",
|
||||
})
|
||||
results.append({"database": db_path, "tables": tables,
|
||||
"sensitive_tables": sensitive_tables})
|
||||
conn.close()
|
||||
except sqlite3.Error as exc:
|
||||
results.append({"database": db_path, "error": str(exc)})
|
||||
return results
|
||||
|
||||
def check_dll_hijack_paths(self):
|
||||
"""Check for DLL hijacking via writable directories in PATH."""
|
||||
writable_dirs = []
|
||||
path_dirs = os.environ.get("PATH", "").split(os.pathsep)
|
||||
for d in path_dirs:
|
||||
if os.path.isdir(d) and os.access(d, os.W_OK):
|
||||
writable_dirs.append(d)
|
||||
|
||||
app_dir = str(self.app_path.parent)
|
||||
app_dir_writable = os.access(app_dir, os.W_OK)
|
||||
|
||||
if writable_dirs or app_dir_writable:
|
||||
self.findings.append({
|
||||
"type": "DLL Hijacking Risk",
|
||||
"severity": "High",
|
||||
"details": f"Writable PATH dirs: {len(writable_dirs)}, "
|
||||
f"App dir writable: {app_dir_writable}",
|
||||
})
|
||||
return {"writable_path_dirs": writable_dirs,
|
||||
"app_dir_writable": app_dir_writable}
|
||||
|
||||
def generate_report(self):
|
||||
"""Generate comprehensive pentest findings report."""
|
||||
report = {
|
||||
"target": str(self.app_path),
|
||||
"report_date": datetime.utcnow().isoformat(),
|
||||
"framework": self.detect_framework(),
|
||||
"total_findings": len(self.findings),
|
||||
"critical": sum(1 for f in self.findings if f["severity"] == "Critical"),
|
||||
"high": sum(1 for f in self.findings if f["severity"] == "High"),
|
||||
"medium": sum(1 for f in self.findings if f["severity"] == "Medium"),
|
||||
"findings": self.findings,
|
||||
}
|
||||
report_path = self.output_dir / "thick_client_report.json"
|
||||
with open(report_path, "w") as f:
|
||||
json.dump(report, f, indent=2)
|
||||
print(json.dumps(report, indent=2))
|
||||
return report
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 2:
|
||||
print("Usage: agent.py <application.exe> [output_dir]")
|
||||
sys.exit(1)
|
||||
app_path = sys.argv[1]
|
||||
output_dir = sys.argv[2] if len(sys.argv) > 2 else "./thick_client_pentest"
|
||||
agent = ThickClientPentestAgent(app_path, output_dir)
|
||||
agent.extract_strings()
|
||||
agent.check_local_storage()
|
||||
agent.check_dll_hijack_paths()
|
||||
agent.generate_report()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user