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:
mukul975
2026-03-10 21:02:12 +01:00
parent c74d52fa30
commit 27c6414ca5
1390 changed files with 106806 additions and 0 deletions
@@ -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,103 @@
# API Reference: Process Hollowing Detection
## MITRE ATT&CK Mapping
- **Technique**: T1055.012 — Process Hollowing
- **Tactic**: Defense Evasion, Privilege Escalation
## Windows API Functions Used in Hollowing
### CreateProcessA/W (kernel32.dll)
```c
BOOL CreateProcessW(
LPCWSTR lpApplicationName,
LPWSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags, // CREATE_SUSPENDED = 0x4
LPVOID lpEnvironment,
LPCWSTR lpCurrentDirectory,
LPSTARTUPINFOW lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
);
```
### NtUnmapViewOfSection (ntdll.dll)
```c
NTSTATUS NtUnmapViewOfSection(
HANDLE ProcessHandle,
PVOID BaseAddress
);
```
### VirtualAllocEx (kernel32.dll)
```c
LPVOID VirtualAllocEx(
HANDLE hProcess,
LPVOID lpAddress,
SIZE_T dwSize,
DWORD flAllocationType,
DWORD flProtect // PAGE_EXECUTE_READWRITE = 0x40
);
```
### WriteProcessMemory (kernel32.dll)
```c
BOOL WriteProcessMemory(
HANDLE hProcess,
LPVOID lpBaseAddress,
LPCVOID lpBuffer,
SIZE_T nSize,
SIZE_T *lpNumberOfBytesWritten
);
```
### ResumeThread (kernel32.dll)
```c
DWORD ResumeThread(HANDLE hThread);
```
## Detection via Linux /proc Filesystem
### /proc/[pid]/exe
Symlink to the actual executable. If deleted or replaced, shows `(deleted)`.
### /proc/[pid]/maps
```
address perms offset dev inode pathname
00400000-00452000 r-xp 00000000 08:02 173521 /usr/bin/target
```
### /proc/[pid]/status
```
Name: svchost
Pid: 1234
PPid: 567
VmExe: 512 kB
```
## Sysmon Event IDs for Detection
| Event ID | Description |
|----------|-------------|
| 1 | Process Create (check CREATE_SUSPENDED flag) |
| 8 | CreateRemoteThread |
| 10 | ProcessAccess (PROCESS_VM_WRITE + PROCESS_VM_OPERATION) |
| 25 | ProcessTampering (image replaced) |
## PowerShell Detection Queries
### Get process with module mismatch
```powershell
Get-Process | Where-Object {
$_.Path -and $_.MainModule.FileName -and
($_.Path -ne $_.MainModule.FileName)
}
```
### Check for suspended child processes
```powershell
Get-CimInstance Win32_Process | Where-Object {
$_.ExecutionState -eq 'Suspended'
} | Select-Object ProcessId, Name, ParentProcessId, CommandLine
```
@@ -0,0 +1,161 @@
#!/usr/bin/env python3
"""Agent for detecting process hollowing (T1055.012) in running processes."""
import argparse
import ctypes
import json
import os
import struct
import subprocess
import sys
from datetime import datetime, timezone
def get_running_processes():
"""Enumerate running processes via tasklist or ps."""
procs = []
if sys.platform == "win32":
out = subprocess.check_output(
["tasklist", "/FO", "CSV", "/NH", "/V"], text=True, errors="replace"
)
for line in out.strip().splitlines():
parts = line.strip('"').split('","')
if len(parts) >= 2:
procs.append({"name": parts[0], "pid": int(parts[1])})
else:
out = subprocess.check_output(
["ps", "-eo", "pid,ppid,comm,args", "--no-headers"], text=True
)
for line in out.strip().splitlines():
fields = line.split(None, 3)
if len(fields) >= 3:
procs.append({
"pid": int(fields[0]),
"ppid": int(fields[1]),
"name": fields[2],
"cmdline": fields[3] if len(fields) > 3 else "",
})
return procs
def check_memory_discrepancy_linux(pid):
"""Check for signs of hollowing: discrepancy between mapped exe and memory."""
indicators = []
exe_link = f"/proc/{pid}/exe"
maps_file = f"/proc/{pid}/maps"
try:
real_exe = os.readlink(exe_link)
if " (deleted)" in real_exe:
indicators.append(f"exe link points to deleted binary: {real_exe}")
except (OSError, PermissionError):
return indicators
try:
with open(maps_file, "r") as f:
maps = f.read()
exe_base = os.path.basename(real_exe)
first_exec_region = None
for line in maps.splitlines():
if "r-xp" in line:
first_exec_region = line
break
if first_exec_region and exe_base not in first_exec_region:
indicators.append(
f"Executable memory region does not reference expected binary: {first_exec_region}"
)
except (OSError, PermissionError):
pass
return indicators
def check_hollowing_windows(pid):
"""Use Windows API to detect hollowing via PEB image base vs section."""
indicators = []
try:
result = subprocess.check_output(
["powershell", "-NoProfile", "-Command",
f"Get-Process -Id {pid} | Select-Object Id,ProcessName,Path,"
"MainModule,StartTime | ConvertTo-Json"],
text=True, errors="replace", timeout=10
)
data = json.loads(result)
if data.get("Path") and data.get("MainModule"):
mod_path = data["MainModule"].get("FileName", "")
if mod_path and data["Path"].lower() != mod_path.lower():
indicators.append(
f"Process path mismatch: Path={data['Path']} MainModule={mod_path}"
)
except (subprocess.SubprocessError, json.JSONDecodeError, KeyError):
pass
return indicators
def analyze_process(pid):
"""Analyze a single process for hollowing indicators."""
if sys.platform == "win32":
return check_hollowing_windows(pid)
return check_memory_discrepancy_linux(pid)
def scan_all(target_pids=None):
"""Scan processes for process hollowing indicators."""
results = []
procs = get_running_processes()
targets = procs if not target_pids else [p for p in procs if p["pid"] in target_pids]
for proc in targets:
pid = proc["pid"]
indicators = analyze_process(pid)
entry = {
"pid": pid,
"name": proc.get("name", "unknown"),
"hollowing_indicators": indicators,
"suspicious": len(indicators) > 0,
}
results.append(entry)
return results
def main():
parser = argparse.ArgumentParser(
description="Detect process hollowing (T1055.012) in running processes"
)
parser.add_argument("--pid", type=int, nargs="*", help="Specific PIDs to scan")
parser.add_argument("--output", "-o", help="Output JSON file path")
parser.add_argument("--verbose", "-v", action="store_true", help="Verbose output")
args = parser.parse_args()
print("[*] Process Hollowing Detection Agent")
print(f"[*] Platform: {sys.platform}")
print(f"[*] Scan started: {datetime.now(timezone.utc).isoformat()}")
results = scan_all(target_pids=args.pid)
suspicious = [r for r in results if r["suspicious"]]
report = {
"scan_time": datetime.now(timezone.utc).isoformat(),
"platform": sys.platform,
"total_scanned": len(results),
"suspicious_count": len(suspicious),
"suspicious_processes": suspicious,
}
if args.verbose:
for r in results:
status = "SUSPICIOUS" if r["suspicious"] else "OK"
print(f" [{status}] PID {r['pid']} ({r['name']})")
for ind in r.get("hollowing_indicators", []):
print(f" -> {ind}")
print(f"\n[*] Scanned {len(results)} processes, {len(suspicious)} suspicious")
if args.output:
with open(args.output, "w") as f:
json.dump(report, f, indent=2)
print(f"[*] Report saved to {args.output}")
else:
print(json.dumps(report, indent=2))
if __name__ == "__main__":
main()