0

if we run the following code using the input "hi", the output will simply be "hi"

main(int argc, char **argv)
{
          char *secret = "This is a secret 1\n";
          char *secret2 = "This is secret 2\n";

          printf(argv[1]);
}

however, if we run the program with the input "%s" the output will be "This is a secret 1"

from what I understand, the reason for this is that when printf is fed with the %s format string, it does not check to see if a string data has been pushed on the stack therefore if there is no string supplied, it will fetch the next data stored on the stack which in this case is our secret string. So for each %s it will fetch the next data on its stack frame and display it in string format.

My question is, keeping in mind that (main) and (printf) each have their own stack frame, how can %s cause printf to display data that does not belong in its stack frame ??(both secret string are in main)

Abbas Javan Jafari
  • 1,916
  • 13
  • 31

1 Answers1

1

however, if we run the program with the input "%s" the output will be "This is a secret 1

No, this is not guaranteed. It may print out the string contained in the secret variable but that is merely a coincidence. You are right that main and printf each has their own stack frames. printf will print out whatever memory address the stack happens to be pointing at at the moment. The nice thing about format string vulnerabilities like this though is that you can essentially read arbitrary amounts of data just by passing in various format strings.

I find this paper to be a nice introduction to the vulnerability.

  • yes I understand this but how can continuous use of %s allow us to read arbitrary data from the stack when that data does not belong to the printf stack frame? I mean (assuming the entire stack has valid addresses) can this allow us to read the entire program stack? how can we pass between stack frames? Thanks for the feedback by the way :) – Abbas Javan Jafari Apr 27 '14 at 09:44
  • @AbbasJavan Think about what a stack frame actually is. In x86-speak, it is the part of the stack between the `esp` and `ebp`. You *can* still read from outside the stack frame. –  Apr 27 '14 at 09:49
  • Tnx for all the help :) – Abbas Javan Jafari Apr 28 '14 at 13:36