简体   繁体   English

缓冲区溢出攻击

[英]Buffer Overflow Attack

I'm trying to execute a very simple buffer overflow attack. 我正在尝试执行一个非常简单的缓冲区溢出攻击。 I'm pretty much a newbie to this. 我几乎是新手。 So, if this question is stupid, please excuse me :-) 所以,如果这个问题很愚蠢,请原谅:-)

The code: 代码:

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

int i, n;

void confused(int i) 
{
 printf("**Who called me? Why am I here?? *** %x\n ", i);
}

void shell_call(char *c) 
{
 printf(" ***Now calling \"%s\" shell command *** \n", c);
 system(c);
}

void victim_func()
{
 int a[4];
 printf("Enter n:  ");  scanf("%d",&n);
 printf("~~~~~~~~~~~~~ values and address of n locations ~~~~~~~~~~");
 for (i = 0;i <n ;i++) 
  printf ("\n a[%d] = %x, address = %x", i, a[i], &a[i]);
 printf("\nEnter %d HEX Values \n", n);

 // Buffer Overflow vulnerability HERE!

 for (i=0;i<n;i++)  scanf("%x",&a[i]);
   printf("Done reading junk numbers\n");
}

int main() 
{
 victim_func();
 printf(“\n done”);
 return 0; 
}

When I use objdump to get the function addresses, I have the following: 当我使用objdump获取函数地址时,我有以下内容:

main(): 0x804854d
Address of main() where printf() is called: 0x8048563
victim_func(): 0x8048455
confused(): 0x8048414

Now, what I want is to jump to the function 'confused()' from victim_func() by overflowing the buffer there, and overwriting the return address to the address of confused(). 现在,我想要的是通过溢出缓冲区来从victim_func()跳转到函数'confused()',并将返回地址覆盖到confused()的地址。 And I want to return back from confused() to the printf() statement in main, and exit normally. 我想从confused()返回到main中的printf()语句,然后正常退出。 So, I provide the following input 所以,我提供以下输入

Enter n: 7
Enter 7 HEX values:
1
2
3
4
5
8048414 (This is to jump to confused)
8048563 (this is to jump to printf() in main)

Although, the program prints "Done" from that printf statement, it is jumping back to victim_func() and prints "Enter n:" 虽然程序从该printf语句打印“Done”,但它会跳回victim_func()并打印“Enter n:”

What am I doing wrong? 我究竟做错了什么? Any help would be greatly appreciated! 任何帮助将不胜感激!

PS: I'm not sure if I have put the question right. PS:我不确定我是否提出了正确的问题。 Please let me know, if any more information is needed. 如果需要更多信息,请告诉我。

A buffer overflow attack is a lot more complex than this. 缓冲区溢出攻击比这复杂得多。 First of all you need to understand assembler in order to perform this. 首先,您需要了解汇编程序才能执行此操作。 After you disassemble the program and function you want to target you need to determine the stack layout when it's executing that function. 在反汇编您想要定位的程序和函数后,您需要在执行该函数时确定堆栈布局。 Here's a sample of a buffer overflow it's using visual studio but principle is the same. 这是一个缓冲区溢出的示例,它使用visual studio,但原理是相同的。

#include "stdafx.h"
#include <math.h>

volatile double  test;

double function3()
{
    test++;
    return exp(test);
}

double  function2()
{
    return log(test);
}

double  function1()
{
    int a[5] = {0};           
    a[7] = (int)&function3;
    return exp(function2());

}
int _tmain(int argc, _TCHAR* argv[])
{
    double a = function1();
    test = a;
    return a;
}

Thanks to disassembly we know that a in function1 is allocated before where the function saved the stack frame pointer. 由于反汇编,我们知道函数1在函数保存堆栈帧指针之前被分配。 The value after that one is the return address where function1 should go to if it is finished. 之后的值是function1应该完成的返回地址。

00401090 55               push        ebp    <- we save the stack pointer
00401091 8B EC            mov         ebp,esp 
00401093 83 EC 1C         sub         esp,1Ch <- save space to allocate a[5]
00401096 B8 CC CC CC CC   mov         eax,0CCCCCCCCh 
0040109B 89 45 E4         mov         dword ptr [ebp-1Ch],eax  <- crt debug init a[5]  
0040109E 89 45 E8         mov         dword ptr [ebp-18h],eax 
004010A1 89 45 EC         mov         dword ptr [ebp-14h],eax 
004010A4 89 45 F0         mov         dword ptr [ebp-10h],eax 
004010A7 89 45 F4         mov         dword ptr [ebp-0Ch],eax 
004010AA 89 45 F8         mov         dword ptr [ebp-8],eax 
004010AD 89 45 FC         mov         dword ptr [ebp-4],eax 

From this we can conclude if we overwrite a[7] with a different address, the function will return not to main but with whatever address we wrote in a[7]. 由此我们可以得出结论,如果我们用不同的地址覆盖[7],函数将不返回main,而是返回我们在[7]中写入的任何地址。

Hope this helps. 希望这可以帮助。

Now, what I want is to jump to the function 'confused()' from victim_func() by overflowing the buffer there, and overwriting the return address to the address of confused()... 现在,我想要的是通过溢出缓冲区来从victim_func()跳转到函数'confused()',并将返回地址覆盖到confused()的地址......

On modern Linux platforms, you will also need to ensure two security features are turned off for testing. 在现代Linux平台上,您还需要确保关闭两个安全功能以进行测试。 First in NX-stacks, and second is Stack Protectors. 首先是NX-stacks,其次是Stack Protectors。

To turn off NX-Stacks, use -Wl,z,execstack (as opposed to -Wl,z,noexecstack ). 要关闭NX-Stacks,请使用-Wl,z,execstack (与-Wl,z,noexecstack )。 To turn off Stack Protectors, use -fno-stack-protector (as opposed to -fstack-protector or -fstack-protector-all ). 要关闭堆栈保护器,请使用-fno-stack-protector (与-fstack-protector-fstack-protector-all相反)。

There's a third protection you might need to turn off. 您可能需要关闭第三种保护措施。 That protection is FORTIFY_SOURCE. 这种保护是FORTIFY_SOURCE。 FORTIFY_SOURCE uses "safer" variants of high risk functions like memcpy and strcpy . FORTIFY_SOURCE使用“更安全”的高风险函数变体,如memcpystrcpy The compiler uses the safer variants when it can deduce the destination buffer size. 当编译器可以推导出目标缓冲区大小时,编译器会使用更安全的变体。 If the copy would exceed the destination buffer size, then the program calls abort() . 如果副本超过目标缓冲区大小,则程序调用abort() To disable FORTIFY_SOURCE, compile the program with -U_FORTIFY_SOURCE or -D_FORTIFY_SOURCE=0 . 要禁用FORTIFY_SOURCE,请使用-U_FORTIFY_SOURCE-D_FORTIFY_SOURCE=0编译程序。

The security features are turned on by default because there's been so many problems in the past. 默认情况下会启用安全功能,因为过去存在很多问题。 In general, its a good thing because it stops many problems (like the one you are experimenting with). 一般来说,这是一件好事,因为它可以解决许多问题(比如你正在试验的问题)。

First of all it seems to me that you shouldn't enter the number 5 in your sample input. 首先,在我看来,你不应该在你的样本输入中输入数字5。 Your array is declared a[4] thus has elements indexed 0-3 - so your attack input seems wrong to me. 你的数组声明为[4],因此元素索引为0-3 - 所以你的攻击输入对我来说似乎不对。

It also seems to me that your program assumes several thing about the architecture: 在我看来,您的程序假设有关架构的几件事:

  • sizof(int)==sizeof(memory address) sizof(int)== sizeof(内存地址)
  • The direction of growth and mechanism of the environments stack implementation 环境堆栈实现的增长方向和机制

If one of these assumptions is untrue it's never going to work. 如果其中一个假设是不真实的,它就永远不会起作用。

This seems like a very hard work work assignment. 这似乎是一项非常艰苦的工作任务。

There are easier examples of buffer overflow attacks than changing the control flow of the code. 缓冲区溢出攻击的简单示例比更改代码的控制流更容易。 For example you might be able to overwrite another piece of data which is supposed to be protected from the user (such as a security setting) 例如,您可能能够覆盖应该受到用户保护的另一段数据(例如安全设置)

You didn't show us the output of the program with the addresses of a[i]. 您没有向我们展示程序的输出,其地址为[i]。 I suspect that the compiler is doing something like aligning the data on the stack to 16. It could be much further to the return address than you expect. 我怀疑编译器正在做一些事情,比如将堆栈上的数据与16对齐。它可能比返回地址远远超出预期。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM