Skip to main content

Format String Exploit and It's Power (一_一) warm up (day 62)



For the past couple of months you guys see me doing lot of buffer overflow exploitation in Linux and Windows but buffer overflow itself is not the only approach in memory corruption attack. There are other techniques such as format string and heap overflow method

But today we are going to focus on Format String attack.

So what is it ?

Format string attack is an attack that are taking an advantage on how the print function work in C.

you guys already know some of them such as printf, sprintf and so on my point is any function from print family

typically you use print function like this:

void main(){

int a = 10;
printf("%d\n",a) ;

}

notice that we parse a string format which is %d, that represent an integer so this telling the program to show the output of the program from variable a.

But things to get little funny when we create program like this:

void main() {

char buffer[512];

fgets(buffer, sizeof(buffer), stdin);

printf(buffer);

}

so whats wrong with this snipped code? we reserve the buffer to be in the correct length, thus we just avoid buffer overflow and after that we print it to the console.

can you guess?

yes! the printf function is the problem we don't specify the format string and let user take control on what they want to print

printf work by using the format string as the reference to the variable that was passed so with this the printf itself know what value that need to be showed

but if we don't specify the format string in the function and let user take control of the input they can just supply another format string that will leaked the stack

like this


notice here there are bunch of hex characters and all of it actually coming from the stack.

cool! right? using Format string attack we are able to dump the stack value, but hold on dumping the stack will not do much of a exploitation right ?

I agree but there much more than meets the eye. The truth is format string can be leverage into RCE

how ?

we will cover this in the next chapter, this post used to show you some capability that how format string can be utilized to be more rather than just showing stack

Before you go further, I suggest you guys study the basic of format string exploitation from protostar or other blog since the next part demand you to have at least a little bit knowledge of format string exploitation.

Also to all of you who already been around in security might notice that format string is already long gone and might not be necessary to learn about it. But once again we should never close our eyes with every possibility since the exploitation might arise again.

https://www.helpnetsecurity.com/2019/07/22/cve-2019-1579-poc/
https://blogs.grammatech.com/tainted-data-and-format-string-attack-strike-again


So let's get into the interesting stuff:



note: you can get the code at protostar format 3 challenge

compile the following piece of code with this command:

~# gcc format_func.c -o format_func -m32 -no-pie

as you guys already know this following piece of code is contain vulnerable printf implementation we can pass some string format in the buffer and leaked according stack value to our input

in the first phase of format string attack we need to know the location of our input in the stack



use the following piece of code to determine at what location in the stack that our input is held on. The code itself is pretty straight forward, we loop until 30 iteration and enter a format string then see the result that fit our goal. Notice the symbol "$" before the "x" this is meant we are going to use direct parameter access so we don't have to type multiple "%x %x %x" every time

 

cool :) so our input is at the 15 iteration of the loop so by the information we can confirm it by doing it manually.



so what's next ?

as you guys know from the code, it is expect us to modify the variable target inside the binary with the value 0x01025544

we are going to use the capability of format string to edit the value in runtime.

How ?

we going to approach this task by using the format string "%n" this format let us to write an integer value of number of bytes written so far to the stack

but doing this task could take up your time if the value is too big. To be more effective we can utilizes what so called "short writes"(%hn) that allow us to write 2 bytes at a certain location

let me show you the example in this following code



part 1, first we assign some variable that hold important information to our exploitation. at the beginning we can see that there are two variable first is target_location and target_location_higher this is the location of target variable that we must change in the program. You can get it by typing:

~# p &target

now as I explained earlier that short write only able let us to write two bytes so we need to initialize the location of target variable along with the next two bytes so we can fully write the variable

then we set value of the offset we got earlier which is 15 and the value that we want to insert at the variable "target"

part 2, concatenate the two variable that contain target variable so when we hit the offset the "%hn" can reference the location at write it at the stack

part 3, here where get it get interesting

as I mentioned again that the short write only let us to write two bytes we need to divide the value 0x01025544 into two pieces.

you can do it by little bit of math, but I think this algorithm is more flexible

lower_addr = target_value & 0xFFFF
high_addr = target_value >> 16


so we divide 0x01025544 into two variable one is going to held the lower address which is 5544 and the high address which is 0102

once we got the two variable we are going to concatenate it with the buf variable

buf += "%" + str((lower_addr - len(buf)) & 0xFFFF ) + "p%" + str(offset) + "$hn"
buf += "%" + str((high_addr - lower_addr) & 0xFFFF) + "p%" + str(offset+1) + "$hn"

but before we can concatenate it with the buf variable we need to adjust the value since the buf variable already have value of location of "target" variable

so if we passed the value like this

buf += "%" + str(lower_addr ) + "p%" + str(offset) + "$hn"

it will be 0x0804c02c0804c02e%21828p%15$hn

this will write 21828 + 8 since the "%n" will write number of bytes written so far in order to make it right we need to subtract it with the buf variable length first and this concept also apply to the second short write that will contain the higher address we need to subtract it again with the lower address to adjust the write value.

the last is just invoke the binary and passed our payload to it.

run the following script with:

~# python exploit.py LOCAL DEBUG


cool so we just change the value of variable

hope you enjoy this and see you at the next post.


Comments

Popular posts from this blog

Having fun analyzing nginx log to find malicious attacker in the net (ง'̀-'́)ง (day 37)

  What makes you sleepless at night? is it because of a ghost or scary stories? is it because you have an important meeting tomorrow? or is it because you have an exam? For me, what keeps me up all night is that I keep thinking about what happens to a website that I just created, is it safe from an attacker (certainly not) or did I missing some security adjustments that lead to vulnerability? well I'm not the best secure programmer in the world, I'm still learning and there is a big possibility that I can make a mistake but for me, a mistake can be a valuable investment to myself or yourself to be better so from this idea, I want to know more about what attackers casually do when attacking a website. Here in this post, I'm going to show you how I analyzed attack to the website that I have permission to design and also some interesting findings that I could get from the analysis Background: All of this analysis comes from the traffic that is targeted to th

Utilize Pwntools for crafting ROP chain :') (day 69)

who doesn't like pwntools? it is a very versatile tool and can be customized according to our need using the python script but did you need to know that pwntools itself can help us to automatically craft a rop chain for us? so in this post, I will show you how to make rop chain less painful and make pwntools do all the heavy lifting. To demonstrate this I will use the binary challenge callme 64 bit from ropemporium link: https://ropemporium.com/challenge/callme.html Crashing the app: Like any other exploitation process, we need to crash the program by generating a long string pattern to determine the offset. based on the information from the above figure we can see that we required to provide 40 bytes of offset Fun stuff: now this where the fun stuff began write the following python script: as in the guideline of the challenged said we need to chain the function call by first to call the callme_one function, callme_two function and then callme_three funct

WriteUp PWN tarzan ROP UNICTF ಠ_ಠ (day 61)

So in this post, I'm going to talk about how to solve the Tarzan pwn challenge from UNICTF 2019. Back in the day when the competition is still going I couldn't finish it and don't have any clue to solve this but this time I was able to finish it :) Also in this post, we will be going to be heavily focused on how to utilize pwntools to construct a ROP chain. If you kinda confused about my explanation in this post you can refer to this following youtube video, link: https://www.youtube.com/watch?v=gWU2yOu0COk I build the python script based on this video Ok, let's get started! In this challenge, you will get two binary first go with tarzan and libc-2.29.so by providing .so file it tell us what version library that the target machine is using this could help us to do ROP chain. first, we run the Tarzan binary to get the basic idea of the program work and as you can see it just show you some text, newline and when you try to input something it doesn't gi