几天前,我从 opensecuritytraining.info 中获取了这段代码来测试缓冲区溢出漏洞:
#include <stdio.h>
char *secret = "pepito";
void go_shell(){
char *shell = "/bin/sh";
char *cmd[] = { "/bin/sh", 0 };
printf("¿Quieres jugar a un juego?...\n");
setreuid(0);
execve(shell,cmd,0);
}
int authorize(){
char password[64];
printf("Escriba la contraseña: ");
gets(password);
if (!strcmp(password,secret))
return 1;
else
return 0;
}
int main(){
if (authorize()){
printf("Acceso permitido\n");
go_shell();
} else{
printf("Acceso denegado\n");
}
return 0;
}
注入shellcode之前的第一个测试是在不知道密码的情况下尝试执行go_shell函数,溢出main函数的返回地址并将其指向go_shell的位置。
据我了解堆栈划分如下:
[STACK] {Return_address}{EBP}{password_buffer(64)}...
所以如果我在 password_buffer 中存储 68 个字节加上 go_shell 的地址,它应该覆盖返回地址并执行所需的函数。
[STACK] {4bytes (Location of go_shell)}{EBP(4 Bytes of junk)}{password_buffer(64)(64 bytes of junk)}...
这里的问题是我需要用 76 字节的垃圾加上 4 字节的地址来填充缓冲区,以实际覆盖返回地址并将 %eip 指向 go_shell。我不明白的是那些额外的 8 个字节来自哪里?
这是注入 74 A (0x41) + if (!strcmp(password,secret)) 行断点中的地址之前的 GDB 输出:
EBP:
0xbffff4a8: 0x41414141 0x0804851c
AAAA + memory_address
并继续 go_shell 执行(断点在 void go_shell(){ ):
EIP 现在指向最后被覆盖的返回地址:
(gdb) x/2x $eip
0x804851c <go_shell>: 0x83e58955 0x45c728ec
任何帮助理解这一点?
问候。