Solved by 梁智湧
由於題目程式中的power_up
在使用strncat
時用了錯誤的上限值,造成在寫滿bullet->desc
這個buffer時會overflow該buffer,使得bullet->power
的least significant byte被歸零。被歸零後,power_up
又可再讓使用者輸入更多的input而造成main
的stack buffer overflow,甚至覆寫main
frame的return address。
因為前述漏洞,我們得以覆寫main
frame的return address。由於程式本身有NX保護,必須使用ROP控制程式行為。但許多address因包含null byte,這些address無法被strncat
複製到buffer上,因此覆寫main
frame的return address時最多只能使用ROP執行某些gadgets。於是在exploit此題時我們使用了三段ROP chains:
此段ROP chain的目的是為了避免gadget address不能有null byte的限制。Chain中使用程式本身的read_input
將第二段ROP chain讀到memory當中某段可讀寫的位置上(bss區段上)後,將stack pointer migrate到該區段。此Chain共兩個gadgets,使用了7格stack(28 bytes)。
此段ROP chain的目的是為得知libc的address以得到更多的gadgets來組成可spawn shell的指令。其做法使用plt上的puts
dump出got上的address後,再度使用程式本身的read_input
將第三段ROP chain讀入memory以及migrate。此Chain共三個gadgets,使用了10格stack(40 bytes)。
在生成此段ROP chain時由於已知道libc的address,因此可以使用libc中的所有gadget,直接將程式換成shell。
$ python solver.py
CTF{Using_the_silv3r_bull3t_to_pwn_th3_w0rld}