mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-06-10 21:24:56 +03:00
c47eed6a64
- Fix 25 shell=True subprocess calls with list-based commands - Fix 49 verify=False in defensive skills (env-var override) - Add timeout to 231 HTTP/subprocess/socket calls - Fix 6 SQL injection patterns with whitelist validation - Replace 8 __import__() with standard imports - Remove 701 unused imports across 442 files - Add authorized-testing disclaimers to all offensive skills - Complete 11 incomplete skill directories - Expand 10 stub SKILL.md files with full content - Fix 2 YAML parse errors in frontmatter - Fix 5 pre-existing syntax errors - Convert 22 hardcoded paths/ports to environment variables - Back up 21 redundant skill pairs to .bak - Fix 2 global declaration errors - 724/724 skills with full folder anatomy (SKILL.md + agent.py + api-reference.md + LICENSE) - 0 compile errors across all 724 agent.py files
133 lines
5.1 KiB
Python
133 lines
5.1 KiB
Python
#!/usr/bin/env python3
|
|
"""PowerShell obfuscated malware deobfuscation agent."""
|
|
|
|
import json
|
|
import argparse
|
|
import re
|
|
import base64
|
|
from datetime import datetime
|
|
|
|
|
|
def decode_base64_commands(script_content):
|
|
"""Find and decode Base64 encoded PowerShell commands."""
|
|
decoded = []
|
|
b64_pattern = re.compile(r'-[eE](?:nc(?:odedcommand)?)\s+([A-Za-z0-9+/=]{20,})')
|
|
for match in b64_pattern.finditer(script_content):
|
|
encoded = match.group(1)
|
|
try:
|
|
raw = base64.b64decode(encoded)
|
|
text = raw.decode("utf-16-le", errors="replace")
|
|
decoded.append({"encoded": encoded[:60] + "...", "decoded": text[:500]})
|
|
except Exception:
|
|
pass
|
|
standalone_b64 = re.compile(r'["\']([A-Za-z0-9+/]{40,}={0,2})["\']')
|
|
for match in standalone_b64.finditer(script_content):
|
|
try:
|
|
raw = base64.b64decode(match.group(1))
|
|
text = raw.decode("utf-8", errors="replace")
|
|
if text.isprintable() or "http" in text.lower():
|
|
decoded.append({"encoded": match.group(1)[:60] + "...", "decoded": text[:500]})
|
|
except Exception:
|
|
pass
|
|
return decoded
|
|
|
|
|
|
def deobfuscate_string_concatenation(script_content):
|
|
"""Resolve string concatenation obfuscation."""
|
|
concat_pattern = re.compile(r"(?:'[^']*'\s*\+\s*){2,}'[^']*'")
|
|
resolved = []
|
|
for match in concat_pattern.finditer(script_content):
|
|
original = match.group(0)
|
|
parts = re.findall(r"'([^']*)'", original)
|
|
result = "".join(parts)
|
|
resolved.append({"obfuscated": original[:80], "resolved": result[:500]})
|
|
return resolved
|
|
|
|
|
|
def detect_obfuscation_techniques(script_content):
|
|
"""Identify obfuscation techniques used in the script."""
|
|
techniques = []
|
|
checks = [
|
|
(r'-[eE](?:nc(?:odedcommand)?)', "Base64 encoded command", "HIGH"),
|
|
(r'\[(?:char|int)\]\s*\d+', "Character code conversion", "MEDIUM"),
|
|
(r'(?:iex|invoke-expression)', "Invoke-Expression (IEX) execution", "HIGH"),
|
|
(r'\$\{[^}]+\}', "Variable name obfuscation with braces", "LOW"),
|
|
(r'\.(?:replace|split|reverse)\(', "String manipulation methods", "MEDIUM"),
|
|
(r'-(?:join|split)\s', "Array join/split obfuscation", "MEDIUM"),
|
|
(r'(?:Net\.WebClient|DownloadString|DownloadFile)', "Web download cradle", "CRITICAL"),
|
|
(r'(?:Start-Process|Invoke-Item|cmd\s*/c)', "Process execution", "HIGH"),
|
|
(r'\[System\.Convert\]::FromBase64String', ".NET Base64 decode", "HIGH"),
|
|
(r'(?:gci|ls|dir)\s+env:', "Environment variable access", "LOW"),
|
|
]
|
|
for pattern, name, severity in checks:
|
|
if re.search(pattern, script_content, re.IGNORECASE):
|
|
techniques.append({"technique": name, "severity": severity})
|
|
return techniques
|
|
|
|
|
|
def extract_iocs(script_content):
|
|
"""Extract indicators of compromise from deobfuscated content."""
|
|
iocs = {"urls": [], "ips": [], "domains": [], "file_paths": []}
|
|
url_pattern = re.compile(r'https?://[^\s"\'<>]+')
|
|
ip_pattern = re.compile(r'\b(?:\d{1,3}\.){3}\d{1,3}\b')
|
|
path_pattern = re.compile(r'[A-Z]:\\[\w\\]+\.\w{2,4}|/(?:tmp|var|etc)/[\w/]+')
|
|
iocs["urls"] = list(set(url_pattern.findall(script_content)))
|
|
iocs["ips"] = list(set(ip_pattern.findall(script_content)))
|
|
iocs["file_paths"] = list(set(path_pattern.findall(script_content)))
|
|
return iocs
|
|
|
|
|
|
def run_analysis(script_path):
|
|
"""Execute PowerShell deobfuscation analysis."""
|
|
print(f"\n{'='*60}")
|
|
print(f" POWERSHELL MALWARE DEOBFUSCATION")
|
|
print(f" File: {script_path}")
|
|
print(f" Generated: {datetime.utcnow().isoformat()} UTC")
|
|
print(f"{'='*60}\n")
|
|
|
|
with open(script_path, "r", errors="replace") as f:
|
|
content = f.read()
|
|
|
|
techniques = detect_obfuscation_techniques(content)
|
|
print(f"--- OBFUSCATION TECHNIQUES ({len(techniques)}) ---")
|
|
for t in techniques:
|
|
print(f" [{t['severity']}] {t['technique']}")
|
|
|
|
b64 = decode_base64_commands(content)
|
|
print(f"\n--- BASE64 DECODED ({len(b64)}) ---")
|
|
for d in b64[:5]:
|
|
print(f" {d['decoded'][:100]}")
|
|
|
|
concat = deobfuscate_string_concatenation(content)
|
|
print(f"\n--- STRING CONCAT RESOLVED ({len(concat)}) ---")
|
|
for c in concat[:5]:
|
|
print(f" {c['resolved'][:100]}")
|
|
|
|
all_decoded = content
|
|
for d in b64:
|
|
all_decoded += "\n" + d["decoded"]
|
|
iocs = extract_iocs(all_decoded)
|
|
print(f"\n--- IOCs ---")
|
|
print(f" URLs: {iocs['urls'][:5]}")
|
|
print(f" IPs: {iocs['ips'][:5]}")
|
|
print(f" Paths: {iocs['file_paths'][:5]}")
|
|
|
|
return {"techniques": techniques, "decoded_b64": b64, "concat": concat, "iocs": iocs}
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description="PowerShell Deobfuscation Agent")
|
|
parser.add_argument("--script", required=True, help="Path to obfuscated PowerShell script")
|
|
parser.add_argument("--output", help="Save report to JSON file")
|
|
args = parser.parse_args()
|
|
|
|
report = run_analysis(args.script)
|
|
if args.output:
|
|
with open(args.output, "w") as f:
|
|
json.dump(report, f, indent=2, default=str)
|
|
print(f"\n[+] Report saved to {args.output}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|