Monday 1 April 2013

How to find a bug, exploit it and write your own 0day exploit

In order to think like a hacker, we'll need to examine and practice their methodology and test it against our own system.

The art of exploitation


Lets say we have a target (ourselves) and ran nmap (a portscanner) on it and discovered open port. The service running on it is SLmail v 5.5.

How do we look for a vulnerability? Since its a binary thus the source isnt available, all we can do is download a trial version, reverse engineer it or fuzz test the software. Let's try fuzzing, i.e. sending expected, or random data to the inputs of a computer program.

Here, im running linux on my attacking machine and installed SLmail on a windows XP xp2 and I want to test the POP service on port 110. Since I do not know the account credentials, the only commands I can fuzz on that service are USER and PASS. On the windows machine, install and start SLMail. Then attach ollydbg to it. (just start ollydbg and click file, select "attach" and select SLmail)

There are several fuzzers available, spike being my favourite, but to keep it simple I'll write a very basic fuzzer in python to illustrate the concept:
In the above code, I skipped the USER command fuzzing since it didnt crash. To fuzz PASS, you need to first input a "USER username" command first. Now we're ready to fuzz PASS. The program will connect to port 110, supply a user name and then send a bunch of A's, if it doesnt crash the program, it will send more A's, on so on (until I send about 5000 A's in this scenario).

We check Ollydbg and oops we do get a memory access violation!



As you can see, we have overwritten the EIP with A's (represented by 41)
Since the EIP register controls the execution flow of the program, that means we can now control the application and redirect it to do whatever we want. A shell would be nice!

Now we must find the exact 4 bytes in our buffer to overwrite it. Here's a way to narrow it down:


If we overwrite the EIP with A's in this new code, that means the 4 bytes overwriting the EIP are located in the first 1000 byte range, if B's, in-between 1000 and 2000, and do on.

Lets see what happens in ollydbg:



Looking at the EIP register, we can see that we have overwritten in with E's (\x45), thus the 4 bytes we're looking after are in-between 4000-5000 in our buffer. We could do this for a while until we get them but I'll let you on a a neat tool by metasploit. pattern_create.rb, it creates a specific pattern and will provide us with the exact location. So we need a length of 5000 so we issue the following command:

we copy the output and paste it in our buffer:

We send it and check the result in ollydbg.
We take the bytes that overwrote the EIP and we need to convert them since they're in hex and reverse them because of the order they go in the EIP. To save you the trouble, i wrote a little script that will sort this out for you:


The output was z1Fz. So now we use the other tool provided by metasploit to know the exact location of the EIP.



We now have the location of the EIP, at 4654. lets test it with our script:



Here we send 4654 A's, then 4B's and then C's. So we shoud overwrite the EIP with B's(\x42), lets check ollydbg:



Bingo, we overwrote exacty with 4 B's the EIP. We are in full control of th EIP. Whats left to do is to find a convenient location for our shellcode. To do that we need to examine the CPU registers right after the crash. click on the ESP register (stack pointer) and select follow in dump. Nice, i have a 1000s C's at that location, more than enough room for my shellcode.

To find a way to ensure we get to the ESP, we need a way to get to the ESP address. For that let's click the 'E' button (Executable Modules button) to look at the DLL's. USER32.DLL is convenient since it's in the core DLL system and its address is static accross service packs. From there we need to find a 'JMP ESP' instruction. So just click on USER32.DLL and click 'search for' and type in 'JMP ESP'. Here;s its at 77D718FC. So in our script, we will now send 4654 A's, then overwrite the EIP with that address so that it will use the JMP ESP instruction to send us to our shellcode. But for testing, we'll send C's after:



You probably noticed the \x90 in my code, its a NOP instruction, which is no instruction. This is just in case I do not land precisely at the address of my shellcode, it will slide the NOPs to it.

Lets's check ollydbg:



Bingo, look in the bottom right corner, we landed right in my NOPs followed by Cs! All we have to do is replace the C's by the shellcode!

You can find shellcodes on the net, although it can be risky, you can write your own or use a metasploit to provide you one. You can use a shellcode that will bind a shell on a port on the target machine, but if he's behind a router, that’s not very effective, so I'll show you how to use a metasploit tool to write a shellcode that will make the target machine connect to us instead:



So the target machine will connect to me, in that case 192.168.2.37 because we are on the same subnet, but that works over the internet as well. so we add our shellcode to the script:



Now we need to have a listener on port 4444 to receive our shell from our victim. Metasploit provides a nice handler for that.
Start metasploit then:


Now that we are listening on port 4444, we launch our exploit!

bingo we get a connection!
From there we can set up a keylogger, etc, but anyway, to get a shell, just use the following command:



Congratulations, you have a shell!:



For those of you reading that are unfamiliar with python, programming and the tools mentionned in this article, no worries, I'll soon keep you posted on how to use them.

"Take advantage of the enemy's unreadiness, make your way by unexpected routes, and attack unguarded spots." --Sun Tzu

2 comments:

  1. I would love to read this with the images intact. Any hope of an update?

    ReplyDelete