mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-09-12 11:20:51 +03:00
feat: add 5 new cybersecurity skills - RDP brute force, Covenant C2, Calico network policies, heap spray analysis, T1098 hunting
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025 Mahipal
|
||||
|
||||
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,40 @@
|
||||
---
|
||||
name: analyzing-heap-spray-exploitation
|
||||
description: Detect and analyze heap spray attacks in memory dumps using Volatility3 plugins to identify NOP sled patterns, shellcode landing zones, and suspicious large allocations in process virtual address space.
|
||||
domain: cybersecurity
|
||||
subdomain: malware-analysis
|
||||
tags: [malware-analysis, memory-forensics, heap-spray, volatility3, exploit-analysis]
|
||||
version: "1.0"
|
||||
author: mahipal
|
||||
license: MIT
|
||||
---
|
||||
# Analyzing Heap Spray Exploitation
|
||||
|
||||
## Overview
|
||||
|
||||
Heap spraying is an exploitation technique that fills large regions of a process's heap with attacker-controlled data (typically NOP sleds followed by shellcode) to increase the reliability of code execution exploits. This skill covers detecting heap spray artifacts in memory dumps using Volatility3's malfind, vadinfo, and memmap plugins, identifying suspicious contiguous memory allocations, scanning for NOP sled patterns (0x90, 0x0c0c0c0c), and extracting embedded shellcode for analysis.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Python 3.9+ with `volatility3` framework installed
|
||||
- Memory dump file (.raw, .vmem, .dmp format)
|
||||
- Understanding of virtual memory layout and VAD (Virtual Address Descriptor) trees
|
||||
- Familiarity with common shellcode patterns and NOP sled encodings
|
||||
|
||||
## Steps
|
||||
|
||||
### Step 1: Identify Suspicious Processes
|
||||
Use Volatility3 windows.malfind to scan for processes with executable injected memory regions.
|
||||
|
||||
### Step 2: Analyze VAD Entries
|
||||
Examine VAD tree entries using windows.vadinfo for large contiguous allocations with RWX permissions.
|
||||
|
||||
### Step 3: Scan for NOP Sled Patterns
|
||||
Search suspicious memory regions for NOP sled signatures (0x90 sequences, 0x0c0c0c0c patterns).
|
||||
|
||||
### Step 4: Extract and Analyze Shellcode
|
||||
Dump suspicious memory regions and identify shellcode using byte pattern analysis.
|
||||
|
||||
## Expected Output
|
||||
|
||||
JSON report with suspicious processes, heap spray indicators, NOP sled locations, memory region sizes, and extracted shellcode hashes.
|
||||
@@ -0,0 +1,55 @@
|
||||
# API Reference: Analyzing Heap Spray Exploitation
|
||||
|
||||
## Volatility3 Plugins for Heap Spray Analysis
|
||||
|
||||
| Plugin | Command | Purpose |
|
||||
|--------|---------|---------|
|
||||
| malfind | `vol -f dump.raw windows.malfind` | Find injected executable memory regions |
|
||||
| vadinfo | `vol -f dump.raw windows.vadinfo` | Virtual Address Descriptor details |
|
||||
| memmap | `vol -f dump.raw windows.memmap --pid PID --dump` | Dump process memory to files |
|
||||
| pslist | `vol -f dump.raw windows.pslist` | List running processes |
|
||||
| handles | `vol -f dump.raw windows.handles --pid PID` | List process handles |
|
||||
|
||||
## Common Heap Spray NOP Sled Patterns
|
||||
|
||||
| Pattern | Hex | Description |
|
||||
|---------|-----|-------------|
|
||||
| x86 NOP | 0x90909090 | Classic NOP instruction |
|
||||
| 0x0C landing | 0x0C0C0C0C | Common heap spray address target |
|
||||
| 0x0D landing | 0x0D0D0D0D | Alternative spray address |
|
||||
| 0x0A landing | 0x0A0A0A0A | Alternative spray address |
|
||||
| 0x41 fill | 0x41414141 | "AAAA" padding fill |
|
||||
|
||||
## Shellcode Signatures
|
||||
|
||||
| Bytes | Mnemonic | Context |
|
||||
|-------|----------|---------|
|
||||
| FC E8 | CLD; CALL | Common shellcode prologue |
|
||||
| 60 E8 | PUSHAD; CALL | Register-saving shellcode start |
|
||||
| 31 C0 50 68 | XOR EAX; PUSH; PUSH | Stack setup for API call |
|
||||
| E8 FF FF FF FF | CALL $+5 | Self-locating shellcode (GetPC) |
|
||||
|
||||
## Detection Thresholds
|
||||
|
||||
| Indicator | Threshold | Meaning |
|
||||
|-----------|-----------|---------|
|
||||
| Large allocation | >= 1 MB per region | Suspicious heap allocation |
|
||||
| Total spray size | >= 50 MB per process | Strong heap spray indicator |
|
||||
| NOP sled count | >= 20 repeated bytes | NOP sled detected |
|
||||
| RWX permissions | PAGE_EXECUTE_READWRITE | Injected executable code |
|
||||
|
||||
## Install Volatility3
|
||||
|
||||
```bash
|
||||
pip install volatility3
|
||||
# Or from source:
|
||||
git clone https://github.com/volatilityfoundation/volatility3.git
|
||||
cd volatility3 && pip install -e .
|
||||
```
|
||||
|
||||
## References
|
||||
|
||||
- Volatility3 GitHub: https://github.com/volatilityfoundation/volatility3
|
||||
- Volatility3 malfind: https://volatility3.readthedocs.io/en/latest/
|
||||
- Heap Spray Techniques: https://www.corelan.be/index.php/2011/12/31/exploit-writing-tutorial-part-11-heap-spraying-demystified/
|
||||
- DFRWS 2025 Workshop: https://webdiis.unizar.es/~ricardo/dfrws-eu-25-workshop/
|
||||
@@ -0,0 +1,219 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Agent for analyzing heap spray exploitation in memory dumps.
|
||||
|
||||
Detects heap spray artifacts using Volatility3 by scanning for
|
||||
NOP sled patterns, large contiguous allocations, and injected
|
||||
executable regions in process virtual address space.
|
||||
"""
|
||||
# For authorized forensic analysis only
|
||||
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
from collections import defaultdict
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
NOP_PATTERNS = {
|
||||
"x86_nop": b"\x90" * 16,
|
||||
"heap_spray_0c": b"\x0c" * 16,
|
||||
"heap_spray_0d": b"\x0d" * 16,
|
||||
"heap_spray_0a": b"\x0a" * 16,
|
||||
"heap_spray_04": b"\x04" * 16,
|
||||
"heap_spray_41": b"\x41" * 16,
|
||||
}
|
||||
|
||||
SHELLCODE_MARKERS = [
|
||||
b"\xfc\xe8", # CLD; CALL
|
||||
b"\x60\xe8", # PUSHAD; CALL
|
||||
b"\xeb\x10\x5a", # JMP SHORT; POP EDX
|
||||
b"\x31\xc0\x50\x68", # XOR EAX; PUSH; PUSH
|
||||
b"\xe8\xff\xff\xff\xff", # CALL $+5 (self-locating)
|
||||
]
|
||||
|
||||
SUSPICIOUS_ALLOC_THRESHOLD = 0x100000 # 1 MB
|
||||
|
||||
|
||||
class HeapSprayAnalyzer:
|
||||
"""Detects heap spray exploitation artifacts in memory dumps."""
|
||||
|
||||
def __init__(self, memory_dump, output_dir="./heap_spray_analysis"):
|
||||
self.memory_dump = memory_dump
|
||||
self.output_dir = Path(output_dir)
|
||||
self.output_dir.mkdir(parents=True, exist_ok=True)
|
||||
self.findings = []
|
||||
|
||||
def _run_vol3(self, plugin, extra_args=None):
|
||||
"""Run a Volatility3 plugin and return stdout."""
|
||||
cmd = ["vol", "-f", self.memory_dump, plugin]
|
||||
if extra_args:
|
||||
cmd.extend(extra_args)
|
||||
try:
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, timeout=300)
|
||||
return result.stdout
|
||||
except (FileNotFoundError, subprocess.TimeoutExpired):
|
||||
return ""
|
||||
|
||||
def run_malfind(self):
|
||||
"""Run windows.malfind to detect injected executable memory."""
|
||||
output = self._run_vol3("windows.malfind")
|
||||
entries = []
|
||||
current = {}
|
||||
for line in output.splitlines():
|
||||
parts = line.split()
|
||||
if len(parts) >= 6 and parts[0].isdigit():
|
||||
if current:
|
||||
entries.append(current)
|
||||
current = {
|
||||
"pid": int(parts[0]),
|
||||
"process": parts[1],
|
||||
"start_addr": parts[2],
|
||||
"end_addr": parts[3],
|
||||
"protection": parts[5] if len(parts) > 5 else "",
|
||||
}
|
||||
elif current and line.strip().startswith("0x"):
|
||||
hex_match = re.findall(r"[0-9a-fA-F]{2}", line.split(" ")[0] if " " in line else line)
|
||||
if "hex_bytes" not in current:
|
||||
current["hex_bytes"] = ""
|
||||
current["hex_bytes"] += "".join(hex_match)
|
||||
if current:
|
||||
entries.append(current)
|
||||
return entries
|
||||
|
||||
def run_vadinfo(self):
|
||||
"""Run windows.vadinfo to find large suspicious allocations."""
|
||||
output = self._run_vol3("windows.vadinfo")
|
||||
large_allocs = []
|
||||
for line in output.splitlines():
|
||||
parts = line.split()
|
||||
if len(parts) >= 5 and parts[0].isdigit():
|
||||
try:
|
||||
pid = int(parts[0])
|
||||
start = int(parts[2], 16) if parts[2].startswith("0x") else 0
|
||||
end = int(parts[3], 16) if parts[3].startswith("0x") else 0
|
||||
size = end - start
|
||||
if size >= SUSPICIOUS_ALLOC_THRESHOLD:
|
||||
large_allocs.append({
|
||||
"pid": pid, "process": parts[1],
|
||||
"start": hex(start), "end": hex(end),
|
||||
"size_bytes": size, "size_mb": round(size / (1024 * 1024), 2),
|
||||
})
|
||||
except (ValueError, IndexError):
|
||||
continue
|
||||
return large_allocs
|
||||
|
||||
def scan_dump_for_patterns(self, dump_path):
|
||||
"""Scan a memory dump file for NOP sled and shellcode patterns."""
|
||||
matches = {"nop_sleds": [], "shellcode_markers": []}
|
||||
try:
|
||||
with open(dump_path, "rb") as f:
|
||||
data = f.read()
|
||||
except (FileNotFoundError, PermissionError):
|
||||
return matches
|
||||
|
||||
for name, pattern in NOP_PATTERNS.items():
|
||||
offset = 0
|
||||
count = 0
|
||||
while True:
|
||||
idx = data.find(pattern, offset)
|
||||
if idx == -1:
|
||||
break
|
||||
count += 1
|
||||
offset = idx + len(pattern)
|
||||
if count > 100:
|
||||
break
|
||||
if count > 0:
|
||||
matches["nop_sleds"].append({"pattern": name, "occurrences": count})
|
||||
|
||||
for marker in SHELLCODE_MARKERS:
|
||||
idx = data.find(marker)
|
||||
if idx != -1:
|
||||
context = data[idx:idx + 64]
|
||||
matches["shellcode_markers"].append({
|
||||
"offset": hex(idx),
|
||||
"bytes": context.hex()[:128],
|
||||
"sha256": hashlib.sha256(context).hexdigest(),
|
||||
})
|
||||
return matches
|
||||
|
||||
def dump_process_memory(self, pid):
|
||||
"""Dump a process's memory using Volatility3 memmap."""
|
||||
dump_dir = self.output_dir / f"pid_{pid}"
|
||||
dump_dir.mkdir(exist_ok=True)
|
||||
self._run_vol3("windows.memmap", ["--pid", str(pid), "--dump",
|
||||
"--output-dir", str(dump_dir)])
|
||||
dumps = list(dump_dir.glob("*.dmp"))
|
||||
return [str(d) for d in dumps]
|
||||
|
||||
def analyze(self):
|
||||
"""Run full heap spray analysis pipeline."""
|
||||
malfind_results = self.run_malfind()
|
||||
large_allocs = self.run_vadinfo()
|
||||
|
||||
spray_candidates = defaultdict(list)
|
||||
for alloc in large_allocs:
|
||||
spray_candidates[alloc["pid"]].append(alloc)
|
||||
|
||||
for pid, allocs in spray_candidates.items():
|
||||
total_mb = sum(a["size_mb"] for a in allocs)
|
||||
if total_mb > 50:
|
||||
self.findings.append({
|
||||
"severity": "high", "type": "Heap Spray Indicator",
|
||||
"detail": f"PID {pid}: {total_mb:.1f} MB in {len(allocs)} large allocations",
|
||||
})
|
||||
|
||||
for entry in malfind_results:
|
||||
hex_bytes = entry.get("hex_bytes", "")
|
||||
if hex_bytes.count("90") > 20 or hex_bytes.count("0c") > 20:
|
||||
self.findings.append({
|
||||
"severity": "critical", "type": "NOP Sled in Injected Region",
|
||||
"detail": f"PID {entry['pid']} ({entry['process']}): "
|
||||
f"NOP sled at {entry['start_addr']}",
|
||||
})
|
||||
|
||||
return {
|
||||
"malfind_entries": malfind_results,
|
||||
"large_allocations": large_allocs,
|
||||
"spray_candidate_pids": list(spray_candidates.keys()),
|
||||
}
|
||||
|
||||
def generate_report(self):
|
||||
analysis = self.analyze()
|
||||
|
||||
report = {
|
||||
"report_date": datetime.utcnow().isoformat(),
|
||||
"memory_dump": self.memory_dump,
|
||||
"malfind_count": len(analysis["malfind_entries"]),
|
||||
"large_allocation_count": len(analysis["large_allocations"]),
|
||||
**analysis,
|
||||
"findings": self.findings,
|
||||
"total_findings": len(self.findings),
|
||||
}
|
||||
out = self.output_dir / "heap_spray_report.json"
|
||||
with open(out, "w") as f:
|
||||
json.dump(report, f, indent=2, default=str)
|
||||
print(json.dumps(report, indent=2, default=str))
|
||||
return report
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Analyze memory dumps for heap spray exploitation artifacts"
|
||||
)
|
||||
parser.add_argument("memory_dump", help="Path to memory dump file (.raw, .vmem, .dmp)")
|
||||
parser.add_argument("--output-dir", default="./heap_spray_analysis",
|
||||
help="Output directory for report and dumps")
|
||||
parser.add_argument("--alloc-threshold", type=int, default=0x100000,
|
||||
help="Minimum allocation size in bytes to flag (default: 1MB)")
|
||||
args = parser.parse_args()
|
||||
|
||||
os.makedirs(args.output_dir, exist_ok=True)
|
||||
analyzer = HeapSprayAnalyzer(args.memory_dump, output_dir=args.output_dir)
|
||||
analyzer.generate_report()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user