Google

peCloak.py – An Experiment in AV Evasion

Written on:March 9, 2015
Comments are closed

Introduction

I just wrapped up the Offensive Security Cracking The Perimeter (CTP) course and one of the topics was AV evasion. Although I write a lot of custom scripts and tools, when it comes to AV evasion, I typically rely on the tools and methods of others (Veil, powershell, python, custom shellcode). That said, the great thing about courses like CTP is they give me an excuse to investigate a topic that I haven’t had an opportunity to delve into in much detail.

The CTP course was developed several years ago and I was curious how far AV vendors have come since then; so, after completing the course module, I decided to delve a bit further and devised a little experiment to see how easy it would be to consistently bypass detection of some of the market leading AV products. I spent a weekend tapping out some code and what resulted was a simple proof-of-concept python script I dubbed “peCloak” which automates the process of hiding a malicious windows executable from AV detection (a copy of the beta version is available at the end of this post).

The Experiment

Before we get wrapped up in the terms, let me just say that I’m using the word “experiment” very loosely. There won’t be any control groups or random selection so please don’t go critiquing my application of the scientific method! 🙂

Hypothesis

My hypothesis was simple and based on common knowledge: AV detection is heavily reliant on file signatures with limited application of sandbox / heuristic-based detection.

Therefore I was confident that by modifying portions of the executable and introducing basic sandbox-defeating functionality I could render most client-side AV detection ineffective.

Requirements

I set out with the following requirements:

  1. The modified PE file must evade AV detection from market-leading products with up-to-date definitions.
  2. The encoded malicious payload must execute without error. Failure to execute regardless of AV detection would be considered an unsuccessful bypass.
  3. The entire process (encoding, decoding, etc) must be automated. No manual manipulation of code caves or jump codes within a debugger.

The Test Environment and Selected AV Products

All testing was performed on a virtualized Windows XP SP3 machine (except for Symantec SEP testing which was conducted on a Mac Host). A Kali VM was used to verify operability of pre- and post-encoded reverse shell payloads.

I wanted to represent the “market share leaders” in the AV product market so I decided on using the opswat January 2015 report.

pecloak1

How accurately this truly represents market share is questionable (especially with a sample size of 4000) so I decided to test every vendor outside of the “Other” category as well as a sampling of vendors within that category. In the end, the vendors I chose were:

Avast Comodo
Microsoft Spybot
AVG Panda
Avira Trend Micro
Symantec Bitdefender
McAfee Bullguard
ESET Malwarebytes
Kaspersky Lab

With the exception of Symantec SEP, all tested AV products were the free versions offered by the respective vendor. The specific product name appears in the results section that follows.

I wanted to test multiple “malicious” executable payloads that would be easily detected by any AV product so I chose the following four:

  • Two metasploit payloads (meterpreter_reverse_tcp and shell_reverse_tcp)
  • A local privilege escalation exploit (KiTrap0D aka”vdmallowed” – http://www.exploit-db.com/exploits/11199/)
  • A metasploit reverse_tcp backdoored executable (strings.exe from sysinternals)

All were verified to function prior to any modification/encoding.

The Approach

For successful AV evasion, I figured I needed a few features.

  • First, I had to implement some form of encoding or encryption that would defeat signature based detection. I gave myself the additional constraint that I could only use simple xor, add, or sub instructions in my encoder — not because anything else would be too complicated, but rather to show that the encoding approach did not have to be complex to defeat signature based detection.
  • Second, I needed to defeat any sandbox -based, heuristic run time detections that might be employed by an AV product.
  • Third, I wanted to minimize the static nature of the decoding/heuristic code that would be included in the modified executable to avoid having it become a signature for AV detection.

A closer look at peCloak.py

To meet all requirements I wrote a python script that I dubbed “peCloak”. While I walk through the basic approach, please keep in mind that the bulk of this was written over a weekend so there are plenty of potential improvements that could be made. I am not presenting this as an alternative to existing tools like the Veil Framework and I don’t plan on maintaining the script beyond this simple beta version. This was simply the automated approach to AV evasion I developed in the context of my little “experiment”; though I hope that some of the approaches I used might be helpful to you if you’re considering delving deeper in the world of AV evasion.

Here’s a copy of my current (beta) version of peCloak.py:

peCloak.py
peCloak.py
Version: Beta
48.3 KiB
5322 Downloads
Details

Please note there are a few dependencies should you desire to try it out for yourself:

While I won’t be covering all of the code in-depth (it’s fairly well commented for a beta version), let me walk you through some of the approaches I used when developing this script.

Encoding

To avoid signature-based detections, there is an obvious requirement for some form of encoding. With my self-imposed constraints of using only basic add, sub, xor instructions, and dynamic construction of the encoding order, I came up with the following really simple encoder routine (portions of the function removed for brevity):

It meets all of my criteria — a simple set of instructions whose number, order, and modifiers are all chosen pseudo-randomly to increase variation.

The encoding process happens at script run-time by reading in the contents of the file and encoding the designated section(s) byte by byte. By default, the script encodes the entirety of the PE section that contains the executable code (typically the .text or .code section) but that’s a configurable option. I leverage the pefile library to do the heavy lifting for mapping the contents of the file and retrieving various sections.

You can see this basic encoding process illustrated in the below excerpt of the encode_data function:

Decoding

Decoding is also relatively simple in that it’s just the reverse of the encoding routine. The order of instructions is reversed (FIFO) and the instructions themselves must be inverse (add becomes sub, sub becomes add and xor remains the same). For example, here is an example encoding routine and it’s corresponding decoder.

Encoder Decoder
  1. ADD 9
  2. SUB 3
  3. XOR 2E
  4. ADD 12
  5. SUB 1
  6. XOR 3F
  7. ADD 7
  1. SUB 7
  2. XOR 3F
  3. ADD 1
  4. SUB 12
  5. XOR 2E
  6. ADD 3
  7. SUB 9

The decode function looks something like this:

To build the decoder, I simply use a dictionary of assembly opcodes for the inverse instructions of the various encode operations. I then loop through the encoder that was previously created and use that to build the corresponding decoder. This is necessary since the encoder is dynamically constructed (and therefore different) each time.

Here’s a look at that function:

Heuristic Bypass

The heuristic bypass routine is nothing more than a set of instructions that waste cycles in an effort to trick the AV scanner that the executable is benign. NOPS, INC/DEC, ADD/SUB, PUSH/POP are all candidates. Just as with the encoding routine, I select a pseudo random number and order of these benign instructions and pair them with an incrementing counter /compare instruction (also chosen pseudo – randomly from a given range) to create a loop of finite iterations .

The number of loops within a given heuristic routine is configurable at script run time, though keep in  mind that the more iterations you implement, the longer it will take for the cloaked executable to start.

The calls to add_fill_instructions() in both the heuristic and decoder creation functions simply pseudo-randomly select from a dictionary of the aforementioned benign instructions (inc/dec, push/pop, etc).

Carving out a code cave

Ultimately what the script does is encode the designated portions of the PE file and insert a code cave containing the heuristic bypass and corresponding decoder function. The location of this code cave is determined at script run time by first checking each PE section for a minimum number of consecutive null bytes (currently hard-coded at 1000). If found, it will make that section executable and insert the code cave at that location. Otherwise, the script will create a new section (named “.NewSection”) using the SectionDoubleP code. You can override the script’s attempt to insert the code cave in an existing section (if it appears to be corrupting the file) with the -a | –add option.

Jumping to the code cave

In order to jump to the code cave, the execution flow of the PE file has to be modified at ModuleEntryPoint. This process is two-fold:

  1. Create the jump instruction using the address of the previously created code cave
  2. Preserve the overwritten instructions at ModuleEntryPoint so they can be replayed later

The latter function is relatively simple in that I leverage the pydasm library to read the entry instructions and obtain the corresponding asm.

One important aspect of this function is to ensure that it preserves the instructions in their entirety. For example, assume the original entry instructions are

If your code cave jump overwrite is 5 bytes, you still want to ensure you’re preserving all 7 of the first two instructions or you’ll end up with corrupted code.

Restoring execution flow

At this point, the module entry contains the jump instruction to the code cave, which will start with the heuristic bypass function and then proceed to decode the encoded section(s) of the pe file. Once that’s done, execution flow has to be redirected back to its original location so the executable can function as intended. This is a two step operation:

  1. Replay the overwritten original instructions
  2. Jump back to the module entry point (offset by the added code cave jump)

Replaying the original instructions is complicated by the fact that they may contain relative jump/call instructions. The location of these jumps/calls need to be re-calculated from the current location in the code cave.

I’ve addressed this by recalculating relative jumps based on the original destination and the current address within the code cave.

The conditional_jump_opcodes and unconditional_jump_opcodes variables are just dictionaries of the respective opcodes. The referenced update_jump_location function is really simple and looks as follows:

Other features

As with anything I do, there’s usually a fair amount of scope creep and so I built a few extra features into the tool to help analyze the target file. For example, during testing, sometimes I wanted to be able to view a particular section of the PE file to determine what might be triggering signature based detection so I built in a simple hex-based viewer

pecloak2

Writing the Modified PE File

One last note is that in order to get expected results from my modification function I had to modify the pefile library slightly. Specifically, I ran into the issue that when pefile saves a modified executable, it overlays the section structure data on top of the modified bytes. In other words, if you modify the first 50 bytes of the .rdata section of a given file, that modification will be replaced by the original section header. To prevent this behavior, I added an additional parameter (SizeofHeaders) to the pefile write() function. This allows me to preserve the pe header but replace everything after should I choose:

pecloak3

Similarly, strings are also overwritten so I made some additional modifications to the write() function to prevent this as well:

pecloak4

Depending on the level of control you require of your modification, additional changes may be necessary, though these two modifications suited by simple testing just fine.

Here’s a look at the output (run with default settings):

pecloak25

Running the Experiment (peCloak in action)

Now that I had the tool, it was time to see how effective it was. Using the previously identified list of AV vendors, I downloaded their respective free AV products and got to testing. Again, my goal was to evade AV detection for each of the four test executables without breaking the exploit’s functionality.

Here is a summary of the results:

pecloak5

As you can see, a green check mark indicates successful evasion, a red X indicates peCloak could not successfully bypass AV evasion, and N/A indicates the AV product did not even detect the original uncloaked version so additional encoding was unnecessary. It should be noted that several products did not detect any of the uncloaked malicious executables (McAfee, Spybot, and TrendMicro) despite updated virus definitions. There were no apparent configuration problems or errors indicated by the product so the reason for detection failure is unknown. Regardless, these products were disqualified from further testing as a result. That left a total of 12 AV products that were tested.

The summary is pretty telling … I was able to successfully hide all four executables from detection in 9 of the 12 products (in some cases, evasion was unnecessary for one or two of the files as the original, unencoded files were not even detected. The only products that provided at least partial protection were Avast ,Bitdefender, and BullGuard. This is largely because any bytes contained outside of the PE file sections (.text, .data, .rdata, .rsrc, etc) are not modified by my peCloak script. For example, in at least one of these AV products, the signature detection was the result of bytes contained within the PE Header, which my script does not attempt to modify.

A quick glance at the table, will demonstrate that despite a few of the products detecting some of the executables, the best method of evading AV detection is by cloaking a backdoored executable (as I did with strings.exe). In fact, as you’ll see below, one of the products actually automatically whitelisted my backdoored executable without any action on my part!

A Closer Look

In case you want to replicate these findings with peCloak, or your own tool, what follows are the exact options I used to cloak each file from the respective AV product. A couple of things to note:

First, I did not include all of the screenshot evidence of each scan result for each file as I thought it would make this post way too long, though I did provide a sampling to illustrate some of the results.

Second, most of the byte range values I used to encode the files were not optimized. For example, if encoding bytes 0 through 500 of the .rdata section resulted in successful AV detection, as long as the executable still functioned as intended, I didn’t test it further to see exactly which bytes were responsible for detection. I’ll leave that exercise up to you should you so desire.

Third, when I refer to peCloak’s “default” settings, I’m referring to a heuristic bypass level of 3 (-H 3) and encoding of only the .text section. This is what happens if you simply run peCloak.py with no additional options.

Also, as reminder, the four files that were tested for evasion were:

  • av_test_msfmet_rev_tcp.exe – Metasploit Meterpreter reverse_tcp executable
  • av_test_msfshell_rev_tcp.exe – Metasploit reverse tcp shell executable
  • strings_evil.exe – strings.exe backdoored with Metasploit reverse_tcp exploit
  • vdmallowed.exe – local Windows privilege escalation exploit

The first three were constructed directly from Metasploit and the third was compiled using the source code at the link I provided at the beginning of this post. No efforts to encode these files was made prior to testing them with peCloak.

Avast Free AntiVirus (Evasion: 1/3, 1 N/A)

This product did not detect the unencoded version of vdmallowed.exe file but did detect the other three as malicious.

I successfully evaded strings_evil.exe by encoding a portion of the rdata section:
peCloak.py -e .text,.rdata:50:500 strings_evil.exe

pecloak21

I was not able to evade either Metasploit executable, even with all PE sections encoded (and the file rendered inoperable). Additional testing indicated detection resulted from the contents of the file header (which is outside of the scope of my simple peCloak script), so no additional evasion was attempted.

MSFT Security Essentials (Evasion: 4/4)

This product successfully detected all four uncloaked test files.

pecloak8

Three of the files (av_test_msfmet_rev_tcp.exe, av_test_msfshell_rev_tcp.exe, and strings.exe) successfully evaded detection with default peCloak settings (peCloak.py [executable name]).

I was able to successfully evade detection of  vdmallowed.exe by encoding an additional portion of the data section: peCloak.py -e .text,.data:50:5000 vdmallowed.exe

Avira (Evasion: 4/4)

This product successfully detected all four uncloaked test files.

Three of the files (av_test_msfmet_rev_tcp.exe, av_test_msfshell_rev_tcp.exe, and strings.exe) successfully evaded detection with default peCloak settings.

I was able to successfully evade detection of  vdmallowed.exe by encoding an additional portion of the data section: peCloak.py -e .text,.data:50:5000 vdmallowed.exe

AVG Free 2015 (Evasion: 4/4)

This product successfully detected all four uncloaked test files. peCloak successfully evaded detection for all four files using the default settings, though evasion was inconsistent. In other words, if an executable was cloaked twice using the exact same peCloak options, one of those cloaked executables would evade detection and the other would not. Additional testing showed that the detection did not appear to come from any of the sections of the PE file (leaving the header) though this makes it even stranger as to why detection would be inconsistent from file to file. This was the only AV product to exhibit this behavior. In addition, once a cloaked file was created that successfully evaded AV detection, testing showed that it would always evade detection, meaning the test files could in fact be reliably cloaked.

pecloak7

Successful evasion of one of the Metasploit payloads

Symantec SEP (Evasion: 3/3, 1 N/A)

As stated previously, testing of SEP was the only AV product tested on a Mac client (simply because I already had it installed). This product did not detect the pre-cloaked strings_evil.exe so additional evasion was not necessary. The remaining three pre-cloaked test files were detected.

pecloak6

I successfully evaded detection for both of the Metasploit executable files using default settings.

I successfully evaded detection of vdmallowed.exe by encoding a portion of the data section: f:\peCloak.py -e .text,.data:50:200 vdmallowed.exe

McAfee AntiVirus Plus (Disqualified)

This product did not detect any of the uncloaked malicious test executables despite having up-to-date signatures and exhibiting no errors before or after the scan. This may not be indicative of its normal behavior and as such it was disqualified from further testing.

pecloak17

ESET NOD32 Antivirus (Evasion: 3/3, 1 N/A)

This product did not detect the unencoded version of vdmallowed.exe file but did detect the other three as malicious.

pecloak11

I successfully evaded detection for strings_evil.exe using default settings. I successfully evaded detection for both av_test_msfmet_rev_tcp.exe and av_test_msfshell_rev_tcp.exe by encoding a portion of the .rdata section on each:

peCloak.py -e .text,.data:17000:1500,.rdata:50:500 av_test_msfmet_rev_tcp.exe

peCloak.py -e .text,.data:16000:50,.rdata:50:500 av_test_msfshell_rev_tcp.exe

pecloak13

Successful evasion of one of the Metasploit payloads

Kaspersky Anti-Virus 2015 (Evasion: 4/4)

This product successfully detected all four uncloaked test files.

I successfully evaded detection for strings_evil.exe and vdmallowed.exe using default settings.

pecloak14

I successfully evaded detection for both of the Metasploit executable files by encoding a portion of the .data section on each:

peCloak.py -e .text,.data:500:10000 av_test_msfmet_rev_tcp.exe

peCloak.py -e .text,.data:500:10000 av_test_msfshell_rev_tcp.exe

Comodo Free Antivirus (Evasion: 3/3, 1 N/A)

This product did not detect the unencoded version of vdmallowed.exe file but did detect the other three as malicious.

pecloak15

All three of the remaining files were successfully cloaked using the default peCloak settings.

pecloak16

Successful evasion of one of the Metasploit payloads

Spybot 2.4 Free Edition (Disqualified)

Similar to McAfee, this product did not detect any of the uncloaked malicious test executables despite having up-to-date signatures and exhibiting no errors before or after the scan. Even worse, it actually automatically whitelisted strings_evil.exe! This product was disqualified from further testing.

pecloak18

Bitdefender Antivirus Free Edition (Evasion: 2/4)

This product successfully detected all four uncloaked test files.

pecloak19

Two of the files (vdmallowed.exe and strings.exe) successfully evaded detection with default peCloak settings.

I was not able to evade either Metasploit executable, even with all PE sections encoded (and the file rendered inoperable) indicating signature detection was likely resulting from the contents of the file header, so no additional evasion was attempted.

BullGuard Antivirus (Evasion: 2/4)

This product successfully detected all four uncloaked test files.

pecloak20

Two of the files (vdmallowed.exe and strings.exe) successfully evaded detection with default peCloak settings.

I was not able to evade either Metasploit executable, even with all PE sections encoded (and the file rendered inoperable) indicating signature detection was likely resulting from the contents of the file header, so no additional evasion was attempted.

Malwarebytes Anti-Malware Free (Evasion: 2/2, 2 N/A)

This product did not detect the unencoded versions of the vdmallowed.exe or strings_evil.exe files but did detect both Metasploit stand-alone executables which were successfully cloaked by encoding a portion of the .data section.

peCloak.py -e .text,.data:50:500 av_test_msfmet_rev_tcp.exe

peCloak.py -e .text,.data:50:500 av_test_msfshell_rev_tcp.exe

Panda Antivirus Pro (Evasion: 3/3, 1 N/A)

This product did not detect the unencoded version of strings_evil.exe file but did detect the other three as malicious. I successfully evaded detection for vdmallowed.exe using default settings. Both Metasploit stand-alone executables were successfully cloaked by encoding a portion of the .data section.

peCloak.py -e .text,.data:50:500 av_test_msfmet_rev_tcp.exe

peCloak.py -e .text,.data:50:500 av_test_msfshell_rev_tcp.exe

pecloak22

Trend Micro Antivirus + Security (Disqualified)

This product did not detect any of the uncloaked malicious test executables despite having up-to-date signatures and exhibiting no errors before or after the scan. This may not be indicative of its normal behavior and as such it was disqualified from further testing.

pecloak23 pecloak24

Conclusion

What does this all mean? Well probably nothing you didn’t already know — AV detection is flawed. At the same time, so many organizations seem to put a lot of stock in the use of AV and while I wouldn’t advocate throwing it away entirely, it certainly shouldn’t be thought of as an absolute control.

Also, as we continue to hear about all of these “advanced” attacks that used “sophisticated” malware that went undetected, you have to wonder how advanced were they really? … especially if one can easily hide a known malicious binary so easily?

At the very least, I think I supported my hypothesis and this little experiment has demonstrated that if you’re faced with needing to bypass AV detection for a penetration test, developing your own method may not be that difficult after all.

Until next time,

Mike

30 Comments add one

  1. jan kuan says:

    Nice work, but PyDasm is dead, and missed many instructions.
    Now about using Capstone (https://github.com/aquynh/capstone)? You can easily install it with just 1 command:

    $ sudo pip install capstone

    • Mike Czumak says:

      Thanks for the suggestion. I don’t plan on maintaining this past beta at this point but I’ll keep Capstone in mind for future projects.

  2. Jarth says:

    I’ve noticed malware bytes may have a knock out weakness. No longer filtering URL’s.

    Pretty hard to believe MSFT proved effective. Usualy Kaspersky or Malwarebytes find hundreds to clean.

    • Mike Czumak says:

      Thanks for the feedback. I didn’t consider MSFT SE to be effective at all. Detecting unencoded known malicious binaries should have been normal behavior for all of the tested AV products in my opinion. That fact that I was able to easily cloak these binaries from Security Essentials made it just as ineffective as most.

  3. tk says:

    Another brilliant write up. Thanks for sharing this. Well done!

  4. Kilroy says:

    I would like to know what version of each AV product you tested this against.
    Each AV product is pretty well established and it would add more weight to the report if you identified each version tested.

    • Mike Czumak says:

      The short answer is that all AV products, with the exception of Symantec 12.1 for Mac and Windows Security Essentials, were downloaded, installed, and had virus definitions fully updated on March 8 2015. Both SEP and MSFTSE were previously installed had updated virus definitions as of that date as well.

      Several of the AV products were installed using a downloader exe (TrendMicro_TAV_8.0_US-en_Downloader.exe, F-SecureNetworkInstaller.exe, PANDAIS15.exe, bitdefender_antivirus.exe, BullGuardDownloader.exe), which ensured the latest version of that product was obtained (as of 8 March 2015). A couple however were self-contained installer packages:
      Kaspersky: kav15.0.2.361en_7201.exe
      Comodo: cav_installer_3269_65.exe
      Spybot: spybot-2.4.exe
      Malwarebytes: Malwarebytes Anti-Malware 2.0.4.1028
      ESET: eav_nt32_enu.msi (8.0.304.0)
      Avira: avira_en_av_5819400583__ws.exe
      AVG: avg_free_stb_all_5751p1_177.exe

      Hopefully this answers your question.

  5. Chris Morton says:

    A very interesting article, confirming a lot of what we all suspect.

    I’d be interested to know if webrootfared any better as it (at least claims) to work differently.

    I was recently discussing it with one of their devs and I have a spare serial that he gave me that you could use if you’d be interested in testing it?

    • Mike Czumak says:

      Thanks Chris. I took a quick look at the webroot website and didn’t see a way to download the product without purchasing first. That said, you’re more than welcome to give it a shot with the version of peCloak I posted to see if evasion is possible. My approach to this experiment was to try and test the products with the largest market share (and those typically deployed to large organizations) to see how they fared but I would not be surprised if there are better products that won’t be fooled by my basic techniques.

  6. runtime? says:

    Did you run the exe like an attacker would? Many AV detect the binary once it hits the disk.

    • Mike Czumak says:

      Good point.For the initial detection of the unencoded binaries, they already resided on disk and were scanned in-place with an on-demand scan. In most cases these unencoded binaries were detected (as they should have been). In addition, since peCloak writes a new, encoded version of the binary to disk, it mimicked exactly what you’re describing. In fact, when products like Avast detected the cloaked exe, it was usually at write time, before I needed to initiate an on-demand scan. If the cloaked binary made it past the write operation, I then performed an on-demand scan to see if the AV product detected it. If it still remained undetected, I ran the binary to ensure it still functioned and also to see if the AV would detect it at run-time. I think I covered most bases with this approach.

  7. hi i got this error with admin user ;( same in the w7 and winxp with py 2.7.9
    plz help me , why ?

    error :

    [!] ERROR: Could not save modified PE file. Check write permissions and ensure t
    he file is not in use

    • Mike Czumak says:

      Aside from write permission issues, the problem could very well lie with the write() function of pefile. As you’ll see in my post, I modified this function and if you made an error when making these changes that could be the cause. My recommendation is to print out a more descriptive error instead of my generic try/except to see the exact cause.

  8. ty man now its work

    ;^)

    [*] New file saved [fff_1426775410_cloaked.exe]

    but nod32 was detected unknown Virus 😉

    this method do not work in x64/meterpreter/rev_tcp Payload ?

  9. 0x90 says:

    Hi Mike

    I’m just preparing for the OSCE exam, and whilst I probably can’t use your script in the exam (?), it’s great, and your site too is excellent – thanks!

    • Mike Czumak says:

      Thanks for the feedback! Yeah, assuming you needed to do something similar on the exam, using my script would not be allowed but I’m glad you’ve found the post useful.

      – Mike

  10. Phobos69 says:

    Sorry but i have the same error: “[!] ERROR: Could not save modified PE file. Check write permissions and ensure the file is not in use”
    when I use the command “./peCloak.py test.exe”

    But I don’t understand how to solve.

    • Mike Czumak says:

      My recommendation is going to be the same … replace the generic error message from the try/except with a more descriptive error to see what the problem is and be sure you’ve properly modified the write function.

  11. Phobos69 says:

    I follow your suggestion and this is the detail of the error:

    Traceback (most recent call last):
    File “./peCloak.py”, line 1186, in
    main(sys.argv[1:])
    File “./peCloak.py”, line 1183, in main
    save_cloaked_pe(pe, file)
    File “./peCloak.py”, line 220, in save_cloaked_pe
    pe.write(pe.OPTIONAL_HEADER.SizeOfHeaders, filename=fname) # MODIFIED WRITE FUNCTION IN PEFILE!!!
    TypeError: write() got multiple values for keyword argument ‘filename’

    Thanks in advanced, for you help.

  12. Phobos69 says:

    Thanks for the feedback! I have read better your post and modified the file. Now works.
    Many Thanks.

  13. trudnai says:

    I just came across of this, but Dude, sorry to say that but you have just discovered fire… This was done somewhat 20 years ago and since then continuously used by malware authors. I barely can see any malware these days that are not encrypted / obfuscated / cloaked (call whatever you want, same stuff). Most exploit kit even apply polymorphism, metamorphism or oligomorphism on the decryption routine, so that every time you pull down the file it looks different. Look up “malware packer” for further study.

    • Mike Czumak says:

      Not sure if you read the whole post, but I think you missed my intent (and you’re actually supporting my point). I am very familiar with malware packers and frequently analyze malware that utilize various forms of obfuscation. This was not at all intended to be portrayed as a new discovery or a novel approach. This was simply a validation that modern AV products are still being eluded by the same old tricks.

  14. Yu Yang says:

    Hi, could you specify which reverse shell you were using in your experiment? I just tried with /windows/shell_reverse_tcp generated by the latest MSF and use the command “peCloak.py -e .text,.data:500:10000 av_test_shell.exe” to encode. But it still can be detected by Kaspersky 2015. I even tried to encode all sections such as “peCloak.py -e .text,.data,.rdata shell.exe” but still not working well. Although the encoded shell does hide from most of antivirus engines in VirusTotal, Kaspersky still pops up a window “legitimate software could be used by intruder…” and deletes the shell automatically. I am really new to antivirus bypass and just start in OSCE. Do you have any idea what might be wrong? The encoded shell by peCloak just cannot hide from Kaspersky with default settings. Thanks.

    • Mike Czumak says:

      The success of simple AV evasion techniques like I demonstrated in this experiment will wane over time as signature detections are updated so it’s very possible you won’t be able to evade without making some additional modifications. If you suspect its a static signature that’s resulting in detection, you can manually encode various sections of the file until you are able to evade detection, see what is contained within that section and then see if you can encode or modify it in such a way that the program still functions but evasion is successful

  15. sansei says:

    Hi Mike,
    I try to bypass a specific malware by using your method “peCloack.py”, but it can not bypass the latest updated versions of Kaspersky and Bitdefender antivirus. I have read your post completely, but It was so ambiguous for me to make a specific change in the your encryption method in order to bypass these latest updated versions of antiviruses.
    Do you have any more complete documentation about this topic?
    Thanks in advance…

  16. jim says:

    Hey, thanks for the nice article. I am still very new at this, “a real noob”. I get this error. Any help please.

    C:\users\raph\desktop>c:\python27\python.exe peCloak.py
    Traceback :
    File “peCloak.py”, line 32, in
    import pefile
    File “c:\python27\lib\pefile.py”, line 26, in
    ImportError: No module named past.builtins

  17. max7253 says:

    If the code cave is in the section which is to be encoded / decoded, do you make sure you don’t decode the code cave at runtime? Or am I missing something?

  18. Kanishk says:

    The hexdump method skips every 17th byte, i suppose this might be able to fix it.

    Line 302: total_count -= 1