It's been three months since my last post on windows exploit and RE, TBH I'm quite rusty so to keep up with the pace we will try to solve some challenges from https://github.com/naivenom/exploiting there is a section called "Windows Exploit Development - Exercises from CLS Exploits" this contains a handful of windows Exploit challenge that fit with my current skills(not too easy but difficult enough to force me to read the assembly code)
Prerequisite:
I run the challenge in windows 10 VirtualBox from https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/I suggest to download this VM since it's free and maintain by windows itself . Furthermore, throughout this challenge, I will use immunity debugger as the primary tool for analysis
Challenge 1:
Open the first challenge file with immunity debugger and you will see a ton of code inside such a small program. We can start the analysis by doing string analysis on the binary this would list all of the string inside the file this could give some ground information about what the program is actually do and locate the actual code.You can do this by using the search function from immunity debugger and choose "all referenced text strings"
let's try to trace the first entry, from the looks of it we can deduce that the string "rb"(read binary) is used for passing a parameter in reading a file function in C. (Double click it! and immunity will take you to the original location within the program)
alright let's try to analyze the code, first, the program starts by creating a random number using srand() function and stored it at [EBP-10]
then it opens a file called "example.txt" and notices there is comparison after opening the file this aim to check if the program exists or not if not it will print a string which is "bye-bye" and exit the program
if the file exists it will read the first 4 bytes of the file and print the content of it then it will feed into atoi() function which is used for converting a string to an integer. This gives us a clue that we have to create a file named example.txt with the first 4 bytes needs to contain integer
next, it turns out the program read again the next 4 bytes and convert it into an integer using atoi() and print the results
after printing the result of the two integers, notice the program do a comparison with the first integer which is located at [EBP-8] and the second integer located at [EBP-C], it compares whether the value is less(pay attention at the "JL" instruction after comparison) than 0xc8(which is 200 bytes) if it's not less than that it will exit the program
if it's yes it will continue the program by reading "again" the "example.txt" file but this time the size of how much the function of fread() will read is determined by the first integer value(located at [EBP-8]) and stored at EBP-DC
next, the program tries to show a random number to the user from [EBP-10] which is set at the beginning of the program and this is where it gets interesting.
Take a look at the second red box the random number that is set earlier will be XORed with the second integer located at [EBP-C] and after that, it will be compared with "0x41424344" (stands for ABCD in hex) if we able to match this value we win the challenge
but how we can do this? since the compared value is random
we can overflow the stack and change the [EBP-10] value with our value from example.txt since it is pretty close. But in order to do that we need to have more than 200 bytes, right? but there is a limit check in how much the function will read the content.
we can bypass this by supplying the first integer with "-1", it is less than 200 but if it's converted to hex in fread() function it will be "0xffffffff" which is enough for us to get all of the content from our example.txt(killing two birds with one stone)
then with all of that combine, we can craft our exploit like this:
~# python -c "print '-1 ' + ' 0' + 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADCBA'") >> example.txt
we fill the first integer as -1 for bypass limit check and the second integer as 0 because it will be used for XORed the random value, we set to 0 to make the random value(that will be overflow with the next content) to not changed at the final comparison.
Finally, to reach the [EBP-10] we need to supply 204 bytes follow with "DCBA"(remember little-endian):
run the immunity debugger again and we pass the challenge:
Challenge 2:
wow! that was pretty intense for the first challenge, okay let's move on to the second one.It seems it is not much different than the first challenge.
First, the program read the "example.txt" and then read 210 bytes content of the file and copy the value with strcpy() to another variable. Finally, the copied value is passed to the function named "EXAMEN_L.00A21010"
nothing interesting here let's move on to the called function:
the function will do a simple comparison if a value in [eax+c8] is not 0 it will lead us to program exit whereas if it's 0 it will show that we have passed the level 2. Let's run the program to see what is this location truly means but before you run it you need to put a breakpoint in the comparison instruction(note: I suggest to put a hardware breakpoint so every time you re-run the program it will stay there)
at the time of running the program, the location of [eax+c8] is in 0x006ff6cc and our input from example.txt is in 0x006ff604. You can see that the value of [eax+c8] is always "1" thus we need to change it by overflowing the stack to pass this level and with simple math from the figure below we need to supply 200 bytes to reach the location
craft the exploit file using python and walaa!! we pass the second level 2
Challenge 3:
It looks like the first part of the challenge is not much of difference with challenge 2, let's analyze the called function (EXAMEN_L.011A10B0)
the called function also has the same comparison with challenge 2 which forces you to overflow the stack by inputting 200 bytes to overwrite the value inside [EAX+C8] with 0 and if you are able to do it, the program will continue to call another function EXAMEN_L.011A1010 by using your input from example.txt as the argument
the called function also do another comparison by comparing the value at [EBP-C8] with "M". You can simply put a breakpoint at the strcmp call to know what is location [EBP-C8] about and it turns out it is a location of 40th character of your input from example.txt, so all you need to do here is to change 40th character with "M" and you pass the level
Challenge 4:
The fourth challenge starts with getting the 200 bytes of input from "example.txt" then saved it at [EBP-C8] then it moves the value again to the [EBP-19C] using strcpy function and before it calls another function(EXAMEN_L.003C1010) it is doing some check on [EBP-D4] if its value is equal to 1 and if it's not it will exit the program.
this comparison is just for checking if our input does not go over than 200 bytes so if you supply input less than 200 bytes you can pass the check
let's continue the analysis by going to the called function(EXAMEN_L.003C1010)
looking at the function we can see from the above figure that there are two comparisons. The first is comparing [EDX+CC] with 0x45("E") and second is [EAX+C8] with 0x46("F"). The two checks basically just comparing two locations in our input with "E" and "F"
let's try to put some pattern in our example.txt using pattern exploit tools(https://github.com/Svenito/exploit-pattern) to identify where we should put "E" and "F" in the input
ok so for the first comparison we need to put "E" at index 193 and for second comparison we need to put "F" at index 189
but we have trouble we can bypass the first check easily but the second check is pretty dodgy because rather than comparing value by index it compares by a range of character so we need to make sure to pass null value between the index 190-192 to pass the level.
We can do this by using python sys stdout library
run the program again and we passed the level
Challenge 5:
Basically, this challenge follows the same concept with challenge 4 however there is a little bit twist at the end :Dsame check limit and if you pass the check it will call other function EXAMEN_L.0041010 using our input from "example.txt" as the parameter
inside the called function there is same check which compare the 193rd character of your input with "E". The input is provided is the same with the input used to solve the 4th challenge
now this where the little twist begins, the first box show there is a second check that will check if debugger present when the program is run and at the end of the program there is the last check which checks if addition between [EBP+8] and [ECX+CC] is equivalent with 46
ok let's try to understand more about the last check we will go through each of the instruction
These two instructions were responsible to get the value at index 189-192 from our input. As you recall value 46 which is equivalent to "F" and we deliberately put this character at index 189 in the previous challenge.
TBH, I don't know exactly what instruction MOV EAX,DWORD PTR SS:[EBP+8] is doing all I can conclude is that it tried to pass location somewhere around the heap in-memory and use this value store in this location for the addition with our input
as you can see from the figure above the location contain a value with "BAADFOOD" and this value add with our current value which is "46"
this is all the information that I can get with "BAADFOOD":
0xBAADF00D: Used by Microsoft's LocalAlloc(LMEM_FIXED) to mark uninitialized allocated heap memory
so how to bypass this check then?
since the our inputted value is always added with "BAADFOOD" I can overflow the value that will reset to 0 and from there I can add additional bytes so it can equivalent with 46, like this
after couple trial and error 0x45521039 will overflow the value to 0 and add additional byte so it can become 0x46
cool! I hope you enjoy this post and see you at the next part of RE challenge Examenes windows
Comments
Post a Comment