Formatting String Vulnerability Experiment

Source: Internet
Author: User

Formatting String Vulnerability Experiment

1. Experiment description

The formatting string vulnerability is caused by Code such as printf (user_input). user_input is the data input by the user, and such programs with the Set-UID root permission are running, the printf statement may become very dangerous because it may lead to the following results:

1. Program crash

2. read data from any memory

3. modify data in any memory.

The last result is very dangerous because it allows users to modify the internal variable values of the set-UID root program, thus changing the behavior of these programs.

This experiment will provide a program with formatting vulnerabilities, and we will develop a plan to explore these vulnerabilities.

Ii. Experiment Preparation

2.1 What Is A formatted string?

Printf ("The magic number is: % d", 1911 );

Try to run The above statement and you will find that The format character % d in The string "The magic number is: % d" is replaced by The parameter (1911), so The output is "The magic number is: 1911 ". This is basically the case for formatting strings.

In addition to % d, which represents the decimal number, there are many other format characters. Let's take a look at it ~

(Use of * % n will be described in section 1.5)

2.2 stack and formatted string

The Formatting Function is controlled by the formatting string. The printf function obtains parameters from the stack.

Printf ("a has value % d, B has value % d, c is at address: % 08x \ n", a, B, & c );


2.3 what will happen if the number of parameters does not match?

What happens if there is only one mismatch?
Printf ("a has value % d, B has value % d, c is at address: % 08x \ n", a, B );

1. In the preceding example, the format string requires three parameters, but the program only provides two parameters.

2. Can this program be compiled?

(1) printf () is a variable parameter length function. Therefore, the number of parameters alone cannot be seen.

(2) The Compiler needs to understand the running mechanism of printf () to identify non-matching. However, the compiler usually does not perform such analysis.

(3) Sometimes, the format string is not a constant string, which is generated during the program running (such as user input). Therefore, the compiler cannot find any mismatch.

3. Can the printf () function detect non-matching?

(1) printf () gets parameters from the stack. If the format string requires three parameters, it will take three parameters from the stack, unless the stack is marked with a boundary, printf () I don't know if I will use all the provided parameters.

(2) Since there is no such boundary mark. Printf () continuously captures data from the stack. In an example of unmatched parameter quantity, it captures data not called by this function.

4. What happens if someone specially prepares data for printf to capture?

2.4 Access Memory anywhere

1. We need to get the memory address of a piece of data, but we cannot modify the code for us to use only the format string.

2. If the memory address is not specified when printf (% s) is called, the target address can be obtained at any position on the stack through the printf function. The printf function maintains an initial Stack pointer, so the position of all parameters in the stack can be obtained.

3. observe that the format string is on the stack. if we can encode the target address into a format string, the target address will also exist on the stack. In the following example, the format string will be saved in the buffer zone on the stack.
 

int main(int argc, char *argv[]){    char user_input[100];    ... ... /* other variable definitions and statements */    scanf("%s", user_input); /* getting a string from user */    printf(user_input); /* Vulnerable place */    return 0;}


4. If we let the printf function get the target memory address in the format string (this address also exists on the stack), we can access this address.
Printf ("\ x10 \ x01 \ x48 \ x08 % x % s ");

5, \ x10 \ x01 \ x48 \ x08 are four bytes of the target address. In C, \ x10 tells the compiler to place a hexadecimal number 0 × 10 at the current position (1 byte ). If the prefix \ x10 is removed, it is equivalent to two ascii characters 1 and 0, which is not the expected result.

6, % x causes the stack pointer to move to the direction of the format string (see section 1.2)

7. Explains the attack mode. If the user input contains the following format strings


8. We use four % x to move the stack pointer of the printf function to the position of the string in the storage format. Once the destination position is reached, we use % s for printing, it prints the content at the address 0 × 10014808, because it is processed as a string, so it will be printed until the end.

9. The stack space between the user_input array and the address passed to the printf function parameter is not prepared for the printf function. However, because the program itself has a format string vulnerability, printf matches % x as an input parameter.

10. The biggest challenge is to find out the distance from the printf function Stack pointer (the function takes the parameter address) to the user_input array, this distance determines how many % x you need to input before % s.

2.5 write a number in the memory

% N: the number of characters entered before the symbol will be stored in the corresponding parameter
Int I;
Printf ("12345% n", & I );

1. the number 5 (the number of characters before % n) will be written to I.

2. When using the same method to access any address memory, we can write a number to the specified memory. Replace % s in the previous section (1.4) with % n to overwrite 0x10014808.

3. Using this method, attackers can do the following:

Override program identity to control access permissions

Return address of stack or function rewriting.

4. However, the written value is determined by the number of characters before % n. Is there a way to write any value?

Use the oldest counting method. To write 1000 characters, enter 1000 characters.

To prevent long format strings, we can use a Format Indicator with the specified width. (For example, (% 0 digit x) the expected number of 0 characters is left filled)

Iii. experiment content

You need to input a piece of data, which is saved in the user_input array. The program uses the printf function to print the data content and runs the program as root. What's even more gratifying is that this program has a Formatting Vulnerability. Let's take a look at the damage caused by these vulnerabilities.

Program description:

There are two secret values in the program memory. We want to know these two values, but we find that they cannot be obtained by reading binary code (for the sake of simplicity, hard-coding these secret values are 0x44 and 0x55 ). Although we do not know their values, it is not very difficult to obtain their memory addresses because these memory addresses remain unchanged for most systems each time they run the program. The experiment assumes that we already know these memory addresses. In order to achieve this goal, the program specially typed these addresses for us.

With these prerequisites, we need to achieve the following goals:

Find the secret [1] value

Modify the value of secret [1]

Change secret [1] to Expected Value

Note: Because the experiment environment is a 64-bit system, you need to use % 016llx to read the entire word. However, for convenience, the program was modified and the experiment can be completed using % 08x.

With the preparation knowledge, please try it first and have a good time :)

The procedure is as follows:
/* vul_prog.c */#include#include#define SECRET1 0x44#define SECRET2 0x55int main(int argc, char *argv[]){  char user_input[100];  int *secret;  long 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;}

(Ps: during compilation, you can add the following parameters to disable stack protection .)
Gcc-z execstack-fno-stack-protector-o vul_prog vul_prog.c

TIPS: you will find that secret [0] and secret [1] exist in the malloc stack. We also know that the secret value exists on the stack, if you want to overwrite the secret [0] value, OK, its address is on the stack. You can exploit the format string vulnerability to achieve this goal. However, although secret [1] is next to its brother 0, you still cannot get its address from the stack, which poses a challenge to you, because there is no such address, how do you use the format string for read/write. But is there no such thing?

3.1 find the secret [1] value

1. First locate the int_input position, so as to confirm the position of % s in the format string.


2. Enter the secret [1] address. Remember to perform hexadecimal conversion and add % s to the format string.


Success! The U ascii code is 55.

3.2 modify the value of secret [1]

1. Only modification is required. What is not required? Simple! If you do not understand the usage of % n, you can review it later.



Success 2!

3.3 modify secret [1] to the expected value

1. What should I do if I want to change it to the expected value? Isn't it exhausting to enter 1000 ?! Can be filled?



By the way, 0x3e8 = 1000. Success 3!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.