---
title: "Accidental LOLBin: Controlling Media Keys with csc.exe"
description: "I needed to pause my music and ended up using csc.exe as a LOLBin: MITRE ATT&CK T1027.004, Compile After Delivery. How it works and how it's detected."
pubDate: 2026-01-08
tags:
  - "cybersecurity"
  - "windows"
  - "csharp"
  - "lolbin"
  - "mitre"
atlasNodes:
  - "https://zapf.dev/atlas/lolbin/"
  - "https://zapf.dev/atlas/mitre-attack/"
  - "https://zapf.dev/atlas/sigma-rules/"
source: "https://zapf.dev/blog/accidental-lolbin-media-keys/"
---

I was coding with music in the background when I needed to pause it. I reached for my mouse button that I'd configured for this, and... nothing. My usual utility had stopped working after a software update.

I decided to write a simple solution: a script that compiles C# code on-the-fly using only Windows built-in tools. It works well. But while documenting it, I realized something interesting: I'd accidentally implemented a technique listed in MITRE ATT&CK as **[T1027.004: Compile After Delivery](https://attack.mitre.org/techniques/T1027/004/)**.

## The Goal

I needed a native way to send media keys (Play, Next, Prev) using only what's included in Windows. No third-party binaries, no installations.

## What's a LOLBin?

**[LOLBin](https://lolbas-project.github.io/)** (Living Off the Land Binary) refers to legitimate system tools that can be used for purposes beyond their original intent.

Windows includes many of these: `certutil.exe`, `mshta.exe`, `regsvr32.exe`, and [`csc.exe`](https://lolbas-project.github.io/lolbas/Binaries/Csc/) (the C# compiler). They're all signed by Microsoft and present in clean Windows installations.

Attackers sometimes prefer LOLBins because:
- They don't trigger antivirus alerts (they're legitimate system files)
- They don't require downloading suspicious tools
- They can bypass Application Whitelisting policies
- They leave fewer obvious traces

## The Code

I wrote a simple C# class that uses `user32.dll` to simulate media key presses.

```csharp title="MediaKey.cs"
using System.Runtime.InteropServices;
using System.Threading;

class P
{
    [DllImport("user32.dll")]
    static extern void keybd_event(byte bVk, byte bScan, int f, int e);

    static void Main(string[] a)
    {
        if (a.Length == 0)
            return;
        byte k = 0;
        switch (a[0].ToLowerInvariant())
        {
            case "playpause":
                k = 0xB3;
                break;
            case "next":
                k = 0xB0;
                break;
            case "prev":
                k = 0xB1;
                break;
            default:
                return;
        }

        keybd_event(k, 0, 1, 0);
        Thread.Sleep(10);
        keybd_event(k, 0, 3, 0);
        Thread.Sleep(50);
    }
}
```

The code is deliberately minimal: short class names, no unnecessary namespaces, just what's needed to work.

## The "LOLBin" Mechanism

To run this without distributing an `.exe`, I used the C# compiler (`csc.exe`) that comes pre-installed with .NET Framework on Windows.

```bat title="compile.bat"
@echo off
setlocal EnableExtensions

set "SRC=%~dp0..\src\MediaKey.cs"
set "OUTDIR=%~dp0..\bin"
set "OUT=%OUTDIR%\MediaKey.exe"
set "CSC_FLAGS=/nologo /optimize+ /debug- /target:winexe /platform:anycpu"

echo Compiling %OUT%...

REM ---- 1) Validate source
if not exist "%SRC%" (
  echo ERROR: "%SRC%" not found in: "%CD%"
  pause
  exit /b 1
)

REM ---- 2) Resolve csc.exe (x64 -> x86 -> PATH)
set "CSC=%WINDIR%\Microsoft.NET\Framework64\v4.0.30319\csc.exe"
if not exist "%CSC%" set "CSC=%WINDIR%\Microsoft.NET\Framework\v4.0.30319\csc.exe"

if not exist "%CSC%" (
  for /f "delims=" %%I in ('where csc.exe 2^>nul') do ( set "CSC=%%I" & goto :got_csc )
  echo ERROR: csc.exe not found. Install .NET Framework 4.x or add csc to PATH.
  pause
  exit /b 1
)
:got_csc

REM ---- 3) Prepare output
if not exist "%OUTDIR%" mkdir "%OUTDIR%" >nul 2>&1

REM ---- 4) Compile
"%CSC%" %CSC_FLAGS% /out:"%OUT%" "%SRC%"
if errorlevel 1 (
  echo.
  echo ERROR: Compilation failed.
  pause
  exit /b 1
)

echo.
echo OK: Compilation successful.
for %%F in ("%OUT%") do (
  echo Generated: "%%~fF" (%%~zF bytes^)
  echo.
  echo Usage:
  echo   %%~fF playpause
  echo   %%~fF next
  echo   %%~fF prev
)
echo.
pause

exit /b 0
```

## Why This Maps to T1027.004

This approach corresponds to **[MITRE ATT&CK T1027.004: Compile After Delivery](https://attack.mitre.org/techniques/T1027/004/)**.

Instead of sending a compiled executable (which antivirus software immediately scans), source code can be sent as text. Once on the target system, built-in tools like `csc.exe` compile it locally.

```mermaid
graph LR
    A[Source Code .cs] -->|csc.exe| B[Binary .exe]
    B -->|Execute| C[Runs]
```

The basic flow:
1. **Delivery**: Send code as text (bypasses binary scanning)
2. **Compilation**: Use built-in compiler
3. **Execution**: Run the fresh binary

In my case, I'm just controlling media playback. But it demonstrates how "Living Off the Land" works in practice.

### Real-World Usage

This technique has been observed in actual threat campaigns:

- **[MuddyWater](https://www.cisa.gov/news-events/cybersecurity-advisories/aa22-055a)** (Iranian APT): Used `csc.exe` compilation in their operations targeting government and commercial networks in the Middle East and beyond.
- **[DarkWatchman](https://attack.mitre.org/software/S0673/)**: A JavaScript-based RAT that dynamically compiles a C# keylogger using the Code DOM (Code Document Object Model) for fileless execution.
- **Imperial Kitten**: Deployed IMAPLoader malware using this technique, writing C# source files to disk and compiling them after initial access.

These groups chose this method specifically to evade static analysis and antivirus detection during the delivery phase.

### Detection

Security tools look for patterns like:
- `csc.exe` running in unusual contexts (e.g., from temp directories)
- Compilation followed by immediate execution
- Source files from suspicious origins
- Command-line arguments that include compilation flags with user-writable output directories

Detection rules for this technique are available in [Sigma](https://github.com/SigmaHQ/sigma/blob/master/rules/windows/process_creation/proc_creation_win_csc_susp_dynamic_compilation.yml) and other security platforms.

### Legitimate vs Suspicious Use

Using `csc.exe` is normal in many contexts:

**Legitimate:**
- Development automation scripts
- Personal tools (like this one)
- Documented build processes

**Suspicious:**
- Compilation from temporary directories by non-developer users
- Combined with other evasion techniques
- Immediate execution after compilation from external sources

## Takeaways

This small project showed me how the same tools used for everyday tasks can be leveraged differently. There's nothing inherently malicious about `csc.exe`—context matters.

As someone starting in cybersecurity, I find this perspective useful. Every system utility, API, or programming pattern can be viewed from multiple angles: building something helpful vs finding attack vectors.

The complete code is available here: **[win-mediakey-lolbin](https://github.com/MatiasZapf/win-mediakey-lolbin)**