|
Page 2 of 2
Now
let's say that the argv[1] should be in normal use send. So you
just type in your prompt:
$
program_name send
You'll
get an output like:
0x8049700
0x8049710
Starting To Print memory address:
0x8049700: s (0x616c62)
0x8049701: e (0x616c)
0x8049702: n (0x61) <---- each of this lines represent a memory
address
0x8049703: d (0x0)
0x8049704: (0x0)
0x8049705: (0x0)
0x8049706: (0x0)
0x8049707: (0x0)
0x8049708: (0x0)
0x8049709: (0x19000000)
0x804970a: (0x190000)
0x804970b: (0x1900)
0x804970c: (0x19)
0x804970d: (0x63000000)
0x804970e: (0x6f630000)
0x804970f: (0x6d6f6300)
0x8049710: c (0x6d6d6f63)
0x8049711: o (0x616d6d6f)
0x8049712: m (0x6e616d6d)
0x8049713: m (0x646e616d)
0x8049714: a (0x646e61)
0x8049715: n (0x646e)
0x8049716: d (0x64)
0x8049717: (0x0)
0x8049718: (0x0)
0x8049719: (0x0)
0x804971a: (0x0)
0x804971b: (0x0)
0x804971c: (0x0)
0x804971d: (0x0)
$
Nice
isn't it? You can now see that there exist 12 memory address empty
between somevar and important. So let's say that you run the
program with a command line like:
$
program_name send------------newcommand
You'll
get an output like:
0x8049700
0x8049710
Starting To Print memory address:
0x8049700: s (0x646e6573)
0x8049701: e (0x2d646e65)
0x8049702: n (0x2d2d646e)
0x8049703: d (0x2d2d2d64)
0x8049704: - (0x2d2d2d2d)
0x8049705: - (0x2d2d2d2d)
0x8049706: - (0x2d2d2d2d)
0x8049707: - (0x2d2d2d2d)
0x8049708: - (0x2d2d2d2d)
0x8049709: - (0x2d2d2d2d)
0x804970a: - (0x2d2d2d2d)
0x804970b: - (0x2d2d2d2d)
0x804970c: - (0x2d2d2d2d)
0x804970d: - (0x6e2d2d2d)
0x804970e: - (0x656e2d2d)
0x804970f: - (0x77656e2d)
0x8049710: n (0x6377656e) <--- memory address where important
variable starts
0x8049711: e (0x6f637765)
0x8049712: w (0x6d6f6377)
0x8049713: c (0x6d6d6f63)
0x8049714: o (0x616d6d6f)
0x8049715: m (0x6e616d6d)
0x8049716: m (0x646e616d)
0x8049717: a (0x646e61)
0x8049718: n (0x646e)
0x8049719: d (0x64)
0x804971a: (0x0)
0x804971b: (0x0)
0x804971c: (0x0)
0x804971d: (0x0)
Hey
cool, newcommand got over command. Now it does something you want,
instead of something he was supposed to do. NOTE: Remember
sometimes those spaces between somevar and important can have other
variables instead of being empty, so check their values and send
them to the same address, or the program can crash before
getting
to the variable that you modified. Now let's think a little. Why
does this happen? As you can see in the source code somevar is
declared before important, this will make, most of the times, that
somevar will be first in memory. Now, let's check how each one is
got. Somevar gets it's value from argv[1], and important gets it
from strcpy() function, but the real problem is that important
value is assign first so when you assign value to somevar that is
before it important can be overwritten.
This
program could be patched against this buffer overflow switching
those two lines, becoming :
strcpy(somevar, argv[1]);
strcpy(important, "command");
If this
was the way that the program was done even if you give an argument
that would get into the memory address of important, it will be
overwritten by the true command, since after getting somevar, is
assign the value command to important.
This
kind of buffer overflow, is a heap buffer overflow. Like you
probably has seen they are really easy to do in theory but, in the
real world, it's not really easy to do them, after all the example
I gave was a really dumb program right? It's a real pain in the
ass to find those important variables, and also to overflow that
variable you need to be able to write to one that is in a lower
memory address, most of times all this conditions.
|