Antivirus is a software program whose main task is to protect, identify and remove any malicious software or virus. However, if we look closely at how the antivirus actually works in identifying and removing viruses, we would realize that it is not very difficult to bypass them.
There are many ways to bypass the antivirus most of them involve using automated tools. There is also a good framework known as known as "Veil Framework" that creates malicious binaries that are very good in bypassing antivirus.
FREE role-guided training plans
Although automating things is good and saves time but it is also important to understand how the process of evading antivirus actually works. Also, modern day antivirus does flag the binaries created from automated tools. Hence, it becomes important to know manual techniques of evading antivirus.
In this article, I will modify the binary contents of a Netcat listener so as to bypass the most popular and commonly used anti-virus.
The Objective is to ensure that the Netcat listener should be undetected by the antivirus software and at the same time, it should be functioning without any issues.
To follow the steps in this article, it is important to have basic knowledge of assembly language and a general familiarity with a Debugger (we will be using Immunity in this case) and its usage.
Antivirus scanners mostly depend on a signature pattern from a local database to identify malicious files and viruses. Also, they scan the file while it is on disk and not in memory.
If we can alter the contents of our Netcat binary when it is on disk, the antivirus that scans the file will not be able to identify the signature since the binary contents of the file have been changed. Now when the file is opened, we revert the contents of the Netcat binary in memory to its original state to ensure that the file is successfully running.
Although modern-day antivirus does scan files in memory and try to replicate its behavior in a sandbox environment, there are other ways to bypass this restriction as well, but as of now we will focus on the scenario where the antivirus who do not scan file in memory.
1) We will first set-up the Netcat listener and scan it on virus
total website. This will give us an idea as to how many antivirus scanners detect the Netcat binary as a malicious file in its original state. The Netcat binary can be downloaded from this website: https://joncraton.org/blog/46/netcat-for-windows/
Below are the results after scanning the Netcat binary on the virus
As you can see a good number of antivirus scanners identify this Netcat binary as malicious. Now we will attempt to decrease the detection ratio of this Netcat file (31/57) by altering the binary contents of the file.
2) What we will attempt to do is hijack the entry point of our malicious Netcat listener, redirect it to a STUB (which in this case will be a custom XOR encoder) which encodes the contents of the file. This stub will be small shellcode which can be placed in the dead-space available in Netcat binary.
After running the stub on the Netcat binary, you will notice that the contents of the Netcat file have completely changed. We can now scan this file on virus total website and see if the detection ratio of this Netcat file decreases.
In a real world scenario, we will save this encoded file on the victim's computer but since its contents have changed it bypasses the antivirus, now when we run the file, XOR encoder will run on the file again while it is in memory and change the file back to its original content and the file will be launched successfully. This is because when XOR function is run on a code that is already being XOR'ed, it will return the original code.
3) Let us start by loading the Netcat file in the Immunity Debugger and look for some dead space code where we can place our stub.
As we can see, there is some dead-space in the Netcat binary which can be used to place our stub. In my case, the dead space starts at the address: 0040A972.
4) We will hijack the entry point the Netcat binary and redirect it to the dead space address (i.e., 0040A972). Also while hijacking the entry point, we will make a note of the initial instructions that are overwritten as these would have to be re-introduced again.
The Initial Instructions of the program are:
00404AC3 6A 18 PUSH 18
00404AC5 68 98C04000 PUSH nc.0040C098
00404ACA E8 69030000 CALL nc.00404E38
We will hijack the entry point by overwriting the first instruction with a redirection to our dead-space code address. While overwriting the code we notice that the first two instructions are overwritten, these will have to be re-introduced in the code later.
5) Now we save the changes made to this binary by doing a right click and selecting Copy to Executable and save the file as nc1.exe.
Before we open this file and jump to our dead-space code address, it is important that we mark all the sections of this file as writable since our stub (custom XOR encoder) will have to encode the contents of the file. In the Netcat binary, we are encoding the text section of the file so we will mark the text section as writable.
To do this, open the nc1.exe file with a PE Editor like Lord PE. Select the text section of the file and do right click to edit the section header and select the writable option and save the changes.
6) Now let us open the nc1.exe file in the immunity debugger and take a jump (by pressing F7) to the dead-space code address.
From this address onwards we will encode the entire text section of the file using our custom XOR encoder. Before starting the encoding, we will make a note of the starting and ending address of the text section. This address is found in the debugger itself from the third instruction (after redirecting to the dead-space code) to the end of the file. Also, the starting and ending addresses of the text section can be known by clicking on the "M" tab (memory-map) in the immunity debugger.
In my case the starting and the ending address of the text sections of the file is:-
Start Address: 00404ACA
Ending Address: 0040A96D
7) Now we will write our custom XOR encoder stub. The custom stub will include the following instructions:-
0040A972 B8 CA4A4000 MOV EAX,nc2.00404ACA
0040A977 8030 0F XOR BYTE PTR DS:[EAX],0F
0040A97A 40 INC EAX
0040A97B 3D 6DA94000 CMP EAX,nc2.0040A96D
0040A985 7E F0 JLE SHORT nc2.0040A977
0040A987 6A 18 PUSH 18
0040A989 68 98C04000 PUSH nc2.0040C098
0040A98E E9 37A1FFFF JMP nc2.00404ACA
The first instruction moves the value of the starting address of text section (00404ACA) in the EAX register. Then we XOR the value of the EAX register with the 0F key. Now we increase the value of EAX. Then compare the value of EAX with the ending address of the text section (0040A96D). If the ending address is not reached then simply jump back to the second instruction (0040A977) and continue the process. After the ending, the address is reached simply reintroduce the initial instruction of the program and continue the normal execution.
8) After writing this stub, we will copy the changes to an executable and save the file as nc2.exe.
Now we will open this file and allow the stub to run and encode the entire text section of the file. After the text section is encoded, we will go to the starting address of text section, i.e., 00404ACA (by doing a right-click and selecting the option Go to>Expression in the immunity debugger) and select all the encoded data right to the end of the text section and copy the changes to the executable. Now we will save the file and rename it as nc3.exe.
We have now completely changed the contents of the text section of this file. If we scan this nc3.exe file on virus
total website, we can see that the detection ratio has been decreased significantly. (20/57)
In a real world scenario what will happen is the modified Netcat binary is saved on disk, since the binary is modified the signature is also changed and the antivirus is bypassed then when we open this file again, the custom XOR encoder will run on the file again and as we know if we run the XOR function again on a code that is already XOR'ed we will get the original contents back.
Hence, when the file is opened the XOR Encoder will revert the modified binary back to its original state in memory thereby bypassing the Antivirus.
9) Now the XOR encoder stub is the not the only way of writing custom encoders; there are many different ways of writing these encoders. For example, we can use a stub that adds 15 bytes to the code, then XOR's it with a 0A key and then adds another 35 bytes to the code. If used on the nc.exe file the above code will look like this:-
ADD BYTE PTR DS:[EAX], 15
XOR BYTE PTR DS:[EAX],0A
ADD BYTE PTR DS:[EAX], 35
JLE SHORT nc2.0040A977
Now we can encode the text section by running the above stub on the Netcat binary and then saving the changes to create the modified binary. Now we change our custom encoder to ensure that the binary can decode itself back in the memory. We simply alter the instructions in the following way so that the program can decode itself.
ADD BYTE PTR DS:[EAX], -35
XOR BYTE PTR DS:[EAX],0A
ADD BYTE PTR DS:[EAX], -15
JLE SHORT nc2.0040A977
Similarly, we can write our own encoders to modify the binary contents of the file and bypass the antivirus.
10) Now apart from writing encoders, there is also another way to bypass antivirus and that is by renaming the sections of the binary. What we will do is open the Netcat binary in the immunity debugger and rename the .text section of the file to .bop.
We can do this by simply doing a right click on the text section, select edit header and rename it from .text to .bop. Then we save the changes to the file and exit the program.
11) After saving this file if we scan it on virus
total website, we see that the detection ratio of the antivirus has been further decreased (15/57) and this time, even popular antiviruses like Kaspersky and McAfee has been bypassed.
FREE role-guided training plans
We can see that bypassing antivirus is not the most difficult job, we simply have to keep trying different techniques to be successful. There are multiple ways to bypass the antivirus and I have highlighted only a couple of easy ways. Hence, it is not ideal to depend only on antiviruses to protect critical assets.