Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

added exe-only options to win32pe generation #904

merged 1 commit into from Mar 27, 2013


None yet
9 participants

agix commented Oct 14, 2012

"msfencode -t exe" or "-t exe-small" are now detected by AV regardless of the template.
This is a patch "-t exe-only" that insert payload at the template entry point adding flag writable on the section Characteristics.
So only payload can be detected by AV.

RWX sections could increase the detection but it can't be the only criterion of detection.

  • Choose a PE (not native windows binary nor already AVs detected binary obviously)
  • Change .text section Characteristics : add W flag (0x800000000) LordPE can do it...
  • Scan the PE with every AV you want
  • Beat me (...or not I hope)

wchen-r7 commented Oct 14, 2012

Which AVs did you test this on?


agix commented Oct 15, 2012

I tried it against MSE, Kaspersky and McAffee, and if you try it WITHOUT payload and with a different template on virustotal you should obtain 0/48.


rsmudge commented Feb 23, 2013

+1 on this pull request. I tested it and it works. Here's how I tested it:

msf > use payload/windows/messagebox
msf payload(messagebox) > generate -t exe -f /root/a.exe
[] Writing 73802 bytes to /root/a.exe...
msf payload(messagebox) > generate -t exe-only -f /root/b.exe
] Writing 4608 bytes to /root/b.exe...

a.exe will get caught by anti-virus (in my case Windows Security Essentials). Why? Because even without attempting to preserve the template exe's functionality, the Metasploit Framework generates some stub code to spin up a new thread with win32_rwx_exec(code). This stub of code is what AV products are picking up as Swrort.A.

This pull request makes it so only the stager gets added when the template exe is not expected to keep its functionality. If the stager code is not picked up by anti-virus, then the exe will work.

One question you may ask--who is going to write new shellcode? Here's a use case: earlier this week I patched the generic/custom payload to make it possible to generate an exe from it. There was a reason why. I can write a small DLL, link it with Stephen Fewer's reflective DLL code, and pass it in as PAYLOADFILE. The earlier generic/custom patch makes it possible to generate an exe from that reflective DLL.

This pull request now makes it possible for that generated EXE to get past anti-virus, so long as the small DLL I provide isn't caught.


rsmudge commented Feb 23, 2013

Works fine with template executables too:

msf payload(messagebox) > generate -t exe -x /root/putty.exe -f /root/c.exe
[] Writing 483328 bytes to /root/c.exe...
msf payload(messagebox) > generate -t exe-only -x /root/putty.exe -f /root/d.exe
] Writing 483328 bytes to /root/d.exe...


agix commented Feb 23, 2013

Thanks for the support :D I thought nobody tried it !
Maybe there is some ruby stuff to improve but the exe-only totally remove the detection of any stubs that are not the shellcode...
The only problem could be the RWX section...


hdm commented Feb 23, 2013

FYI, RWX sections trigger a number of AV heuristics


agix commented Feb 24, 2013

I don't know on which information you rely but on virustotal, only two trigger RWX section.
Here is a simple test :

python -c 'print "\x90"' | git/metasploit-framework/msfencode -e generic/none -t exe -x /mnt/vm/notepad++.exe > /tmp/test2.exe
26 / 46 :

python -c 'print "\x90"' | git/metasploit-framework/msfencode -e generic/none -t exe-only -x /mnt/vm/notepad++.exe > /tmp/test2.exe
2/46 : https://www.virustotal.com/fr/file/5b7b349beede01926017bbe5131d511957cc52dbac98b19d3d08a5596c9fcb04/analysis/1361742998/

@todb-r7 todb-r7 referenced this pull request in agix/metasploit-framework Mar 18, 2013


Exe only patch #1


todb-r7 commented Mar 18, 2013

agix#1 resolves the merge conflict, and incidentally pulls back some original functionality.


agix commented Mar 19, 2013

C:\Windows\SysWOW64\ntkrnlpa.exe and C:\Windows\SysWOW64\ntoskrnl.exe
and same in System32 have a section RWX and I think they are important to windows system...
So if AV use only RWX section to catch virus, they would catch windows system binaries too...
One point for you is that the RWX section (in that binaries) doesn't contain the Entry Point...
I continue to scan windows native binaries.

@jlee-r7 jlee-r7 and 1 other commented on an outdated diff Mar 20, 2013

+ if pe.hdr.opt.AddressOfEntryPoint >= virtualAddress && pe.hdr.opt.AddressOfEntryPoint < virtualAddress+sizeOfRawData
+ #put this section writable
+ characteristics|=0x80000000
+ newcharacteristics = [characteristics].pack('L')
+ exe[sec[0],newcharacteristics.length]=newcharacteristics
+ end
+ end
+ #put the shellcode at the entry point, overwriting template
+ exe[pe.rva_to_file_offset(pe.hdr.opt.AddressOfEntryPoint),code.length]=code
+ return exe
+ end
+ def self.to_win32pe_old(framework, code, opts={})x

jlee-r7 Mar 20, 2013


Typo? x at end of line.


todb-r7 Mar 20, 2013




jlee-r7 commented Mar 20, 2013

Travis failure is legit. Please fix.

Virustotal is a poor indicator. For one thing, heuristics engines are NOT included in VT scans. You mgiht avoid signatures this way but could end up tripping new heuristics detection as @hmoore-r7 suggested.

@todb-r7 todb-r7 referenced this pull request in agix/metasploit-framework Mar 20, 2013


Fix egypt's typo #2


agix commented Mar 21, 2013

@dmaloney-r7 how can I show my tests :) ? I think @rsmudge did his own tests...
I use this patch to avoid AVs during pentests (with a custom encoder that's catched when using with classic PE creation).
So can you prove me that an AV catch a binary just because of RWX section ?


todb-r7 commented Mar 21, 2013

@agix describing a test procedure would be sufficient. Github Pull Requests even have some handy markup:

  • Dream up a testing procedure
  • Write it down in checkbox format on the PR
  • Toast your great success.

Note you might want to see if you can't convince @wchen-r7 to throw in, he has a pretty nice little AV lab environment set up now.


Meatballs1 commented Mar 21, 2013

If this is additional functionality that doesn't affect existing functionality is there really a huge requirement to prove it bypasses lots? If it only bypasses one AV solution its still a benefit?

Its another technique/option people can choose which doesn't detract from existing functionality and people have confirmed it bypasses AV in some situations?


todb-r7 commented Mar 21, 2013

@Meatballs1 the original PR wanted to change out the defaults for basically everything that used EXEs. For something like that, yes, it would need to get proved out to at least some level that existing functionality isn't busted.

As it stands now with the edits (default behavior was restored), that level of proof isn't required to land this -- but proving assertions is always better than merely asserting them. Once someone wants to change out the defaults again, then yes, we'll need to know that we're getting something out if it.


agix commented Mar 21, 2013

Oh yeah, sorry, with @todb-r7 patch, now it doesn't affect any existing feature.
The test is pretty simple.
Take almost any binary you want.
The binary must be clean (not already detected by AV of course).
The binary must not be a windows native binary because some AV made a whitelist and detect for exemple calc.exe if you change just one byte.
After you choose your binary, just change the Characteristics of .text section with LordPE for exemple and add the flag W (0x80000000) to it.
If your AV tilt, so my patch is shit :(

This patch doesn't bypass AVs ! It's just a loader almost signatureless that AVs don't detect for the moment.
I hope AVs won't use section with RWX Characteristics because some windows binaries have this kind of sections.

I did it because the actual loader is detected even if you give nopsled as shellcode.


scriptjunkie commented Mar 27, 2013

  • rsmudge's use case is valid
  • I could also see the value of something like this when debugging payloads
  • and agix's VT test showed that there might even be AV-bypassing value in this
  • the current version should not change any expected behavior

So it looks good to me.

@scriptjunkie scriptjunkie merged commit e567597 into rapid7:master Mar 27, 2013

1 check passed

default The Travis build passed

@agix agix deleted the agix:exe_only_patch branch Mar 30, 2013

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment