Protostar Heap 2
protostar heap2
this will be the explanation on the protostart heap2 Use After Free vulnerability
cool little trick i have learned about this script, is that sometimes c programs that take user input will be stuck in a constant loop, through the while without asking for user input
not sure what causes this, but this script provided us with a solution:
this should ensure that the program will not continue until it recieves input
just thought it was a neat little trick since nowhere on the internet does it mention this problem im sure in some obscure corner there is probably somebody who can deal with info, but i guess i found it here anyways
anyways, on with reversing the binary, we have the source code so we could just look at it but that isnt the point of these writeups, i want to understand everything about this vulnerability and about this binary.
Lets explain what the program is doing from the source code, then match that up with the disassembly
first, it will create a struct called auth, it will have a char array for the name, and an int auth then we see the struct being initialized, a pointer to an object of struct auth along with a pointer to a char array named service
now we are at main
this first section of main will declare our buffer to read our input into with the fgets this will constantly print out our program status, then read in user input and store it in line no stack buffer overflow vulnerability here, will only read in 128 bytes
lets check out the auth check next, it will check if our input is equals to the auth keyword things may get confusing so let me walk through all the instances of auth we have a pointer to a struct called auth, and within that struct we have an integer variable called auth, this is very poor naming btw.
anyways, it will allocate the sizeof auth on the heap, and return the pointer to auth the only way to know how many bytes it allocated, is to read the dissassembly it will then zero out auth.
Then will check if the line+5 is less than 31? this is very random, and i sure hope it serves a purpose later on if that passes the check, it will then copy that string into auth->name on the heap i presume it will copy line+5?, line is a char array, so either they are talking about the address of the char array in memory or i am missing something
anyways lets continue, we can come back to this strange scenario
this check is simple, it only reads in "reset", and nothing more, if we input reset it will free auth, completely free it off the stack(may still be stored in thread local cache(tcache))
service was our pointer to a char array(string) at the start remember? lets just think of service as a string, now it will duplicate line+7 into service? again, my best guess as of right now is that line+7 is incrementing the pointer address by value 7 in decimal.
last, we have our login function, this as well only reads in 5 bytes, the size of the string "login" it will check if the auth struct pointer is equals to service
i assume that our end goal will be to achieve "you have logged in already", since that seems to be the only string in this binary that seems to represent success and fail
now that we have walked through the code, lets try and find a way to exploit this this should be a use after free, since we have the ability to free an object, and use the object on our command
again, our auth command just for reference, will allocate the size of our auth object memset/zero out that memory on the heap since malloc does not initialize the data
"we can use calloc to automatically zero out that memory for us, though i dont know if that function will bring in some complications within the challenge"
it will then check the length of the input, and see if it exceeds the size of auth->name if all is ok, it will then copy the characters after the auth command will be copied "auth " will be ignored
reset is simple and needs no further explanation, it will read in "reset", then free auth nothing else
service is simple as well, so we dont need to step through it, though its got a lot of moving pieces that need explanations. The service function will read in 6 bytes, the size of "service" then will change our "string" pointer to strdup(line+7), which means that it will read in the bytes AFTER your command "service"
lets think of this scenario for example, lets run the program and input:
service loser
the address of that input string(line), will have an address space, and that address space will be in base 16(hexadecimal), if we wanted to iterate through that, we could simply move up that address space since it is a string, or an array of chars it will store that next char in sequential order in memory. which means that:
since service is 6 bytes, and the space counts as a character, we are now at the input after we said service. Im sure that there is something very very wrong with this solution, but im not one to prod around with best practice, this works just fine in this scenario i guess :/
the last "function" we have within the binary is "login" this is pretty simple as well, it will only read in 5 bytes, the size of login to compare it against our input, if auth->auth is not zero, then it will tell us that
else it will prompt us with
that is the only functionality that serves
now that we have fully reviewed these functions(again), since the first time wasnt so coherent lets(actually) exploit this binary now
first, we look at what "strdup" does, since this is an important function in helping us exploit this
so it allocates the new string in the heap?, very interesting, very interesting indeed so we have a way to write what we want onto the heap
so now that we know this, the solution to the challenge is this:
we must first initialize the auth struct on the heap, since login requires the pointer to it
then, after our pointer to auth gets updated, we can free it a quick note: free() will not destroy the pointer, so after we free() auth, the pointer will still remain, so it still believes that auth->name and auth->auth still exists on that address but we know better right?, we know that we had just free'd it off the heap, its gone, only the pointer to that empty address remains lets play with that
after our free, we can write to the heap with "service" we will be able to write to the same area that auth was allocated, since we had free'd it we will be able to write over the addresses to where auth is pointing to now all we have to do, is to write to the heap using service:
Boom! and we are logged in already!
Last updated
Was this helpful?