Wednesday 18 November 2015

An Easy Guide to Bypass DEP using ROP

               DEP (Data Execution Prevention) was introduced in Windows in 2004 with Windows XP Service Pack 2 which ensures that data does not gets executed unless it has execute memory rights (PAGE_EXECUTE). To bypass DEP  we will use ROP (Return Oriented Programming) gadgets. I have also provided MS Visual Studio solution in a zip for testing. 

What is ROP ?:

           After the introduction of ASLR (Address space layout randomization) shellcodes which had hardened addresses of the APIs started to fail. For example API UrlDownloadToFileA was located at 0x781C4868 in windows XP SP3 even after reboot. Hence it was very easy to develop exploits and shellcodes. From Windows 7 onwards, most of the essential modules started to load at random addresses after every reboot (due to ASLR) which failed all previous shellcodes / exploits which had defined fixed addresses in their exploits. But few remained ASLR disabled (msvcr71.dll, msxml15.dll etc ) which are still loaded at the fixed addresses in similar builds of Windows even after reboots. This gives an opportunity to use some of the code section (gadgets) in an artful way to change memory protection rights of shellcode area. For example, we can find the instructions necessary to prepare the arguments on stack and then call the VirtualProtect function to change the memory rights of shellcode region and then execute it. This can be done by first calculating the instructions which could do this and then populating it on stack in a manner that there is a "ret" instruction at the end of those instructions. When "ret" gets executed OS will pop an address from ESP (stack pointer) and transfer control to that instructions and so on and so forth. Once all parameters to VirtualProtect /VirtualAlloc are prepared a JMP instruction to VirtualProtect will change memory permissions of shellcode region and hence DEP will be bypassed.

Purpose of ROP:

  • Change memory region rights (or allocate memory) of shellcode to PAGE_EXECUTE or PAGE_EXECUTE_READWRITE (DEP bypass)
  • Change EIP control to ROP chain (stack pivot)
  • Execute shellcode

This Blog:

  •  Using C for demonstration of ROP
  •  ROP gadgets creation using mona.py (immunity debugger's extension) in msvcr71.dll
  •  Use of VirtualProtect function for changing memory rights

Requirements:

  1. MS Visual Studio 2008 or higher
  2. Immunity debugger with mona installed. For installation guide click here
  3. Windbg (optional). Download form here

Steps: 

  1. Set up VS project ( Download VS project )
  2. Create ROP chains /suggestion using mona 
  3. Build the exe and open with Immunity or windbg. Program will halt on software breakpoint (int 3) instruction defined in inline assembly 
  4. Step into ROP gadgets and see the behavior of ROP chain. When arguments to VirtualProtect are prepared, PUSHAD instruction pushes arguments on stack and returns which is a jump to VirtualProtect function. 
  5. Shellcode will get executed and calculator will popup showing the successful bypass of DEP by ROP
Build and test environment: Windows 7 x64 SP1

1. Setup project:

Open the .sln file with Visual studio or create new project in visual studio and copy paste the rop_x86.cpp file contents in main file and build the solution. We will use msvcr71.dll for creating ROP chain. This dll is loaded most of the times, but if it isn't loaded already, we can use LoadLibrary API to load it. In this example i have loaded it using LoadLibrary as you can see in the code. 

2. Creating ROP Chains:

    Here i assume that you have installed mona in immunity by now. Now to check which modules (dlls) are ASLR disabled give this command !mona noaslr in the command window at the bottom as shown in image 2.1


Image 2.1
-------------

You can see that there is one module which is ASLR disabled, means we can use this module to generate rop chain. To generate gadgets provide command !mona rop -m msvcr71.dll which will create three files namely rop.txt, rop_suggetsions.txt and rop_chains.txt. Rop_chains.txt will contain nicely prepared rop gadgets in different languages like C, python and ruby. Image 2.2 shows the output of rop generation command. 

Image 2.2
-------------

I have used some of these gadgets and some of my own. You can search for specific gadgets in rop.txt and rop_suggestions.txt files. Some of the gadgets created by mona are shown in image 2.3.

Image 2.3


3. Analysis of ROP with Windbg / Immunity: 

                         Execute the binary and it will break at instruction "int 0x03" as shown in image 3.1. As breakpoint will hit, source file will be loaded and we will be able to see the source as well. Then step into using F11. Next instruction will add 0xd0 to ESP. Actually rop gadgets and shellcode declared in char ROP_shellcode[] are pushed on stack. To trigger the rop chain we have to point ESP to first gadget and execute the "ret" instruction. In real world exploits it is called stack pivot (usually xchg eax,esp ; ret) but in this scenario i have simplified it by pointing ESP to rop chain and then executing "ret" instruction manually. Difference of ESP and rop chain is shown in image 3.2  and difference is evaluated in image 3.3. 


    Image 3.1
    -------------

 Image 3.2
-------------


 Image 3.3
-------------

Image3.4 shows the rop chain in immunity debugger. By stepping in you can see the execution of rop step by step.  

Image 3.4
-------------

 4. ROP Chain Execution: 

                             From here on we will be executing rop chain. Stepping in using F11 will give a fair idea that how rop gadgets are executed. You will notice that every instruction is followed by "ret" which triggers another gadget until the purpose is achieved. Thats why this is called return oriented programming (ROP). 

Image 4.1
-------------


Here (image 4.2) is the chain with symbols (dps display addresses with symbols) showing addresses of msvcr71.dll 

Image 4.2
-------------

 Main purpose of this chain is to prepare arguments to VirtualProtect in registers in an order that when "PUSHAD" intruction is executed, stack should be prepared in following order (image 4.3) at gadget 0x7c3415a2.

Here is little description of VirtualProtect from MSDN.

BOOL WINAPI VirtualProtect(          =>    A pointer to VirtualProtect()
  _In_   LPVOID lpAddress,           =>   Address whose rights have to be changed (some address down the ESP)
  _In_   SIZE_T dwSize,              =>    dwSize up to you to chose as needed (0x201)
  _In_   DWORD flNewProtect,         =>    flNewProtect (0x40)
  _Out_  PDWORD lpflOldProtect       =>    A writable pointer
);

Following image shows the stack when VirtualProtect is called via a jump to pointer ( to VirtualProtect) stored in EAX.


Image 4.3
-------------

To see the memory rights at this point use !address esp command which will show the memory rights of the page as given in image 4.4

Image 4.4
-------------

5. Identifying successful DEP bypass:

Set a breakpoint at gadget pointed by ESP (bp 7c35630c) and run the sample using F5 command or "g". When breakpoint hits, check the memory rights using !address esp command. You will notice that the page will have PAGE_EXECUTE_READWRITE protection rights as shown in image 5.1.









Image 5.1
-------------

After confirming memory rights elevation, we can give command "g" in command panel which should popup the calculator (image 5.2) if everything goes well. In my tests i have observed that sometimes stack is not aligned and an exception occurs, in that case just re-run the sample and it will run fine.

Image 5.2
-------------


You can also visit these links which are more rop development-centric rather than reversing / analysis of rop gadgets:
  1. Corelan
  2. FuzzySecurity

Enjoy exploiting!!!

Tuesday 20 October 2015

FireEye Flare Challenge 2 (2015) Solutions


This year's Flare challenge was lengthier and tougher than the last year's. Some android challenges were also included which give a chance to experience mobile reversing for people like me who never had the chance to explore that side. Anyways lets get started.


Challenge 1:

Challenge 1 exe (Flare-On_start_2015.exe) is 64 bit executable which is actually an EULA (End User License Agreement). Upon accepting the agreement challenge binary with the name of i_am_happy_you_are_to_playing_the_flareon_challenge.exe is extracted. This challenge can be solved by two ways, one, the easy one, by decompiling and the other by reversing. I always choose the hard way in initial challenges because it helps in furher challenges.

Here are the steps:

  1. open the binary with ollydbg/immunity 
  2. right click in the main thread and click search for and  all referenced strings
  3. Click "Lets start with easy. Enter password". It will open assembly.
  4. Insert a breakpoint on call to kernel32.ReadFile some lines below
  5. enter some garbage string, press enter. It will stop at breakpoint. press F8
  6. You can see the XOR AL, 7D instruction. 7D is the key
  7. Now xored byte will be compared one by one in the memory in next instruction. It means if we just XOR this data with 7D, we will have our key. For this i have written a python script which prints the key after xoring.




Here is the script:

bytes="1F08131304220E114D0D183D1B111C0F18501213531E1210"
j=0
email=''
while j < len(bytes):
try:
email+=chr(int(bytes[j:j+2],16) ^ 0x7D)
j+=2

except:
j+=2
pass
print email


Challenge 2:

 Challenge 2 is on the same footing as challenge1 but a bit harder.  Same steps can be followed to reach at the password matching block.
Algorithm:
char+=previuos
char & 03
rotate (ah) left with anded result of above
xor your input with C7
add above result with ah+carry
compare usinf scos in reverse





Following script replicates the above algorithm, key is found using bruteforce :)

def print_in_reverse(bytes):
a=[]
j=0
while j < len(bytes):
a.append(bytes[j:j+2])
j+=2
x=len(a)
b=''
while(x!=0):
b+=a[x-1]
x-=1
return b
def ROL(data, shift,size):
    shift %= size
    remains = data >> (size - shift)
    body = (data << shift) - (remains << size )
    return (body + remains)


#  get data in reverse
bytes="AFAAADEBAEAAECA4BAAFAEAA8AC0A7B0BC9ABAA5A5BAAFB89DB8F9AE9DABB4BCB6B3909AA8"

j=0
r=''
a=[]
bx=0x0000
add=0
key=0x00
result=''
bytes=print_in_reverse(bytes)
while j < len(bytes):
anded=bx & 0x03
add=0
add=ROL(1, anded,8)+1
found =False
key=0x00
while(found==False):
if (int(key ^ 0xC7)+add) == int(bytes[j:j+2],16):
found=True
result+=chr(key)
else:
pass
key+=1

bx+=int(bytes[j:j+2],16)
j+=2
print result 


Challenge 3:

Challenge 3 looks annoying in the beginning but if you investiagate the memory and strings, you will realize that its the easiest one. Strings investigation by pestudio did not reveal anything useful, except lot of garbage as exe has been created by QT framework. When i started to see some base64 strings and other code structures in dump, i became interested in memory dumps rather than strings.

elfie.exe creates another process so opening it in debugger won't do any good. Run the elfie.exe and attach the debugger with the process whose window name is "Look inside! you can ..."

Steps:

  1. Go to View -> Executable Modules. Select QtGUI4
  2. Click M (memory dump) in the task bar 
  3. Search for "import base64". Memory dump shows the concatenation of base64 strings which will be decoded and executed, see the below images


image 3.1

image 3.2

     4. Save this file (right click and backup ->save data to file) with py (c3.py in below example) extension, after removing junk code above and below the dump. Run this command and you will have the code for this binary saved to c3.txt


 image 3.3

5. Email string is printed in reverse, as in below image


image 3.4

Challenge 4:


As soon as you check the file attributes of youpecks using PE exploerer or some other tools, you will realize that the bnary is UPX packed and name suggests too. In my test i could not get around it by unpacking by upx (exception occured right after execution). So, you have to manually unpack and reverse it. If you use Ollydbg 2, it will automatically stop at the OEP (original entry) and let you analyze the rest cleanly.
Without argemunets binary terminated early, so i tried with an argument. I must say i was lucky to see the email in plain after some analysis. Put a breakpoint on memcpy functions and see the data being copied, email will be there after copying some base64 strings. Later i figured that if you provide "16" as argument, email is printed after 2 + 2 = 4.


Challenge 5:


This challenge is little interesting than the previous ones. A pcap is given that contains the encoded data captured on the wire, we have to find the key with which it was encoded using the suspected binary sender.exe which is sending this data. Here are the steps to solve it:
  1. open the pcap in wireshark
  2. apply filter "http". Every packet contains the four bytes string. Save this data for later use
  3.  Open the binary "sender.exe" with ollydbg or with your favorite debugger. It requires a file with the name "key.txt", from which binary reads the keys and encodes it. So, create a file in the working directory with the name key.txt and write any junk data in this file.
  4. First of all every character of the key is added with "flarebearstare" string  as shown in the following image
  5. Then an algorithm encodes the data and later this data is sent. Here is the little snap of the assembly code where key is being encoded. Here is my understanding of algorithm

       
                            C5.2
c5.4


C5.5 Algorithm 

alphanumerals='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/='
for all keys:
key_data+="flarebearstare"
while(read key_data):
array[2]=3 bytes from key
checkbit or whatever=array[2]&0x3f (position) in alphanumerals
first_char=array[0] >> 0x12 anded with 0x3f (position) in alphanumerals
second_char=array[1] >> 0x0c anded with 0x3f (position) in  alphanumerals
first_char=array[2] >> 0x06 anded with 0x3f (position) in  alphanumerals
sent_data+=first_char+second_char+third_charcheckbit



I have written a python script which takes the pcap data and reverses it into the key. Here is the script:
    
                
#!/usr/bin/python
addent="flarebearstare"
#encoded string retrieved from pcap
result="UDYs1D7bNmdE1o3g5ms1V6RrYCVvODJF1DpxKTxAJ9xuZW==" 
str='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/='
def position(chr):
x=False
pos=0
while x!=True:
if(pos<len(str)):
if(str[pos]==chr):
x=True
return pos
pos+=1

def iterator(data): # reversing function
i=0
key=''
b=0
shift=0x12
k=0
pos=position(data[3:4]) #position of encoded chars in string
end=pos&0x3f # checksum 4th byte of each encoded string
tmp=0
while b!=3:
pos=position(data[b:b+1])
k=(pos&0x3f)
if shift == 0x12:
key=hex(k)[2:4]
tmp=int(key,16)<<shift
if shift == 0x0c:
key=hex(k)[2:4]
tmp+=int(key,16) <<shift
if shift == 0x06:
key=hex(k)[2:4]
tmp+=int(key,16) <<shift
b+=1
shift-=6
tmp+=int(hex(end)[2:4],16) # add 4th byte thing
#print hex(tmp)[2:] 
return hex(tmp)[2:8]

val=''
j=0
while j < len(result):
tetro=result[j:j+4] # four bytes chunks as in pcap
val+=iterator(tetro) 
j+=4
email=''
i=0
index=0
# loop to minus flarebearstare string and get the original key 
while(i < len(val)):
try:
if index == 14: #length of flarebearstare 
index=0
email+=chr(int(val[i:i+2],16)-ord(addent[index]))

index+=1
i+=2
except:
index+=1
i+=2
pass

print email


More to Come....

 

Sunday 20 September 2015

Detecting Shellcode using LibEmu's Sctest Tool


           Libemu is an x86 emulation library. It has many tools though but i will be covering "sctest" only. This tool has very good detection rate. First lets make a raw shellcode with metasploit's msfvenom tool.


$ msfvenom -p windows/messagebox  -f raw > shell.bin

where:
-p payload
-f format of generated payloads. For complete list type msfvenom --help-formats

(Note: sctest require input data in form of raw bytes, so you have to convert your shellcode into raw data if you generate shellcode in other formats.)

After creating shellcode , lets test it with sctest tool. 


$ cat shell.bin | sctest -gvS -s 1000000

where:
-g using GetPC heuristics
-S input from stdin
-v verbose
-s step-count

Above command result:

verbose = 1
success offset = 0x00000000
[emu 0x0x7fb331404c10 info ] The following function is a stub instr_wait_9b functions/misc.c:88 
unhooked call to MessageBoxA
stepcount 157109
HMODULE LoadLibraryA (
     LPCTSTR lpFileName = 0x00416fb2 => 
           = "user32.dll";
) = 0x7e410000;

"success" marks the presence of shellcode in the given data, shell.bin. Some more information is also provided like LoadLibraryA call and call to MessageBoxA api.

For query, please comment.