Examen de Fundamentos de Sistemas Operativos 2011 Problema: Log de programa Implementa un programa en C para Plan 9 llamado proglog que recibe como argumentos un nombre de programa y sus argumentos. El programa indicado se debe ejecutar con entrada estándar redirigida a /dev/null y su salida estándar redirigida a un fichero llamado data.out en el directorio de trabajo. En caso de que el programa especificado tenga problemas en su ejecución, el fichero de salida se tiene que renombrar como data.err. Un ejemplo de ejecución podría ser: ; proglog ls -l /blah ; ls data* data.err ; Entrega: Copie un fichero llamado proglog-login.c, donde login es tu nombre de usuario, en el directorio /usr/elf/examen. ATENCIÓN: Sólo se puede efectuar la entrega una vez. Problema: ataque de diccionario Escriba un programa de Rc llamado ripper.rc encargado de realizar un ataque de diccionario a un conjunto de contraseñas. El script recibirá como argumentos el nombre de dos archivos. El primero contendrá una lista de contraseñas de usuario resumidas con el algoritmo SHA1. El archivo contiene líneas con: login:hash Puede encontrar un fichero de ejemplo en /lib/accounts. El segundo archivo contendrá una lista de palabras que, una por línea, que deben usarse para para realizar el ataque de diccionario. Pare ello puede usar el fichero /lib/ripper. Para obtener el resumen SHA1 se debe usar el comando sha1sum(1). Si ejecutamos sha1sum sin argumentos, leerá los datos por su entrada estándar hasta el momento en que reciba EOF, y después escribirá el resumen SHA1 por salida estándar. Esto significa que hay que ejecutar sha1sum para cada resumen que se quiera calcular. El script que se debe realizar mostrará por salida estándar los login y las contraseñas en claro que haya conseguido romper, siguiendo un formato similar al archivo de password: ; ripper.rc /lib/accounts /lib/ripper johnny:ramone joey:heyholetsgo Las contraseñas no deben incluir el carácter \n (salto de línea) al final de la línea. Dicho carácter debe ser eliminado. Como ejemplo puede considerar las palabras ’ejemplo’ y ’ejemplo\n’, cuyos respectivos SHA1 son: a6c05bd5d579650bdb5f2088a3b8ea44452929a7 83389eabdee6084c080e9bb398c362bfd5d623bf Entrega: Copie un fichero llamado ripper-login.rc, donde login es tu nombre de usuario, en el directorio /usr/elf/examen. ATENCIÓN: Sólo se puede efectuar la entrega una vez. -2- Solución ________ _proglog.c #include <u.h> #include <libc.h> void usage(void) { fprint(2, "proglog cmd args ...\n"); sysfatal("usage"); } int proglog(int fdout, int argc, char *argv[]) { int pid, fdnull, res, i; char *name; for(i = 0; i < argc - 1; i++) argv[i] = argv[i + 1]; argv[argc - 1] = nil; if (strchr(argv[0], ’/’) == nil) name = smprint("/bin/%s", argv[0]); else name = argv[0]; pid = fork(); if (pid != 0) return pid; fdnull = open("/dev/null", OREAD); if(fdnull < 0) sysfatal("opening null %r"); res = dup(fdnull, 0); if (res < 0) { sysfatal("dup null %r"); } close(fdnull); res = dup(fdout, 1); if (res < 0) { sysfatal("dup fdout %r"); } close(fdout); exec(name, argv); sysfatal("exec %r"); return -1; /* para el compilador */ } -3- int fdrename(char *newname, int fd) { int res; Dir d; if (access(newname, AEXIST) == 0){ res = remove(newname); if (res < 0) return res; } nulldir(&d); d.name = newname; res = dirfwstat(fd, &d); return res; } void main(int argc, char *argv[]) { int pid, fd, res; Waitmsg *wm; if(argc <= 1) usage(); fd = create("data.out", OWRITE|OTRUNC, 0600); if (fd < 0) sysfatal("creating data.out: %r"); pid = proglog(fd, argc, argv); if (pid < 0) sysfatal("having child: %r"); for (;;){ wm = wait(); if (wm == nil) sysfatal("no children"); if (wm->pid == pid) break; free(wm); } if(wm->msg[0] != ’\0’){ fprint(2, "the child had an error\n"); res = fdrename("data.err", fd); if (res < 0) sysfatal("renaming data.out %r"); } free(wm); close(fd); exits(nil); } ________ _ripper.rc #!/bin/rc -4- if (! ~ $#* 2){ echo ’usage: ripper accounts dictionary’ >[1=2] exit ’usage’ } acc = $1 dict = $2 if (! test -f $acc){ echo $acc does not exist or is not a file >[1=2] exit ’bad file’ } if (! test -f $dict){ echo $dict does not exist or is not a file >[1=2] exit ’bad file’ } for (p in ‘{cat dict}){ s = ‘{echo -n $p|sha1sum} logins = ‘{grep ’:’^$s^’$’ $acc | sed ’s/:.*//g’} for(l in $logins){ echo $l^’:’^$p } }