sg********@gmail.com wrote:
Can anyone explain how this shell spawning code works......
I am not able to figure out exactly..... I got this from Aleph1's
Smashing the stack file. :)
As you will no doubt be told by many, this is pretty much off-topic
here. Follow-ups set.
Here it is
================================================== ================
testsc.c
------------------------------------------------------------------------------
char shellcode[] =
"\xeb\x2a\x5e\x89\x76\x08\xc6\x46\x07\x00\xc7\x46\ x0c\x00\x00\x00"
"\x00\xb8\x0b\x00\x00\x00\x89\xf3\x8d\x4e\x08\x8d\ x56\x0c\xcd\x80"
"\xb8\x01\x00\x00\x00\xbb\x00\x00\x00\x00\xcd\x80\ xe8\xd1\xff\xff"
"\xff\x2f\x62\x69\x6e\x2f\x73\x68\x00\x89\xec\x5d\ xc3";
This creates an array of bytes that I presume is intended to represent
executable code of some nature. This is, no doubt, highly platform and
architecture dependant. Some of the bytes are no-ops to position the
rest of the bytes just so. Others probably represent unconditional
jumps to some other place.
void main() {
If you are trying to black-hat hack, I guess no one cares if you aren't
ISO standard. Check the prototype for main() to be sure.
int *ret;
Declares an int. The address of this int will be in process memory.
Smart hackers have a pretty good idea where this memory is in relation
to other process memory, like the data and text segments (on
architectures where this nomenclature makes sense).
ret = (int *)&ret + 2;
This assumes an int is 2 bytes, I guess. This makes the int pointer ret
point to 2 bytes passed what has been allocated for ret in the first
place. Typically, auto variables like this are maintained on the stack,
and adding to this location often yields a smaller address. At any rate
the hope is ret has been incremented past what the runtime code has
allocated for a single int and into the part of the process memory that
holds executable code.
(*ret) = (int)shellcode;
This stores the bytes (encoded as hex bytes, above) into the new
location which we hope is beyond the end of the stack. A part of the
data runs into process memory that can run code. Often the intent is to
simply have it invoke the equivalent of the exec() library call. This
allows one to exec() any sort of thing they would like over the current
process, like a shell.
}
I'm no hacker, so the preceding was my poor understanding of classic
stack smashing. Hence my violent hand-waving.
I'll float the idea that this is *somewhat* on-topic given that on most
platforms C is the language of choice because, well, you are allowed to
do stuff like walk off the end of a pointer (this is not a criticism,
but merely an observation). Plus, I find it sort of interesting,
especially in light of how some platforms have countered this naive (but
so useful) way of leveraging process memory.
As you can see, much of this depends on highly non-portable assumptions
and specific platform, architecture and compiler knowledge. This is why
"rootkits" tend to be so customized for specific targets.