Saltar al contenido
sudoquest@root
Blue Team

Lo que se quedó dentro

Revisar un servidor tras una noche rara: cuentas, sudo, cron, claves y setuid de más, sin quitar lo que parece raro y es de la casa.

35 min de lectura

Son las siete de la mañana en la Academia Faro. Esta vez no estás en el SOC: estás en su cuarto de servidores, junto al aula, delante de srv-aulas. De madrugada, el vigilante de integridad del SOC (un programa que compara cada noche los archivos sensibles con los del día anterior) avisó: alguien cambió cosas que no se cambian solas. Las clases empiezan a las ocho y media.

Nadie sigue dentro. Lo que hay son rastros: lo que se queda para poder volver. Una cuenta nueva, permiso para hacer de root, una tarea que se lanza sola, una clave más en un authorized_keys, un programa que da permisos de root a quien lo ejecute. Tu trabajo es encontrarlo y quitarlo sin quitar lo que es de la academia, que también hay cosas que parecen raras.

Para eso está la hoja de la academia, la que dejó el técnico de antes:

tecnico@srv-aulas:~$ cat ~/hoja-academia.txt
Hoja de la Academia Faro (srv-aulas): lo que es nuestro
Cuentas de personas: profesor (Rubén Ortega, informática) y marta (Marta Gil, secretaría). La del técnico: tecnico.
La cuenta del proyector: proyector (de sistema, sin shell). Su crontab lo enciende a las 8:25 con /usr/local/bin/encender-proyector.
Las copias: /etc/cron.d/copias-academia, cada noche a las 2:15 (/usr/local/sbin/copia-academia).
Sudo: Rubén solo puede reiniciar el proyector (/etc/sudoers.d/profesor). Nadie más, salvo tecnico.
Las claves de Rubén: la de su portátil del aula (SHA256:FVcxGYtv45bt7yW/8qCyDn+mrWyiyVPmXyHOyNUiFaQ) y la de casa (SHA256:wgXEzso68tG35DYtzUsT7LCywLEFsVa7JwsutBjvbIs).
Programas propios: /usr/local/bin/encender-proyector y /usr/local/sbin/copia-academia, sin setuid.

Qué cambió anoche

Lo primero, saber dónde mirar. find con -mtime -1 busca lo modificado en el último día; con -ls, además, cuándo y de quién:

tecnico@srv-aulas:~$ sudo find /etc /usr/local /var/tmp /home -xdev -mtime -1 -type f -ls
      178      4 -rw-r--r--   1 root     root         1721 Oct 14 03:10 /etc/passwd
    179      4 -rw-r--r--   1 root     root          777 Oct 14 03:10 /etc/group
    180      4 -rw-r-----   1 root     shadow        962 Oct 14 03:10 /etc/shadow
    278      4 -rw-r--r--   1 root     root           52 Oct 14 03:15 /etc/cron.d/actualizar-cache
    275      4 -r--r-----   1 root     root           32 Oct 14 03:12 /etc/sudoers.d/90-sistemas
    279     28 -rwsr-xr-x   1 root     root        26936 Oct 14 03:19 /usr/local/bin/diagnostico
    277     16 -rwxr-xr-x   1 root     root        14632 Oct 14 03:14 /var/tmp/.sys/run
    269      4 -rw-------   1 profesor profesor      287 Oct 14 03:17 /home/profesor/.ssh/authorized_keys
    272      4 -rw-r--r--   1 sistemas sistemas     3771 Oct 14 03:10 /home/sistemas/.bashrc
    273      4 -rw-r--r--   1 sistemas sistemas      807 Oct 14 03:10 /home/sistemas/.profile
    274      4 -rw-r--r--   1 sistemas sistemas      220 Oct 14 03:10 /home/sistemas/.bash_logout

Todo entre las 3:10 y las 3:19, y cada línea es un sitio de los de este tema. Pero ojo: -mtime dice qué archivo cambió, no qué línea. En /etc/passwd está la cuenta nueva, pero también la del proyector; en el authorized_keys del profesor, la clave nueva y las suyas. Hay que mirar dentro.

Una cuenta de más

Las cuentas de personas tienen uid de 1000 para arriba; las de sistema (como la del proyector), por debajo. awk las separa:

tecnico@srv-aulas:~$ awk -F: '$3 >= 1000 && $3 < 60000' /etc/passwd
tecnico:x:1000:1000:tecnico:/home/tecnico:/bin/bash
profesor:x:1001:1001:Ruben Ortega,,,:/home/profesor:/bin/bash
marta:x:1002:1002:Marta Gil,,,:/home/marta:/bin/bash
sistemas:x:1003:1003:sistemas,,,:/home/sistemas:/bin/bash

sistemas no está en la hoja. Su nombre suena a algo de la casa (es lo que se busca), pero lastlog dice cuándo entró cada cuenta por última vez, y desde dónde:

tecnico@srv-aulas:~$ sudo lastlog -u sistemas
Username         Port     From             Latest
sistemas         pts/1    203.0.113.34     Wed Oct 14 03:22:12 +0000 2026

Desde fuera, de madrugada. Y en auth.log, cuándo se creó (useradd deja dos líneas):

tecnico@srv-aulas:~$ sudo grep -E "useradd|Accepted" /var/log/auth.log
Oct 14 03:10:46 srv-aulas useradd[4147]: new group: name=sistemas, GID=1003
Oct 14 03:10:46 srv-aulas useradd[4147]: new user: name=sistemas, UID=1003, GID=1003, home=/home/sistemas, shell=/bin/bash, from=/dev/pts/1
Oct 14 03:22:12 srv-aulas sshd[4148]: Accepted password for sistemas from 203.0.113.34 port 40065 ssh2

Para quitarla, userdel -r borra la cuenta, su grupo y su casa. Si prefieres guardarla para investigar, bloquéala: sudo usermod -L -s /usr/sbin/nologin sistemas (sin contraseña y sin shell).

tecnico@srv-aulas:~$ sudo userdel -r sistemas
userdel: sistemas mail spool (/var/mail/sistemas) not found

Ese aviso es normal: no tenía buzón. Lo que no borra userdel es su crontab, si lo tuviera: queda en /var/spool/cron/crontabs con el número de la cuenta en vez de su nombre. cron ya no lo lanza (la cuenta no existe), pero sudo find / -xdev -nouser lo encuentra, por si acaso.

Ejercicio

Una cuenta de más: /etc/passwd, lastlog y userdel

En srv-aulas hay una cuenta de persona que no está en la hoja de la academia (~/hoja-academia.txt). Encuéntrala y que no pueda entrar, sin tocar las de verdad ni la del proyector.

Preparando la máquina…

Quién puede ser root

sudo no solo mira el grupo sudo: lee /etc/sudoers y, por su última línea (@includedir /etc/sudoers.d), los archivos de /etc/sudoers.d. Ahí es fácil dejar una línea:

tecnico@srv-aulas:~$ ls -l /etc/sudoers.d
total 12
-r--r----- 1 root root   32 Oct 14 03:12 90-sistemas
-r--r----- 1 root root 1096 Sep  7 09:30 README
-r--r----- 1 root root   67 Sep  7 09:30 profesor

Sin abrirlos, sudo -l -U dice qué deja sudo a cada cuenta:

tecnico@srv-aulas:~$ sudo -l -U profesor
Matching Defaults entries for profesor on srv-aulas:
  env_reset, mail_badpass,
  secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin,
  use_pty

User profesor may run the following commands on srv-aulas:
  (root) NOPASSWD: /usr/bin/systemctl restart proyector

Eso es lo de la hoja: Rubén puede reiniciar el proyector como root, sin contraseña, y nada más. (ALL) NOPASSWD: ALL sería otra cosa: todo, como root, sin preguntar. Esa es la de 90-sistemas.

tecnico@srv-aulas:~$ sudo rm /etc/sudoers.d/90-sistemas
tecnico@srv-aulas:~$ sudo visudo -c
/etc/sudoers: parsed OK
/etc/sudoers.d/README: parsed OK
/etc/sudoers.d/profesor: parsed OK

visudo -c comprueba todo lo que lee sudo. Si un archivo tiene un error, sudo avisa cada vez que se usa y se salta esa línea (no se rompe entero); si cualquiera puede escribirlo, lo ignora; y uno con un punto en el nombre (ana.conf) ni se lee. Por eso la regla de serie es: archivos sin punto, de root, con permisos 0440, y visudo -c después de tocar.

Ejercicio

Sudo de más: sudo -l -U, sudoers.d y visudo -c

Alguien puede hacer de root sin contraseña y no es el técnico. Encuentra la regla en /etc/sudoers.d y quítala, sin tocar la del profesor (solo reinicia el proyector).

Preparando la máquina…

Lo que se lanza solo

cron lanza lo de tres sitios: /etc/crontab, los archivos de /etc/cron.d (con una columna más: el usuario) y el crontab de cada cuenta. Los de /etc/cron.d se pueden leer sin sudo:

tecnico@srv-aulas:~$ cat /etc/cron.d/*
*/10 * * * * root /var/tmp/.sys/run >/dev/null 2>&1
SHELL=/bin/sh
# Las copias de la academia, cada noche (al NAS del despacho).
15 2 * * * root /usr/local/sbin/copia-academia
30 3 * * 0 root test -e /run/systemd/system || SERVICE_MODE=1 /usr/lib/x86_64-linux-gnu/e2fsprogs/e2scrub_all_cron
10 3 * * * root test -e /run/systemd/system || SERVICE_MODE=1 /sbin/e2scrub_all -A -r

La primera: cada diez minutos, como root, algo en /var/tmp (una carpeta que cualquiera puede escribir) dentro de una carpeta con punto (escondida para ls), y sin dejar rastro de su salida. La de las copias está en la hoja; la de e2scrub_all es de Ubuntu. Los crontab de cada cuenta están en el spool, que solo lee root:

tecnico@srv-aulas:~$ sudo crontab -l -u proyector
25 8 * * 1-5 /usr/local/bin/encender-proyector

Para quitar la tarea, su archivo; y lo que lanzaba, también:

tecnico@srv-aulas:~$ sudo rm /etc/cron.d/actualizar-cache
tecnico@srv-aulas:~$ sudo rm -r /var/tmp/.sys

Aunque ya no esté, cron apunta en el diario cada vez que lanza algo: journalctl -u cron | grep CMD dice qué lanzó y cuándo (y con grep -o "CMD (.*" | sort | uniq -c, cuántas veces cada cosa).

Lo que tiene que lanzarse como otra cuenta va en su crontab: sudo crontab -u marta -e (o echo "<la línea>" | sudo crontab -u marta -, que lo sustituye entero), sin columna de usuario. Así corre como ella y no como root, que es lo que se busca: con lo justo.

Ejercicio

Una tarea de más: /etc/cron.d y crontab -l -u

Algo se lanza cada diez minutos que no es de la academia. Encuentra la tarea y quítala, y también lo que lanza; la de las copias y la del proyector, que sigan.

Preparando la máquina…

Una clave de más

Una clave en un authorized_keys deja entrar sin contraseña, y no hace falta crear ninguna cuenta: basta con añadirla a la de alguien. Las huellas se comparan con las de la hoja:

tecnico@srv-aulas:~$ sudo ssh-keygen -lf /home/profesor/.ssh/authorized_keys
256 SHA256:FVcxGYtv45bt7yW/8qCyDn+mrWyiyVPmXyHOyNUiFaQ ruben@portatil-aula (ED25519)
256 SHA256:wgXEzso68tG35DYtzUsT7LCywLEFsVa7JwsutBjvbIs ruben@casa (ED25519)
256 SHA256:LJcmfzPZQnqEHWPAE17ExoFd/0/sH+XKhM5Jy74uCr4 soporte@faro (ED25519)

La tercera no está en la hoja. El comentario (soporte@faro) lo escribe quien hace la clave: no prueba nada; la huella sí. Se quita esa línea, solo esa (borrar el archivo entero dejaría a Rubén sin entrar):

tecnico@srv-aulas:~$ sudo sed -i "/soporte@faro$/d" /home/profesor/.ssh/authorized_keys

Al revés, una clave nueva de alguien de la casa (la de un portátil nuevo) se comprueba igual, por su huella, y se añade como una línea más, sin tocar las otras: cat nueva.pub | sudo tee -a y el authorized_keys. Y la de un equipo que deja de usarse se quita como esta: no se queda con su llave.

Ejercicio

Una clave de más: ssh-keygen -lf y la hoja

En el authorized_keys del profesor hay una clave que no es suya. Compara las huellas con las de la hoja de la academia y quita la que sobra, solo esa.

Preparando la máquina…

Programas con setuid

Un programa con setuid se ejecuta con los permisos de su dueño, no con los de quien lo lanza. Así funciona passwd: es de root y por eso puede escribir en /etc/shadow cuando cambias tu contraseña. En ls -l se ve como una s en lugar de la x del dueño (-rwsr-xr-x). Un programa de root con setuid que haga lo que le pidan es una puerta para volver a ser root.

tecnico@srv-aulas:~$ find / -xdev -perm -4000 -type f 2>/dev/null
/usr/bin/sudo
/usr/bin/su
/usr/bin/gpasswd
/usr/bin/passwd
/usr/bin/newgrp
/usr/bin/mount
/usr/bin/umount
/usr/bin/chfn
/usr/bin/chsh
/usr/bin/fusermount3
/usr/bin/pkexec
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/openssh/ssh-keysign
/usr/local/bin/diagnostico
/usr/libexec/polkit-agent-helper-1

Esos catorce son los de cualquier Ubuntu Server; diagnostico no. Lo que pone apt viene de un paquete, y dpkg -S dice de cuál; lo copiado a mano, de ninguno:

tecnico@srv-aulas:~$ dpkg -S /usr/bin/passwd /usr/local/bin/diagnostico
passwd: /usr/bin/passwd
dpkg-query: no path found matching pattern /usr/local/bin/diagnostico

Se le quita el setuid (o se borra, si no es de nada), sin tocar los de verdad: a passwd sin setuid nadie podría cambiarse la contraseña.

tecnico@srv-aulas:~$ sudo chmod u-s /usr/local/bin/diagnostico

Ejercicio

Un programa con setuid: find -perm y dpkg -S

Hay un programa con setuid de root que no trae Ubuntu. Encuéntralo entre los de verdad (passwd, sudo, su…) y quítale el setuid, sin tocar los demás.

Preparando la máquina…

En la sala: lo que se quedó dentro

En la sala estás en el cuarto de servidores de la academia, con el aula al lado. En el panel del vigilante de integridad sale lo que sigue distinto de ayer, archivo por archivo, y sus avisos, que suben de tono cada vez que vuelve a mirar. El vigilante no sabe qué es de la academia: la hoja, en tu mesa, sí (y ayer por la tarde la academia cambió dos cosas suyas). Hasta las ocho y media: a las 8:25 el servidor enciende el proyector y a esa hora Rubén entra en el aula. Quita lo que sobra; si quitas algo de la academia, se nota en clase (y en la nota). Y si te quedas sin sudo o sin SSH, la consola del servidor arranca en modo de recuperación, pero cuesta veinte minutos.