I have a small C program to be exploited. And I also understood the logic behind the attack to be performed. However, as much as I try, it is just not working for me.
#include <stdio.h>
#include <stdlib.h>
#define SECRET1 0x44
#define SECRET2 0x55
int main(int argc, char *argv[]) {
char user_input[100];
int *secret;
int int_input;
int a, b, c, d; /* other variables, not used here.*/
/* The secret value is stored on the heap */
secret = (int *) malloc(2*sizeof(int));
/* getting the secret */
secret[0] = SECRET1; secret[1] = SECRET2;
printf("Please enter a decimal integer\n");
scanf("%d", &int_input); /* getting an input from user */
printf("Please enter a string\n");
scanf("%s", user_input); /* getting a string from user */
printf(user_input);
printf("\n");
/* Verify whether your attack is successful */
printf("The original secrets: 0x%x -- 0x%x\n", SECRET1, SECRET2);
printf("The new secrets: 0x%x -- 0x%x\n", secret[0], secret[1]);
return 0;
}
I just need to print the address and value of secret[0] using the format string "printf(user_input);"
I have tried giving something like "\x6e\xaf\xff\xff%x%x%x%x%s". but it is not working. Any suggestions will be appreciated. Thanks a lot.
This looks like an exercise for a class, so I'll provide some pointers, but no the actual solution.
You are attempting to exploit this program, by providing untrusted input. There are two fairly obvious bugs here; one is the
scanf()
using%s
, as you can overflow the buffer and overwrite the stack. The other is a format-string vulnerability. Overwriting the stack probably wouldn't let you do anything interesting until the function returned. Based on the "verify whether your attack is successful" section, you probably want to exploit the vulnerability before then, so I'm guessing it's supposed to be a format string vulnerability.Based on the verification section, you are expected to overwrite the memory pointed to by
secret
. The only way of causingprintf
to write to a controlled location in memory is to use the%n
format specifier, which writes the given pointer.Now the trick is to figure out how to walk up the stack until we find the appropriate pointer. Conveniently, there's a user-controlled integer right before the pointer on the stack. So, we enter a number with an easy to spot pattern (maybe 65535, which is
ffff
in hex), and use a format string with a lot of%x
s to see what's on the stack. Once we find that, the next thing on the stack should be the pointer.Hmm. I just tried this, and it turns out that it's not quite so simple. The exact layout of the stack frame isn't actually related to the order of declarations; and it differs between different systems for me. Instead, I had to use a lot of
%lx
s, along with a well-known string at the beginning, and add a line to print out the actual pointer, so I would know when I found it. Then replace the corresponding%lx
with the%n
to write through that pointer. It may be easiest to just try 20 or so%lx
s, and substitute each one by one with%n
, until you have managed to overwrite that pointer.Anyhow, hope that's enough to get you started. Let me know if you have any questions.