2

我编写了以下程序来自学缓冲区溢出和内存寄存器:

#include <stdio.h>
int main(int argc, char *argv[])
{
    char name[400];
    strcpy(name,argv[1]);
    printf("Hello %s!\n",name);
    return 0;
}

溢出它大约需要 432 个字节。

$ ./bof `python -c 'print "A"*432'`
Hello AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA!
Segmentation fault: 11

当我试图让它执行实际的 shell 代码时,问题就来了。我首先尝试使用 pattern_create.rb(包含在 metasploit 框架中)找到偏移量。但是,我得到的不是分段错误,而是 EXC_BAD_ACCESS。

(gdb) run Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6
Starting program: /Users/me/Downloads/bof Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6
Reading symbols for shared libraries +.............................. done
Hello Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6!

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: 13 at address: 0x0000000000000000
0x0000000100000f0d in main ()
(gdb) 

我正在运行 OS X 10.8.5。有没有人有任何想法?

[编辑]

当我用一大堆 nops 运行它时,我得到以下输出,这是不同的,但仍然不是我所期望的:

(gdb) run `python -c 'print "0x90"*108'`
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /Users/me/Downloads/bof `python -c 'print "0x90"*108'`
Hello 0x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x900x90!

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000000
0x00007fff8539d700 in tlv_load_notification ()
(gdb) 
4

1 回答 1

1

随着程序参数 [1] 变长,OP 正在经历各种未定义行为 (UB)。

int main(int argc, char *argv[]) {
  char name[400];
  strcpy(name,argv[1]);
  printf("Hello %s!\n",name);

一旦 argv[1] 有 400 个或更多字符,strcpy(name,argv[1]);就开始将数据复制到内存的各个无主部分。

OP 在输入字符串长度为 432 时遇到了 seg 错误,但由于它是 UB,明天它可能会在另一台机器上使用不同的数据发生变化。OP 没有解释如何设置这些数据。我假设 argv[1] 是通过 OP 的开发环境设置的。

OP 在 shell 中运行并有不同的结果“EXC_BAD_ACCESS”。既然是UB,什么事都有可能发生。考虑到缓冲区溢出,这种类型的错误肯定是预期的 UB 类型。

OP 说:“当我试图让它执行实际的 shell 代码时,问题就来了。” 我会断言问题很简单发生在程序执行时strcpy(name, TooMuchData)

于 2013-10-20T00:50:07.087 回答