很好理解的一个攻击

条件:1、程序存在栈溢出至少溢出0x10字节(32位至少溢出0x8个字节)。

​ 2、程序中存在后门,如:system(“/bin/sh”);

这里我们写一个demo测试一下

环境:gcc (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>

void backdoor(){
system("/bin/sh");
}

int main(){
char buf[0x10];
puts("plz input your name:");
read(0,buf,0x40);
return 0;
}

编译命令:gcc -no-pie -fno-stack-protector 1.c

img

这时候将生成的elf文件进行反编译,查看代码。

img

这里看到buf的大小是0x10也就是16,而我们可以写入的长度是0x40,这样就可以造成一个溢出。

这里要先介绍一下stack的结构

img

buf的大小是0x10(这里一个单元格为0x8的大小,所以buf占两个单元格),在buf下是rbp的位置,也就是栈底寄存器的位置,占0x8。再往下是占位0x8大小的ret(返回地址),ret这个地方控制了当前函数执行过后所返回的地址,所以如果劫持到ret地址,就可以将程序的执行流执行想要执行的地方。在pwn中我们最终目的是getshell,也就是执行到system(“/bin/sh”),思路就是将ret地址修改成system(“/bin/sh”)的函数地址。

这里rbp+ret是0x10大小,所以上面条件中我们说程序存在栈溢出至少溢出0x10字节。

这里我们是写了system(“/bin/sh”)的,所以我们只需要找到函数的地址。

img

地址为0x40057b

img

也就是说我们只需要溢出将ret覆盖成0x40057b就可以getshell

写入之后我们发现rbp中已经被修改成了backdoor函数

img

在栈回溯中也能看到体现

img

通过动调往下看,也可以看到这里执行到了system(“/bin/sh”)

img

成功getshell

img