lunes, 8 de septiembre de 2008

Acertijo para sysadmins

Hoy a la tarde, Isart me propuso un acertijo interesante, que suena más a pregunta de examen que otra cosa, pero me dio un buen rato de entretenimiento super geek.

Seguramente más de uno lo conoce, pero esta bueno para investigar un poco sobre el sistema, aca va el enunciado:

Alguien ejecutó el comando:
chmod -x /bin/chmod

¿Cómo lo arreglás sin reinstalar ni recompilar ningún programa?


Cada uno encontró una solución diferente, y después encontré una tercera solución más académica. Conclusión, somos un poco chapuceros, pero creativos :P

Que se diviertan, y dejen que el resto se divierta un rato antes de postear alguna solución ;)

6 comentarios:

Marcelo Fernández dijo...

DISCLAIMER: YA PASO UNA HORA!!! Así que mando mi solución. :-)

Chmod es sólo una syscall Posix[1] más del montón que tienen sus comandos en /bin. Aunque también se puede utilizar la función de la glibc[2].

Yo preferí resolverlo en Python :-)

marcelo@saturno:~$ sudo chmod -x /bin/chmod
marcelo@saturno:~$ ls -l /bin/chmod
-rw-r--r-- 1 root root 52176 2008-04-04 03:44 /bin/chmod
marcelo@saturno:~$ sudo python -c "import os;os.chmod('/bin/chmod',0755)"
marcelo@saturno:~$ ls -l /bin/chmod
-rwxr-xr-x 1 root root 52176 2008-04-04 03:44 /bin/chmod
marcelo@saturno:~$

En realidad, al ser una syscall, se puede resolver de cualquier manera que se pueda llamar a una syscall (o a una función C, por ejemplo).

[1] http://www.gnu.org/software/libtool/manual/libc/System-Calls.html
marcelo@saturno:/usr/include$ grep chmod -n2 /usr/include/bits/syscall.h
18-#define SYS_capset __NR_capset
19-#define SYS_chdir __NR_chdir
20:#define SYS_chmod __NR_chmod
21-#define SYS_chown __NR_chown
22-#define SYS_chroot __NR_chroot
--
44-#define SYS_fallocate __NR_fallocate
45-#define SYS_fchdir __NR_fchdir
46:#define SYS_fchmod __NR_fchmod
47:#define SYS_fchmodat __NR_fchmodat
48-#define SYS_fchown __NR_fchown
49-#define SYS_fchownat __NR_fchownat

[2] http://www.delorie.com/gnu/docs/glibc/libc_290.html

Gabriel dijo...

Jaja... que bien que estuviste... con lo de compilar me refería a hacer un programa, pero python no se compila, asi que muy buena tu solución.

Saludos,

Adrián dijo...

Tres soluciones:

1. Comparen Perl con la solución Python:

$ perl -e 'chmod 0755, "/bin/chmod"'

2. Ruby es un mejor Perl y también se lee más fácil que Python:

$ ruby -e 'File.chmod 0755, "/bin/chmod"'

3. Usando install:

$ install -m 0755 /bin/chmod xxx && mv xxx /bin/chmod



Ahora, si son verdaderos hackers...

4. Editando a mano el raw device con dd(1).

P.D. no se ofenda nadie con lo del Python, eh. ;-)

Adrián dijo...

Otra manera mucho más chambona pero sin usar nada de scripting (nadie es perfecto):

$ cp -p cualquier_binario_0755 xxx
$ cat /bin/chmod > xxx
$ mv xxx /bin/chmod

Hablando en serio el principio es interesante. Los permisos se ponen con el O_CREAT de open(2) pero no con el O_TRUNC si el archivo ya existe.

Gabriel dijo...

Adrian, descubriste mi forma de hacer las cosas!

No, no es con perl ni ruby, sino haciendo chapuzas :)

Aguante el cp+cat

Anónimo dijo...

En Linux lo más sencillo es usar el dynamic loader directamente:

$ /lib/ld-linux.so.2 /bin/chmod
/bin/chmod: missing operand
Try `/tmp/chmod --help' for more information.

Pueden no tener perl o ruby o python, pero el dynamic loader lo van a tener *seguro* :)