Travel tracker lets us add, view and edit reviews. Nothing special there, but it also contains an option to save the reviews.
This will open /dev/null and then print the review to it. writeToFile contains a format string vulnerability, since it just calls
We won’t be able to see the output of it, since it’s written to /dev/null, but we can still exploit it. airportCode can only contain 10 chars, so it will be a bit of a hassle to do something useful with it.
With gdb we can find the possible parameters, that can be used
Parameter 6 will contain a pointer to our comment chunk on the heap. Since we first need some leaks, we can use this to write into the comment field to get some pointers.
Though as already mentioned, the possible format string is only 10 chars and the string is on the heap, so we cannot reuse addresses from our input.
But we can use a neat little trick using dynamic width parameters for printf
With *3 we specify, that the width for the string should come from the third format string parameter. This would write a string with 0x565571d1 whitespaces. %6$n will then write the count of written characters to the address at parameter 6, which is our comment chunk.
This will effectively write 0x565571d1 into our comment field, which we then can read via View all airport reviews.
We’ll use this, to leak an ELF, heap and libc address.
With those addresses at hand, we can now craft a ropchain in our comment chunk and try to pivot the stack into it.
We can again use the dynamic width trick to now write the address of our comment chunk into ebp, which parameter 9 points to.
This will take the address of comment from parameter 6 as width and then writes it to parameter 9.
The prologue of main would then move the stack 8 bytes before our heap chunk, pop ecx from there and then loads ecx-0x4 into esp again.
So we cannot directly pivot into our chunk. To get around this, we can first allocate a bigger comment chunk, fill it up with addresses to our final comment chunk, free it via edit and then trigger the stack pivot.
While locally, I could just do a system("/bin/sh") ropchain, it didn’t work out remote, so I opted for a stage ropchain.
Since the comment will be moved to the heap via strcpy it must not contain any null bytes, but for an execve("/bin/sh", 0, 0) ropchain, I’d need some. So the first ropchain will just read the final chain into bss and then stack pivot there.
After pop ecx
So ecx now points exactly to comment+0x4, and lea esp, [ecx-0x4] will stack pivot into the comment chunk.
We can now send the second ropchain, which will then do execve("/bin/sh", 0, 0)