Format String Vulnerability 2 - Writing data in memory

Hi everyone,

Today I will be discussing about exploiting format strings. In case you did not read the 1st part you can read here ( http://oxhat.blogspot.com/2017/12/exploiting-format-string-vulnerability.html )

In this post I will show you how we can exploit format string to write data in memory. Here is a code from a fictitious admin. Please note we have disabled ASLR system wide during this work.

The code is self explanatory but still I will give a small overview about it: The code is from a fictitious admin. He has removed the password check and hence the variable called "success" that controls login never gets affected due to it. That means the value of the success variable is always 0. The admin is confident that this will stop unauthorized access to the application. Let us prove him wrong by exploiting it.


What will be our attack ?

Our attack will be to overwrite the success variable value with some arbitrary value so that the check pass as it will become non-zero. 

If we run the code with a small input , let us see what happens

Now let us run the code with a longer input and see what happens
Or maybe even looooonger, 10000 characters INPUT.
Sadly none of our long inputs could overwrite it. But why ? Let us try to find the reason why we couldn't overwrite it, by loading in gdb.

Our stack address lies in range between 0xbffeb000 to 0xc00000000

Where does our variable "success" lies ? ( We can see it in the output as well as in the object dump )
This means they are lying at entirely different region and hence the overflow is not happening..

Hmm .. did I see the fictitious admin giggling at us ???


Let us look into the code again, we can see that the code uses an user controlled printf function. Let us try same method from previous post to dump contents using a format string exploit.

Sweet! It worked as expected.

Now let us try adding some more format strings and see if we can print some of the string we entered. We will add a TAG so that we can know the offset at what the arguments are stored in memory. The TAG we will use here is AAAABBBB.

So within the range of 200 memory location in stack , we find our input as 41414141 42424242

So what can we do now over here with format string. Well the concept goes something like this.

Step 1: In format string the attacker passes various format string as input like $x %x or %p etc. So when the printf function will be called, those format strings will be first pushed on the stack and they will point to certain address on the stack and they start printing out values from the stack. So we will try to overwrite the location of a stack memory with a memory of the address variable or any variable you have supplied to store the results.

Step 2: The format string %n return the number of bytes it has written till the format string in the memory. This value is generally written at the address referenced by the location where the string ends.

Chaining Step 1 and Step 2

We will first try to find how many format strings are required to pop out our TAG at the end of the output of the format string. After trial and error we find its 125.

You might wonder why did we use `python -c  'print "AAAABBBB"+"-%x"*125'`-%x instead of `python -c  'print "AAAABBBB"+"-%x"*126'`. The reason is once we find the exact format string that spits out the tag we need to replace that particular string format with %n. So we have kept one %x separate.

Next our target is to inject the address of the "success" variable in the last location of the TAG replacing BBBB or 42424242 by the address of the variable.

You can see we are able to write our TAG with the address of the variable. So now we are all loaded to give our fictitious admin a panic. The last piece of the puzzle will be to replace %x with %n. So that will return the total bytes written to a memory location that is referenced at the end of the string which resides in stack and now points to success variable.
And Boom ! We are now into Admin ! Check we are able to overwrite the value of variable success with 779 ( the total characters that is printed from AAAA till 41414141- . I still need to work on this why it shows random values between 777 to 779 sometimes. Maybe someone can help ? )

References
https://www.geeksforgeeks.org/g-fact-31/
https://www.geeksforgeeks.org/format-string-vulnerability-and-prevention-with-example/
https://www.exploit-db.com/docs/english/28476-linux-format-string-exploitation.pdf