¿Qué es el shellcode?

Como se indica en Shellcode – Wikipedia, shellcode es un pequeño fragmento de código generalmente utilizado como carga útil en la explotación de una vulnerabilidad de software. Se llama “shellcode” porque normalmente inicia un shell de comandos.

Después de que se escribe algún programa, digamos Ensamblado, los bytes hexadecimales de ese programa se insertan en otro programa escrito, digamos C. Al ejecutar el programa C, también se ejecuta el “shellcode” subyacente.

En este ejemplo, solo estamos imprimiendo “Hello World” en la pantalla usando el código de ensamblaje x86–64 a continuación.

// código derivado de http://www.securitytube-training.com/online-courses/x8664-assembly-and-shellcoding-on-linux/

sección .text
inicio global
_comienzo:
jmp real_start
hello_world: db `Hola Mundo \ n`

real_start:
; escribir
xor rax, rax; por el bien de shellcode
mov al, 1; syscall # escribir

mov rdi, rax; std out = 1
lea rsi, [rel hello_world]; buffer con direccionamiento relativo
xor rdx, rdx; bits claros
mov dl, 14; # bytes
syscall

_salida:
xor rax, rax
añadir eax, 60
xor rdi, rdi
syscall

Si hacemos un volcado de objeto (es decir, objdump) del archivo de objeto de código ensamblado ensamblado tenemos lo siguiente:

$ objdump -d -M intel 028_helloworld_shellcode_rip_rel

028_helloworld_shellcode_rip_rel: formato de archivo elf64-x86-64

Desmontaje de la sección .text:

0000000000400080 :
400080: eb 0c jmp 40008e

0000000000400082 :
400082: 48 65 6c 6c 6f 20 57 6f 72 6c 64 0a Hola Mundo.

000000000040008e :
40008e: 48 31 c0 xor rax, rax
400091: b0 01 mov al, 0x1
400093: 48 89 c7 mov rdi, rax
400096: 48 8d 35 e5 ff ff ff lea rsi, [rip + 0xffffffffffffffe5] # 400082
40009d: 48 31 d2 xor rdx, rdx
4000a0: b2 0d mov dl, 0xd
4000a2: 0f 05 syscall

00000000004000a4 :
4000a4: 48 31 c0 xor rax, rax
4000a7: 83 c0 3c agregar eax, 0x3c
4000aa: 48 31 ff xor rdi, rdi
4000ad: 0f 05 syscall

Extraemos los códigos de operación del conjunto del archivo de objeto anterior y luego pre-pendulamos cada byte con “\ x” para generar la siguiente “cadena” de “shellcode”.

\ xeb \ x0c \ x48 \ x65 \ x6c \ x6c \ x6f \ x20 \ x57 \ x6f \ x72 \ x6c \ x64 \ x0a \ x48 \ x31 \ xc0 \ xb0 \ x01 \ x48 \ x89 \ xc7 \ x48 \ x8d \ x35 \ \ xe5 \ xff \ xff \ xff \ x48 \ x31 \ xd2 \ xb2 \ x0d \ x0f \ x05 \ x48 \ x31 \ xc0 \ x83 \ xc0 \ x3c \ x48 \ x31 \ xff \ x0f \ x05

Insertamos el “shellcode” en algún programa en C como el siguiente.

// http://shell-storm.org/shellcode/files/shellcode-806.php

#include
#include

código de char sin firmar [] = \
“\ xeb \ x0c \ x48 \ x65 \ x6c \ x6c \ x6f \ x20 \ x57 \ x6f \ x72 \ x6c \ x64 \ x0a \ x48 \ x31 \ xc0 \ xb0 \ x01 \ x48 \ x89 \ xc7 \ x48 \ x8d \ x35 \ xe5 \ xff \ xff \ xff \ x48 \ x31 \ xd2 \ xb2 \ x0d \ x0f \ x05 \ x48 \ x31 \ xc0 \ x83 \ xc0 \ x3c \ x48 \ x31 \ xff \ x0f \ x05 “;

int main ()
{
printf (“Longitud del código de shell:% d \ n”, (int) strlen (código));
int (* ret) () = (int (*) ()) código;
jubilado();
}

Compile el programa C y luego ejecútelo en consecuencia.

$ gcc -fno-stack-protector -z execstack shellcode.c -o shellcode

./shellcode

Longitud del Shellcode: 47

Hola Mundo

  • Asume x86–64 NASM Assembly en el sistema operativo basado en Linux.

El código de Shell originalmente se refiere a Linux / unix. El sistema operativo se basa en la línea de comandos y la interfaz gráfica de usuario o GUI es un shell sobre el código base.

Ahora se usa para hacer referencia a cualquier codificación de línea de comando.