When joining the ctf, Xion and procfs had already worked on that challenge and Xion already provided code for a PIE leak and pointed out, that by renaming a polygon to the same name will reset the polygon (setting the address of the vertex array to 0 and length also to 0).
That enables an arbitrary write in set_vertex, since index will now always be smaller than length-1 (overflow)
So, we have a PIE leak and an arbitrary write, but with that we can only write stuff in bss, so we need to find a way to get some kind of code execution and then pivot the stack into bss to do something more useful there.
Preparing PIE leak and an array for arb write
As for getting initial code execution, we can overwrite the vtable of _D27TypeInfo_HAyaS4main7Polygon6__initZ to point to a fake vtable, which we can also put into bss
With a fake table on bss, we can achieve, that when we try to create a new polygon, it will call an arbitrary function defined by us, while passing that new polygon as parameter to it. Without knowing libc, there’s not too much we can do with that, so we’ll need to find a way to pivot the stack also into bss.
When the vtable function will be called, rcx will point to the vtable itself.
Searching for a way to pivot the stack, we overlooked the perfect gadget for that for quite some time :D
This will push the vtable address onto the stack and then pop it into rsp, by which the stack now points to our vtable and then it’s even so nice to move it 0x18 bytes forward into a controllable area :)
Now creating a new polygon would try to use our fake vtable (at offset 0x152b50) and then call the GOSTACK gadget, which will set rsp to rcx, letting the stack point to our vtable and then move it forwards by 0x18 bytes. The stack would now point to the ADDRSP18 gadget, which again moves the stack 0x18 bytes forward out of our vtable, where we can now put our final ropchain.
After this new will then trigger our system("/bin/sh") ropchain giving us a shell.