HITB-GSEC-XCTF 2018 Pwn-Writeup

Last week , HITB-GSEC-XCTF.
We solved four PWN problems and work out another MutiPig after the game.
Now I'll make a record and summary.


Easy blind format string.
Just dump the binary first and guess the offset of .plt and .got.
Then DynELF for leaking libc base or use this powerful!
Last, change plt['printf'] to system and input "/bin/sh" to get shell.
I didn't solve it in time because doubting about my dump binary is wrong :-D..
Paste my teammate's script


We I frist meet this problem it's familiar with the CUIT pwn500

Just as the name describe , ever operation just make only once.

The vulnerability is an obvious heap overflow with editing.

And heap chunks(0x20) are organized with double circular linked list, and operation of delete is just act on the last one and is an unsafe unlink without any check.

Similar to the thinking in CUIT, My train of thought as belows:

  1. leaking libc address
  2. Use heap overflow and unsafe unlink change global_max_fast from 0x80 to a larger number.
  3. Fastbin index will cause main_arena overflow and overwrite arbitrary 8 byte with our heap chunk address, I change to overwrite _IO_2_1_stdout_ pointer.
  4. For avoiding one_gadget lose efficacy, I chose to build a fake file with vtable and use _IO_str_overflow to Getshell.

It's a troublesome method ,so I search out another easy method.
Use unlink to change pointer at 0x202068 to 0x202020, and then we can change the construction(flags) in .bss and we can use not only once.

Then by simply reading in __free_hook we can control flow.


There are three operations:

  • Read message
  • Edit message
  • Wipe message

On read message, our input will be base64 decode and store in heap chunk and there is a vulnerability in decode algorithm.

There is a base64-padding vulnerability.
Base64 decode does not check the length properly and will cause off-by-null but seriously

if we input two == it will drop "\x00" at the end of the string and edit only judge the length by strlen() that will cause heap overflow.

But it's annoyed because edit by strlen and write a byte "\x00" at end constraintly it means we can't not change GOT['free']=>system directly.

So my train of thought seems a lit complex and strange…

  1. Heap overflow and unlink twice.
  2. alter atoi to printf create a format string vulnerability and leaking libc.
  3. For break through the limitation of the number of edit,I change strlen to alarm for a larger return value to edit free to system.
  4. free("/bin/sh") execute system("/bin/sh").
    Also, because of heap overflow , many method can use for exploiting.


Notice libc version is 2.26.
It's all about tcache ,learn from tcache
so it's easy to exploit the process like fastbin dup ,however it's simpler because there's no check in tcache, it may not be a proven technique.

Notice two tips:

  1. Ever tcache bins has limited number 7. However,we can alloc 8 bins, it means the last one use unsortedbin or smallbin.
  2. tcache check nothing, it means we can use double free without consideration anything.


It's a template of House of rabbit
I have's never seen before, so can't work out in the end.
By the way,House of rabbit is a really funny technique based on your deep understanding in Glibc malloc.