Solucion 2.

Anuncio
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
}
}
Descargar