Buffer overflow attack

I am trying to perform a very simple buffer overflow attack. I am pretty new to this. So if this question is stupid, 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 ("\na[%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 function addresses, I have the following:

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

Now I want to go to the function 'confused ()' from victim_func (), overflowing the buffer there, and rewriting the return address to confused (). And I want to return from confused () to printf () to main and exit normally. 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 this printf statement, it jumps back to victim_func () and prints "Enter n:"

What am I doing wrong? Any help would be greatly appreciated!

PS: I am not sure whether the question was posed correctly. Please let me know if you need more information.

+18
c objdump buffer-overflow
Sep 08 2018-11-11T00:
source share
4 answers

A buffer overflow attack is much more complicated than this. First of all, you need to understand assembler in order to accomplish this. After you have disassembled the program and the function that you want to target, you need to determine the stack structure when this function is executed. Here the sample buffer overflows it with visual studio, but the principle is the same.

 #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 the disassembly, we know that the function a in the function is allocated until the moment when the function has retained the stack frame pointer. The value after this is the return address where function1 should go if it is completed.

 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 that if we rewrite [7] with a different address, the function will return not to the main address, but to any address that we wrote in [7].

Hope this helps.

+8
Sep 08 2018-11-11T00:
source share

First of all, it seems to me that you should not enter number 5 in your input example. Your array is declared as [4], therefore elements with an index of 0-3 - therefore your attack input seems to me wrong.

It also seems to me that your program suggests a few things about architecture:

  • sizof (int) == sizeof (memory address)
  • The direction of growth and the implementation mechanism of the environment stack

If one of these assumptions is wrong, it will never work.

It looks like a very difficult job.

There are simpler examples of buffer overflows than changing a code control flow. For example, you can overwrite another piece of data that must be protected from the user (for example, a security setting).

+1
Sep 08 2018-11-11T00:
source share

Now I want to go to the function 'confused ()' from victim_func (), overflowing the buffer there and rewriting the return address to confused () ...

On modern Linux platforms, you will also need to disable two security features for testing. First in NX-stacks, and secondly, Stack Protectors.

To disable NX-Stacks, use -Wl,z,execstack (unlike -Wl,z,noexecstack ). To disable stack protection, use -fno-stack-protector (unlike -fstack-protector or -fstack-protector-all ).

There is a third protection that you may need to disable. This protection is FORTIFY_SOURCE. FORTIFY_SOURCE uses "safer" variants of high-risk functions such as memcpy and strcpy . The compiler uses safer options when it can determine the size of the destination buffer. If the copy exceeds the size of the destination buffer, the program calls abort() . To disable FORTIFY_SOURCE, compile the program with -U_FORTIFY_SOURCE or -D_FORTIFY_SOURCE=0 .

Security features are enabled by default because there have been so many problems in the past. In general, this is good because it stops many problems (for example, the one you are experimenting with).

+1
Sep 12 '14 at 13:01
source share

You did not show us the output of the program with addresses [i]. I suspect that the compiler is doing something like aligning the data on the stack to 16. This could be a much larger return address than you expect.

0
Sep 08 2018-11-11T00:
source share



All Articles