Skip to content

Repository files navigation

MostShittyEDR Logo


MostShittyEDR

The World's Most Intentionally Terrible Endpoint Detection & Response Agent

Nim License Platform Status

An educational EDR agent built in Nim with an optional kernel driver for learning detection techniques and their bypasses.

FeaturesQuick StartDriver ModeChallengesArchitectureEDR ExplainedResources


Overview

MostShittyEDR is a deliberately weak EDR agent designed for security research, education, and red team training. It implements detection methods that mirror real-world EDR engines but with intentional weaknesses mapped to 42 bypass challenges across 11 categories.

The project has two operating modes:

  • User-mode (default) — polls processes via Toolhelp32 snapshots
  • Kernel-mode (--driver) — receives real-time events from a kernel driver via IOCTLs, with kernel-level process blocking, LSASS handle protection, and hardware-enforced kill

"If you can't bypass this, you definitely need more practice"

⚠️ Disclaimer: This is NOT production security software. It's an educational tool for understanding EDR evasion techniques.


Features

9 Detection Rules

Rule Method Action
1 Process Name Blacklist (12 names) BLOCKS
2 Command Line Keywords (substring) BLOCKS
3 Reconnaissance Detection discard
4 LSASS Dump Detection (dual condition) BLOCKS
5 PowerShell Analysis (flags) BLOCKS
6 Hash-Based Detection (SHA256, --signatures) BLOCKS
7 Hooked API Import Detection (--profile) ALERTS
8 ETW Integrity Check BLOCKS
9 PE Structure Analysis (packer/header) ALERTS

Technical Features

  • Dual-mode monitoring

    • User-mode: Toolhelp32 snapshot polling
    • Kernel-mode: driver callbacks via --driver
  • Kernel driver integration

    • Process/thread creation callbacks
    • LSASS handle guard (ObRegisterCallbacks)
    • Kernel-level process blocking & termination
    • Overlapped I/O with async event delivery
  • EDR hook profiles

    • Real hook data from CrowdStrike, Carbon Black, Cylance, Bitdefender, Cortex, Checkpoint
  • ETW telemetry

    • Custom ETW provider & trace session
    • Integrity monitoring (tamper detection)

Quick Start

Prerequisites

  • Windows 10/11 (64-bit)
  • Nim 2.0+ with MinGW
winget install nim-lang.Nim

Build & Run

# Install dependencies and build
make build

# Or manually:
nimble install winim -y
nim c -d:release --opt:size -o:edr_agent.exe src/edr_agent.nim

# Run in detection-only mode
.\edr_agent.exe --verbose --no-kill

# Run with hash signatures
.\edr_agent.exe --verbose --signatures signatures/malware_hashes.txt

# Run with EDR hook profile
.\edr_agent.exe --verbose --profile crowdstrike

# Run with kernel driver (requires loaded driver + admin)
.\edr_agent.exe --driver --verbose

Command-Line Options

Flag Description
--verbose, -v Show all new processes (not just detections)
--no-kill, -n Detect but don't terminate processes
--interval MS Set polling interval in ms (default: 500, min: 50)
--profile NAME Load EDR hook profile for Rule 7
--signatures FILE Load SHA256 hash signatures for Rule 6
--driver Connect to kernel driver for real-time monitoring
--no-etw Disable ETW telemetry provider and Rule 8
--list-profiles Show available hook profiles

Lab Usage

# Terminal 1: Start the EDR agent
.\edr_agent.exe --verbose --no-kill --signatures signatures/malware_hashes.txt

# Terminal 2: Try to execute commands without being detected
whoami          # This WILL be detected (Rule 3, but discarded)
mimikatz.exe    # This WILL be blocked (Rule 1)
# Can you find a way that won't be?

Kernel Driver Mode

The --driver flag connects the agent to the kernel driver (\\.\MostShittyEDR) for real-time, event-driven monitoring instead of user-mode polling.

What the driver provides

  • Process creation callbacks via PsSetCreateProcessNotifyRoutineEx — every process start/exit is observed
  • Thread creation callbacks via PsSetCreateThreadNotifyRoutine — thread lifecycle events
  • LSASS handle protection via ObRegisterCallbacks — strips PROCESS_VM_READ and PROCESS_QUERY_INFORMATION from LSASS handles
  • Kernel-level block rules — the agent pushes block rules (process name + command-line patterns) to the kernel, which can deny process creation before it starts
  • Kernel-level process termination — uses ZwTerminateProcess from ring 0 instead of user-mode TerminateProcess

Communication protocol

The agent communicates with the driver via 5 IOCTLs over \\.\MostShittyEDR:

IOCTL Code Direction Purpose
WAIT_FOR_EVENT 0x222000 Kernel → Agent Agent blocks until next event (overlapped I/O)
KILL_PROCESS 0x222004 Agent → Kernel Kernel-level process termination
ADD_BLOCK_RULE 0x222008 Agent → Kernel Push block rule (image suffix + cmdline substr)
CLEAR_BLOCK_RULES 0x22200C Agent → Kernel Reset all block rules
SIGNAL_LSASS_DUMP 0x222010 Agent → Kernel Signal LSASS dump — kernel kills dumper + logs event

Driver setup

# Use the install script (requires Administrator)
.\install_driver.ps1 -Install

# Or manually:
# 1. Enable test-signing (one-time, requires reboot)
bcdedit /set testsigning on

# 2. Register and start the driver
sc.exe create MostShittyEDR type= kernel binPath= C:\path\to\driver.sys
sc.exe start MostShittyEDR

# 3. Run the agent with --driver
.\edr_agent.exe --driver --verbose

# Uninstall driver only
.\install_driver.ps1 -Uninstall

# Uninstall everything (agent + driver)
.\uninstall.ps1

# Uninstall everything + remove build artifacts
.\uninstall.ps1 -Clean

User-mode vs Kernel-mode

User-mode (default) Kernel-mode (--driver)
Monitoring Toolhelp32 polling (500ms gaps) Kernel callbacks (no gaps)
Process blocking Kill after detection Deny creation before start
LSASS protection Keyword matching only Handle permission stripping
Process termination TerminateProcess (user-mode) ZwTerminateProcess (ring 0)
Evasion difficulty Easy (timing, elevation) Harder (needs kernel access)
Requirements None WDK, test-signing, Administrator

The Challenge

Can you bypass the EDR? This agent uses common detection patterns found in real-world EDR products. Your mission: Execute tools and commands without being detected or killed!

Known Vulnerabilities

  • 🔓 Case-sensitive blacklist (Mimikatz.exe != mimikatz.exe)
  • 🔓 No command-line deobfuscation (carets, env vars, encoding all bypass)
  • 🔓 Recon detection is theater (Rule 3 detects but discards the result)
  • 🔓 LSASS rule needs dual match (rename tool OR omit "lsass" keyword)
  • 🔓 Only monitors powershell.exe (not pwsh.exe)
  • 🔓 Plaintext signature file is readable and exact-match only
  • 🔓 Static import analysis bypassed by dynamic resolution or direct syscalls
  • 🔓 ETW session has hardcoded name, patchable EtwEventWrite
  • 🔓 PE analysis has no entropy check, strict parser crashes on corrupted headers
  • 🔓 Polling-based monitoring has timing gaps (without --driver)
  • 🔓 Driver device has no access control — any process can send IOCTLs
  • 🔓 Single-slot event delivery is monopolizable (DoS)

Challenge Categories

Category Challenges Difficulty Target Rules
Process Name Evasion 01-04 Easy Rule 1
Command Line Obfuscation 05-09 Easy-Medium Rules 2, 3, 5
Process Monitoring Bypass 10-14 Medium Architecture, Rule 4
Execution Evasion 15-18 Medium-Hard Architecture, Rule 5
Advanced Bypass 19-20 Easy-Hard Architecture, Rule 6
API Hook Evasion 21-24 Medium-Hard Rule 7
ETW Bypass 25-28 Easy-Hard Rule 8
Signature Bypass 29-32 Easy-Hard Rule 6
Packer & PE Evasion 33-36 Medium-Hard Rule 9
BYOVD / Kernel Attacks 37-39 Hard Kernel Driver
IOCTL Abuse 40-42 Medium Kernel Driver

42 challenges with full solutions at the Challenge Browser.


Architecture

Detection Pipeline

Process Event (polling or kernel callback)
    |
    +-> Rule 1: Process Name Blacklist   --> KILL   (case-sensitive!)
    +-> Rule 2: Command Line Keywords    --> KILL   (no deobfuscation!)
    +-> Rule 3: Recon Detection          --> discard (never blocks!)
    +-> Rule 4: LSASS Dump Detection     --> KILL   (needs both conditions!)
    +-> Rule 5: PowerShell Analysis      --> KILL   (only powershell.exe!)
    +-> Rule 6: Hash Check (SHA256)      --> KILL   (exact match, on-disk only!)
    +-> Rule 7: Hooked API Imports       --> ALERT  (static imports only!)
    +-> Rule 8: ETW Integrity            --> KILL   (user-mode only!)
    +-> Rule 9: PE Structure Analysis    --> ALERT  (no entropy, strict parser!)

Dual-Mode Architecture

graph TB
    subgraph Kernel["🔒 Kernel Driver (--driver mode)"]
        direction TB
        CB1["PsSetCreateProcessNotifyRoutineEx<br/>→ ProcessCallback"]
        CB2["PsSetCreateThreadNotifyRoutine<br/>→ ThreadCallback"]
        CB3["ObRegisterCallbacks<br/>→ LsassHandleGuard"]
        EQ["📋 Event Queue<br/>(LIST_ENTRY FIFO)"]
        BR["🚫 Block Rules<br/>(up to 64)"]
        IRP["⏳ Pending IRP<br/>(single-slot)"]

        CB1 --> EQ
        CB2 --> EQ
        CB3 --> EQ
        BR -->|deny creation| CB1
        EQ --> IRP
    end

    subgraph Device["IOCTL Interface — \\\\.\\MostShittyEDR"]
        direction LR
        I1["WAIT_FOR_EVENT<br/>0x222000"]
        I2["KILL_PROCESS<br/>0x222004"]
        I3["ADD_BLOCK_RULE<br/>0x222008"]
        I4["CLEAR_RULES<br/>0x22200C"]
        I5["SIGNAL_LSASS<br/>0x222010"]
    end

    subgraph User["🛡️ Nim Agent (edr_agent.exe)"]
        direction TB
        Rules["Rules 1-9"]
        ETW["ETW Telemetry"]
        Sigs["Hash Signatures"]
        Hooks["Hook Profiles"]
    end

    IRP -->|overlapped I/O| I1
    I1 -->|EDR_EVENT struct| User
    User -->|EdrCommand struct| I2
    User -->|BlockRuleEntry struct| I3
Loading

Project Structure

MostShittyEDR/
├── src/
│   ├── edr_agent.nim              # User-mode EDR agent (Nim)
│   └── driver/
│       └── driver.cpp             # Kernel driver (C++, WDK required)
├── tests/
│   ├── test_rules.nim             # 98 rule + ABI verification tests
│   ├── test_profiles.nim          # 20 hook profile tests
│   ├── test_driver_logic.cpp      # 44 driver logic tests (user-mode)
│   └── test_driver_ioctl.cpp      # Driver IOCTL integration tests
├── profiles/                      # Real EDR hook profiles
├── signatures/
│   └── malware_hashes.txt         # SHA256 signature database
├── _challenges/                   # 42 bypass challenges
├── _solutions/                    # Detailed solution walkthroughs
├── install_driver.ps1             # Driver install/uninstall script
├── uninstall.ps1                  # Full uninstall (agent + driver + cleanup)
├── Makefile                       # Build automation
└── MostShittyEDR.nimble           # Nim package config

Testing

# Run all Nim tests (rules + profiles)
make test-nim

# Run driver logic tests (no driver needed)
make test-driver-logic

# Run driver IOCTL tests (requires loaded driver + admin)
make test-driver-ioctl

# Run all safe tests
make test

The test suite includes 162 tests:

  • 98 detection rule tests (Rules 1-9, helpers, analysis engine)
  • 24 driver ABI verification tests (struct sizes, field offsets, IOCTL codes)
  • 20 hook profile tests
  • 20 driver logic tests (C++)

Resources

EDR Internals

Companion Projects

  • MostShittyAV - The AMSI bypass companion lab (43 challenges)

Security Research


License

This project is licensed under the MIT License - see the LICENSE file for details.


⚠️ Legal Notice

This tool is for educational and research purposes only.

  • ❌ Do not use on systems you don't own or have explicit permission to test
  • ❌ Do not use for malicious purposes
  • ❌ Not a replacement for real endpoint security
  • ✅ Use in controlled lab environments only
  • ✅ Understand applicable laws and regulations in your jurisdiction

The author assumes no liability for misuse of this software.


Happy Hunting!

Made with Nim for the security research community

⭐ Star this repo🐛 Report Bug💡 Request Feature

About

The World's Most Intentionally Terrible EDR - An educational platform for learning EDR detection and evasion techniques.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages