How to evade antivirus [easy method]

Carlos Gonçalves
7 min readApr 22, 2020

--

Summary

Nowadays antivirus are incredibly sophisticated pieces of software, used for protecting you from different types of threats, to make your computer and you safe. Although they make use of advanced detection techniques such as signatures, heuristics, behavior analysis, and even machine learning algorithms, they can be easily evaded. In this article, we will present an easy to follow tutorial on how to evade all most any antivirus out there. We will be using the well-known memory injection combined with a tricky entry point. Our goal is not to create a FUD payload from scratch but to take a well-known malware and make it undetectable.

Quick note: I still think that using a good up to date antivirus is a good practice as they play a big role in making you safe by adding an extra layer of security, just do not trust it with your life.

For this tutorial, I have chosen a .NET open-source payload so the wrapper for this malware will also be coded in .NET to facilitate the process (although it is perfectly possible to use different languages here). There are a lot of open-source malware projects you can use for this on GitHub repositories, if you do not have any to start with, just pick one.

Although we are using C#, presented concepts are language agnostic and I encourage you to implement it in a different one.

Requirements

For this tutorial you will need:

As I mentioned earlier, we are going to use memory injection to load the malicious executable but, before loading it, we need an entry point. To trick the antivirus and evade sandbox behavior analysis, a mouse click will trigger the injection since most of the sandboxes do not allow keyboard/mouse interaction and besides that, no one can predict when this condition occurs. We will also keep the malware encrypted until the moment it is loaded into memory to avoid AV static detection.

Step 1: Encrypt the payload

After choosing a malware (.NET only), we need to convert it to base64 so we can store it as a string in our wrapper (there are multiple online base64 encoders/decoders that you can use for it). This wrapper is usually called a stub because it is the code in charge for decrypting and executing the malware. After converting to base64 we are going to encrypt it using standard AES encryption and convert it again to string.

Brief explanation of the conversion:

  • Convert your binary (bytes -> base64)
  • Encrypt (base64 -> bytes)
  • Convert it again (bytes -> base64)

Open Visual Studio and create a project, that will be responsible to encrypt our binary, build and run it. The image below illustrates the process.

This code saves the encrypted payload in a file, that will be used later.

Step 2: Detect mouse click

Now we need to create a program that detects the mouse click globally and executes our binary upon click detection. The easiest way to do this is by using a nugget package named MouseKeyHook. We want to detect clicks globally, but the execution of our wrapper should be stealth, so we are going to force our console application to run as a windows forms application.

In this way, we can run the program without showing any output window to the user.

  • Create a console application (.NET Framework 4.6) in VisualStudio and run it as a windows form application
  • Go to Solution->Manage NuGet Packages and install MouseKeyHook and ILmerge.
  • Create a Hook for the left/right mouse click

The load method is executed after a click and triggers the process of decryption and execution and will be explained in detail further.

Step 3: Decrypt and inject

After setting the hook for the mouse click (we are going to use any mouse click left/right, but feel free to use whatever click you want or even double clicks for instance), we need to do the opposite operation we did in the first step to decrypt the malware. The base64 string is the one that was created and saved in a file in the first step (our encoded encrypted malware).

Reverse process:

  • Convert (base64 -> bytes)
  • Decrypt (bytes -> base64)
  • Convert it again: (base64 -> bytes)

After decrypting the payload we are going to execute it in memory, using memory injection in C#. This method is not new and you can learn more about it here.

Note: Alternatively to the encryption process we could create a Pastebin with the raw payload and make a web request at the time we want to load it. This would make the final binary smaller since we didn’t need to have a hardcoded payload. On the other hand, it increases the probability of being classified as a malicious dropper.

Fifth step: Build and merge

We added a nugget package to detect the mouse click when we build this solution, so an external DLL will be generated. Malware should be discreet, and having two files breaks this rule.

To solve this issue ILmerge, a static linker for .NET, is used to merge all files into a single one. The use of ILmerge may seem a bit confusing and tricky but with the following bash script, it is pretty straight forward.

:: [Change] Set your target executable name (typically [projectname].exe) your DLL name and your merged file NameSET APP_NAME=unwrapped.exe
SET DLL_NAME=Gma.System.MouseKeyHook.dll
SET MERGED_NAME=wrappedPayload.exe
:: [Change] Set the path to the folder where the executable and the DLL is:
SET PATH_TO_EXE_FOLDER= C:\YOUR\PATH\TO\PROJECT\NAMEOF\PROJECT\bin\Release
:: [Change] set your NuGet ILMerge Version (check on Visual Studio)
SET ILMERGE_VERSION=3.0.29
:: the full ILMerge should be found here:
SET ILMERGE_PATH=%USERPROFILE%\.nuget\packages\ilmerge\%ILMERGE_VERSION%\tools\net452
SET FINAL_PATH=%PATH_TO_EXE_FOLDER%\%APP_NAME%
SET DLL_PATH=%PATH_TO_EXE_FOLDER%\%DLL_NAME%
"%ILMERGE_PATH%"\ILMerge.exe %FINAL_PATH% ^
/lib:Bin\%ILMERGE_BUILD%\ ^
/out:%MERGED_NAME% ^
%DLL_PATH%
:Done
set /p asd="DONE. Merge was completed!"

After saving this as a .bat file, customize the path and name variables to match your configuration and execute it. A merged file will be created in the directory where the script was executed. This merged file is our single file payload, fully indetectable at the time this article is written. Let’s test it!

Sixth step: Test it

The best way to check if the resulting payload is undetectable consists in pass it through an online antivirus scanner, to test against dozens of different antivirus. For the sake of comparison, our payload was tested twice, before and after applying our wrapper.

Before: As you can see in the image below the original version of the payload is detected by a significant amount of engines (21/31).

After: As predicted, the presented solution was able to evade all the antivirus in this online scanner (0/31).

We proved that it works in theory, but let’s check it in practice, running it on a fully patched Windows 10 machine with Windows Defender enabled.

Voilât! Our victim machine pinged back the host machine, meaning that the payload was successfully loaded on our victim.

You can check out all the files used in this tutorial here.

Final thoughts

The purposed goal was accomplished since we were able to evade antivirus and execute the payload, but this solution is far from complete and can be improved in several different ways such as:

  • Add persistence to the payload (process injection, windows registry, startup keys,…)
  • Remove .Net dependencies
  • Add compression/obfuscation
  • Shrink payload size
  • Choose random string and variables names
  • Change the encryption used

Another interesting variation would be implementing this mechanism in a low-level language like C or C++ making it stealthier. Just be creative :)

--

--

Carlos Gonçalves

Software Developer interested in web, blockchain, and cybersecurity.