mirror of
https://github.com/prox0959/MemGuard
synced 2026-09-25 09:04:35 +00:00
267 lines
12 KiB
Python
267 lines
12 KiB
Python
r"""
|
||
MemGuard: Zero-Dependency LSASS Memory Dump Detector & EDR Hook Shield.
|
||
Protects Windows credentials against Mimikatz, ProcDump, and LOLBin dump attacks.
|
||
|
||
Author: prox0959 (Çınar)
|
||
License: MIT
|
||
Repository: https://github.com/prox0959/MemGuard
|
||
|
||
# TR: MemGuard: Sıfır Bağımlılıklı LSASS Bellek Dökümü Dedektörü ve EDR Kalkanı.
|
||
# Windows kimlik bilgilerini Mimikatz, ProcDump ve LOLBin saldırılarına karşı korur.
|
||
"""
|
||
|
||
import sys
|
||
import os
|
||
import time
|
||
import json
|
||
import argparse
|
||
|
||
# TR: Windows 11 konsolu UTF-8 desteği (Türkçe Windows cp1254 uyumluluğu)
|
||
if sys.platform == "win32":
|
||
try:
|
||
sys.stdout.reconfigure(encoding='utf-8')
|
||
sys.stderr.reconfigure(encoding='utf-8')
|
||
except Exception:
|
||
pass
|
||
|
||
# Add local directory to path for core imports
|
||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||
|
||
from core.win_api import (
|
||
is_user_admin,
|
||
enable_debug_privilege,
|
||
get_process_snapshot,
|
||
find_lsass_process,
|
||
suspend_process
|
||
)
|
||
from core.handle_scanner import scan_lsass_handles
|
||
from core.process_auditor import audit_processes_and_cmdlines
|
||
from core.honey_dmp import scan_dump_artifacts
|
||
|
||
# ==============================================================================
|
||
# ANSI Color Codes
|
||
# ==============================================================================
|
||
RED = "\033[91m"
|
||
GREEN = "\033[92m"
|
||
YELLOW = "\033[93m"
|
||
CYAN = "\033[96m"
|
||
MAGENTA = "\033[95m"
|
||
BOLD = "\033[1m"
|
||
DIM = "\033[2m"
|
||
RESET = "\033[0m"
|
||
|
||
# ==============================================================================
|
||
# Localization Dictionary (EN / TR)
|
||
# ==============================================================================
|
||
I18N = {
|
||
"en": {
|
||
"title": "MemGuard - Zero-Dependency LSASS Memory Shield & EDR Hook Detector",
|
||
"mitre": "MITRE ATT&CK: T1003.001 (OS Credential Dumping: LSASS Memory)",
|
||
"admin_status": "Privilege Level",
|
||
"admin_true": "Elevated (Administrator) - Full Kernel Handle Access",
|
||
"admin_false": "Standard User (Non-Elevated) - Run as Admin for full handle auditing",
|
||
"debug_priv": "SeDebugPrivilege Status",
|
||
"enabled": "Enabled Successfully",
|
||
"disabled": "Not Assigned / Inactive",
|
||
"lsass_found": "Target Security Process Found",
|
||
"lsass_not_found": "LSASS process could not be identified!",
|
||
"sec_handles": "--- LSASS Handle Table Audit (NtQuerySystemInformation) ---",
|
||
"sec_procs": "--- Process Heuristics & LOLBin CommandLine Inspection ---",
|
||
"sec_dumps": "--- Dump File Artifacts & Honeypot Tripwire ---",
|
||
"no_threat_handles": "No unauthorized or suspicious handles targeting LSASS detected.",
|
||
"no_threat_procs": "No credential dumping processes or LOLBin signatures found.",
|
||
"no_threat_dumps": "No rogue memory dump (.dmp) files identified in triage directories.",
|
||
"holder": "Process",
|
||
"pid": "PID",
|
||
"handle": "Handle",
|
||
"access": "Access Mask",
|
||
"severity": "Severity",
|
||
"flags": "Granted Rights",
|
||
"action_taken": "Action Taken",
|
||
"suspended": "SUSPENDED (Frozen via NtSuspendProcess)",
|
||
"report_saved": "Forensic audit report saved to",
|
||
"monitoring": "MemGuard Real-Time Protection Active. Monitoring interval: {}s. Press Ctrl+C to stop.",
|
||
"threat_detected": "CRITICAL THREAT DETECTED!",
|
||
"summary": "Audit Summary: {} handle threats, {} process threats, {} dump artifacts."
|
||
},
|
||
"tr": {
|
||
"title": "MemGuard - Sıfır Bağımlılıklı LSASS Bellek Kalkanı ve EDR Dedektörü",
|
||
"mitre": "MITRE ATT&CK: T1003.001 (İşletim Sistemi Kimlik Bilgisi Çalma: LSASS Belleği)",
|
||
"admin_status": "Yetki Seviyesi",
|
||
"admin_true": "Yönetici (Administrator) - Tam Çekirdek Handle Erişimi Aktif",
|
||
"admin_false": "Standart Kullanıcı - Tam handle denetimi için Yönetici olarak çalıştırın",
|
||
"debug_priv": "SeDebugPrivilege Durumu",
|
||
"enabled": "Başarıyla Etkinleştirildi",
|
||
"disabled": "Atanmadı / Pasif",
|
||
"lsass_found": "Hedef Güvenlik Süreci Tespit Edildi",
|
||
"lsass_not_found": "LSASS süreci tespit edilemedi!",
|
||
"sec_handles": "--- LSASS Handle Tablosu Denetimi (NtQuerySystemInformation) ---",
|
||
"sec_procs": "--- Süreç Sezgisel Analizi ve LOLBin Komut Satırı İncelemesi ---",
|
||
"sec_dumps": "--- Bellek Dökümü (.dmp) Dosyaları ve Tuzak Denetimi ---",
|
||
"no_threat_handles": "LSASS sürecini hedef alan yetkisiz veya şüpheli açık handle bulunamadı.",
|
||
"no_threat_procs": "Şüpheli şifre çalma süreci veya LOLBin komut satırı imzası tespit edilmedi.",
|
||
"no_threat_dumps": "Geçici dizinlerde yetkisiz bellek dökümü (.dmp) dosyası bulunamadı.",
|
||
"holder": "Süreç",
|
||
"pid": "PID",
|
||
"handle": "Handle",
|
||
"access": "Erişim Maskesi",
|
||
"severity": "Tehdit Seviyesi",
|
||
"flags": "Verilen Yetkiler",
|
||
"action_taken": "Uygulanan Eylem",
|
||
"suspended": "ASKIYA ALINDI (NtSuspendProcess ile donduruldu)",
|
||
"report_saved": "Adli bilişim denetim raporu kaydedildi:",
|
||
"monitoring": "MemGuard Gerçek Zamanlı Koruma Aktif. Kontrol aralığı: {}s. Durdurmak için Ctrl+C.",
|
||
"threat_detected": "KRİTİK TEHDİT TESPİT EDİLDİ!",
|
||
"summary": "Denetim Özeti: {} handle tehdidi, {} süreç tehdidi, {} döküm dosyası."
|
||
}
|
||
}
|
||
|
||
|
||
def print_banner(lang: str):
|
||
"""Print ASCII logo and architectural header."""
|
||
t = I18N[lang]
|
||
banner = f"""
|
||
{CYAN}{BOLD}███╗ ███╗███████╗███╗ ███╗ ██████╗ ██╗ ██╗ █████╗ ██████╗ ██████╗
|
||
████╗ ████║██╔════╝████╗ ████║██╔════╝ ██║ ██║██╔══██╗██╔══██╗██╔══██╗
|
||
██╔████╔██║█████╗ ██╔████╔██║██║ ███╗██║ ██║███████║██████╔╝██║ ██║
|
||
██║╚██╔╝██║██╔══╝ ██║╚██╔╝██║██║ ██║██║ ██║██╔══██║██╔══██╗██║ ██║
|
||
██║ ╚═╝ ██║███████╗██║ ╚═╝ ██║╚██████╔╝╚██████╔╝██║ ██║██║ ██║██████╔╝
|
||
╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═════╝ {RESET}
|
||
{DIM}Zero-Dependency LSASS Memory Dump Shield & EDR Hook Detector | Pure Python{RESET}
|
||
{YELLOW}► {t['mitre']}{RESET}
|
||
"""
|
||
print(banner)
|
||
|
||
|
||
def run_audit(lang: str, auto_suspend: bool = False) -> dict:
|
||
"""
|
||
Execute a full security audit across handles, processes, and memory artifacts.
|
||
# TR: Handle'lar, süreçler ve bellek dosyaları üzerinde kapsamlı güvenlik denetimi yapar.
|
||
"""
|
||
t = I18N[lang]
|
||
is_admin = is_user_admin()
|
||
debug_priv = enable_debug_privilege() if is_admin else False
|
||
|
||
print(f"[*] {t['admin_status']}: {GREEN + t['admin_true'] if is_admin else YELLOW + t['admin_false']}{RESET}")
|
||
print(f"[*] {t['debug_priv']}: {GREEN + t['enabled'] if debug_priv else DIM + t['disabled']}{RESET}")
|
||
|
||
# 1. Snapshot processes
|
||
proc_map = get_process_snapshot()
|
||
lsass_info = find_lsass_process(proc_map)
|
||
|
||
if lsass_info:
|
||
print(f"[*] {t['lsass_found']}: {CYAN}lsass.exe{RESET} (PID: {BOLD}{lsass_info['pid']}{RESET}) | Path: {lsass_info.get('path', 'Protected')}")
|
||
else:
|
||
print(f"{RED}[!] {t['lsass_not_found']}{RESET}")
|
||
|
||
print()
|
||
# 2. System Handle Table Audit
|
||
print(f"{BOLD}{t['sec_handles']}{RESET}")
|
||
handle_threats = []
|
||
if lsass_info and is_admin:
|
||
raw_handles = scan_lsass_handles(lsass_info["pid"], proc_map)
|
||
for h in raw_handles:
|
||
# Filter unauthorized processes
|
||
if not h["is_whitelisted"]:
|
||
handle_threats.append(h)
|
||
sev_color = RED if h["severity"] == "CRITICAL" else (YELLOW if h["severity"] == "HIGH" else CYAN)
|
||
print(f" {sev_color}[{h['severity']}]{RESET} {h['holder_name']} (PID: {h['holder_pid']}) -> Handle: {h['handle_value']} | Mask: {h['access_mask']}")
|
||
print(f" {DIM}Rights: {', '.join(h['flags'])}{RESET}")
|
||
|
||
# Active mitigation if flag provided
|
||
if auto_suspend and h["is_dump_capable"]:
|
||
if suspend_process(h["holder_pid"]):
|
||
print(f" {RED}{BOLD}► {t['action_taken']}: {t['suspended']}{RESET}")
|
||
h["action"] = "SUSPENDED"
|
||
|
||
if not handle_threats:
|
||
print(f" {GREEN}✓ {t['no_threat_handles']}{RESET}")
|
||
elif not is_admin:
|
||
print(f" {YELLOW}[i] Skipped full kernel handle audit (Requires Administrator elevation).{RESET}")
|
||
|
||
print()
|
||
# 3. Process Heuristic & LOLBin Audit
|
||
print(f"{BOLD}{t['sec_procs']}{RESET}")
|
||
proc_threats = audit_processes_and_cmdlines(proc_map, lsass_info)
|
||
for p in proc_threats:
|
||
sev_color = RED if p["severity"] == "CRITICAL" else YELLOW
|
||
print(f" {sev_color}[{p['severity']}]{RESET} {p['name']} (PID: {p['pid']}) - {p['technique']}")
|
||
print(f" Reason: {p['reason']}")
|
||
if p["cmdline"]:
|
||
print(f" {DIM}CmdLine: {p['cmdline'][:120]}...{RESET}")
|
||
|
||
if auto_suspend:
|
||
if suspend_process(p["pid"]):
|
||
print(f" {RED}{BOLD}► {t['action_taken']}: {t['suspended']}{RESET}")
|
||
p["action"] = "SUSPENDED"
|
||
|
||
if not proc_threats:
|
||
print(f" {GREEN}✓ {t['no_threat_procs']}{RESET}")
|
||
|
||
print()
|
||
# 4. Dump Artifact Audit
|
||
print(f"{BOLD}{t['sec_dumps']}{RESET}")
|
||
dump_artifacts = scan_dump_artifacts()
|
||
for d in dump_artifacts:
|
||
sev_color = RED if d["severity"] == "CRITICAL" else YELLOW
|
||
print(f" {sev_color}[{d['severity']}]{RESET} Found: {d['filename']} ({d['size_mb']} MB) in {os.path.dirname(d['path'])}")
|
||
print(f" {DIM}Modified: {d['modified']}{RESET}")
|
||
|
||
if not dump_artifacts:
|
||
print(f" {GREEN}✓ {t['no_threat_dumps']}{RESET}")
|
||
|
||
print()
|
||
print(f"{BOLD}{t['summary'].format(len(handle_threats), len(proc_threats), len(dump_artifacts))}{RESET}")
|
||
|
||
return {
|
||
"timestamp": time.time(),
|
||
"is_admin": is_admin,
|
||
"lsass_info": lsass_info,
|
||
"handle_threats": handle_threats,
|
||
"process_threats": proc_threats,
|
||
"dump_artifacts": dump_artifacts
|
||
}
|
||
|
||
|
||
def main():
|
||
parser = argparse.ArgumentParser(
|
||
description="MemGuard: Zero-Dependency LSASS Memory Shield & EDR Hook Detector",
|
||
formatter_class=argparse.RawDescriptionHelpFormatter
|
||
)
|
||
parser.add_argument("--scan", action="store_true", help="Perform an immediate one-shot security audit")
|
||
parser.add_argument("--monitor", action="store_true", help="Run in continuous real-time monitoring mode")
|
||
parser.add_argument("--interval", type=int, default=3, help="Polling interval in seconds for monitor mode (default: 3)")
|
||
parser.add_argument("--suspend", action="store_true", help="Automatically suspend offending processes with dump capability")
|
||
parser.add_argument("--json", type=str, metavar="FILE", help="Export audit results to a JSON report")
|
||
parser.add_argument("--lang", choices=["en", "tr"], default="en", help="Interface language: en (English) or tr (Turkish)")
|
||
|
||
args = parser.parse_args()
|
||
print_banner(args.lang)
|
||
|
||
# Default to --scan if no mode selected
|
||
if not args.scan and not args.monitor:
|
||
args.scan = True
|
||
|
||
if args.scan:
|
||
report = run_audit(args.lang, auto_suspend=args.suspend)
|
||
if args.json:
|
||
with open(args.json, "w", encoding="utf-8") as f:
|
||
json.dump(report, f, indent=2)
|
||
print(f"\n[+] {I18N[args.lang]['report_saved']} {args.json}")
|
||
|
||
elif args.monitor:
|
||
t = I18N[args.lang]
|
||
print(f"{GREEN}[*] {t['monitoring'].format(args.interval)}{RESET}\n")
|
||
try:
|
||
while True:
|
||
os.system('cls' if os.name == 'nt' else 'clear')
|
||
print_banner(args.lang)
|
||
run_audit(args.lang, auto_suspend=args.suspend)
|
||
time.sleep(args.interval)
|
||
except KeyboardInterrupt:
|
||
print(f"\n{YELLOW}[*] Monitor stopped by user.{RESET}")
|
||
|
||
|
||
if __name__ == "__main__":
|
||
main()
|