If you haven’t read the first part, pwn400, please do so before continuing.
In this post I will only explain the differences between pwn400 and pwn600, and of course the exploitation methods.
The biggest difference is that here, we have a call to srand(time()) followed by rand(). The resulting value is used as a canary between the list->number_of_elements and list->array[n].
The canary is checked every time, we try to Update an index. If the canary has changed from the original value, the binary exits. Another difference is that here for the Main Menu’s option is compared with rep cmpsb instruction instead of strcmp. However, Sort Menu’s options are converted from ascii to integers via strtol which will allow us to substitute with system() and use just like we used strcmp in the previous part.
Knowing that our plan of action does not differ much.
Calculate the canary
Make list of 2 elements
Use canary and 0x40000001 as elements
Sort, so the ptr to the struct is saved
Leak the ptr to the struct
Overwrite the ptr to struct with ptr to struct+8
Update the elements so they are no longer sorted. We need the number_of_elements in index 0 and canary in index 1
Invoke ‘reload’ to cause the initialization of the new active list. This list just like before, it will
use our array as number_of_elements and array as canary