Wednesday, October 10, 2012

Format String Attacks to maniplulate information anywhere in memory

By manipulating programs that misuse the printf and related command, an attacker can Read arbitrary information from memory. And, maniplulate information anywhere in memory. So, an attacker can have complete control over victim process
The right way: printf("%s",buffer);
The wrong way: printf(buffer);
If program is implemented in "wrong" way, an attacker can place input into the string that will be interpreted as a string format
So, an attacker can print memory, stack. In easy way to understand that

main()
{
    char user_input[100];
    char buffer[100];
    int x = 1;
    ....
    /* get user input*/
    ...
    snprintf(buffer, sizeof buffer, user_input); <==== Oh, forgot the format string, the user input will be interpreted as the format  
}

Attacker enter "%x %x %x" into user_input, becomes: snprintf(buffer, sizeof buffer, "%x %x %x");. And buffer now contains the next three hexadecimal value on the strack, so, we can read the stack
But, we can rewriting memory location. Attacker enters "\xde\xad\xbe\xef%d%n" into user_input, becomes: snprintf(buffer, sizeof buffer, "\xde\xad\xbe\xef%d%n");

If the snprintf function is called, the stack like that:

Bottom of Memory
-------------------------------------------
| Return Pointer        |
-------------------------------------------
| Pointer to Buffer        |
-------------------------------------------
| sizeof buffer        |
-------------------------------------------
| Pointer to user_input     |
-------------------------------------------
| int x ( value 1)        |
-------------------------------------------
| buffer ( 100 char)        |
-------------------------------------------
...
-------------------------------------------
| Value to change          |
-------------------------------------------

Character \xde\xad\xbe\xef are written to the string. It is address of value to change
Bottom of Memory
-------------------------------------------
| Return Pointer        |
-------------------------------------------
| Pointer to Buffer        |
-------------------------------------------
| sizeof buffer        |
-------------------------------------------
| Pointer to user_input     |  <= \xde\xad\xbe\xef%d%n
-------------------------------------------
| int x ( value 1)        |
-------------------------------------------
| buffer ( 100 char)        |
-------------------------------------------
...
-------------------------------------------
| Value to change          |
-------------------------------------------

It will be copied to buffer, so first 4 bytes of buffer become: deadbeef, it is address of value to change
Because of the "%d". the value of x ( that is number 1). is written into buffer
-------------------------------------------
| Return Pointer        |
-------------------------------------------
| Pointer to Buffer        |
-------------------------------------------
| sizeof buffer        |
-------------------------------------------
| Pointer to user_input     |  <= \xde\xad\xbe\xef%d%n
-------------------------------------------
| int x ( value 1)        |
-------------------------------------------
| buffer ( 100 char) = deadbeff|
| value of x (1)        |
-------------------------------------------
...
-------------------------------------------
| Value to change          | <= 0xdeadbeff| here
-------------------------------------------

snprintf then see "%n". %n make it write the number of character printed, in this case is 5 ( 4 of address value, 1 of x value). But where will it write ? In the memory space pointed to by its next argument.
It pointed to int x ( after read %d and write to buffer). So, next argument is next value on the stack, first 4 bytes of buffer. So, it write to address deadbeef, it is value want to change
-------------------------------------------
| Return Pointer        |
-------------------------------------------
| Pointer to Buffer        |
-------------------------------------------
| sizeof buffer        |
-------------------------------------------
| Pointer to user_input     |  <= \xde\xad\xbe\xef%d%n
-------------------------------------------
| int x ( value 1)        |
-------------------------------------------
| buffer ( 100 char) = deadbeff|
| value of x (1)        |
-------------------------------------------
...
-------------------------------------------
| value 5             | <= 0xdeadbeff| here
-------------------------------------------

So, we just wrote the number 5 into memory location 0xdeadbeef

------------------------------------------------------------
Thanks for reading
--------------------------------------------------------------------------
Security Research
All my Lab:
Linux Lab -- window and Cisco Lab
to be continued - I will update more. 

No comments:

Install Xposed Inspector and Frida on Genymotion

Today i had some work with android. So i need trace application. I found 2 nice tool can help me: Xposed Inspector and Frida. To setup ther...