Tcpdump DROP privileges

Estoy seguro que muchos de vosotros conocéis tcpdump y en más de una ocasión la habréis utilizado. Como todos sabréis cuando la ejecutamos como usuario sin privilegios para capturar paquetes en una interfaz de red recibimos el siguiente mensaje:

$ /usr/sbin/tcpdump -i eth0
tcpdump: eth0: You don't have permission to capture on that device
(socket: Operation not permitted)

Esto es porque la aplicación requiere de ciertos privilegios que nuestro usuario no tiene. Es por esto que se suele ejecutar como usuario root, corriendo el riesgo de que una vulnerabilidad al ser explotada, pudiera aprovechar que estamos lanzando la aplicación como usuario con privilegios de administrador y esto si nos ponemos en “mode paranoid ON” nos incomoda.

Lanzando una búsqueda rápida en Google podemos ver en el blog de Taosecurity ejemplos de vulnerabilidades de tcpdump que nos pueden servir de ejemplo de que éstas existen, aunque no son muy habituales. Hay que ser consciente de que la probabilidad de explotación de este tipo de vulnerabilidades suele ser baja (debido a la madurez de la aplicación, y a otros factores que engloban su uso habitual), pero aún así, “siempre” es recomendable (u obligatorio) ejecutar cualquier aplicación con el mínimo privilegio que sea necesario, y este caso no tiene porque ser menos. Al hilo de lo que acabamos de comentar vamos a ver una opción interesante de tcpdump que nos va a permitir justo esto.

Si lanzamos tcpdump como root y hacemos un ps observaremos lo siguiente (el dueño del proceso es el usuario root):

$ps -ef 
root  	5445  5435  0 13:09 pts/0	00:00:00 tcpdump -i eth0 port 4444

En cambio si lo lanzamos con la opción -Z, que como podemos ver el ‘man’ tiene el siguiente sifgnificado:

-Z : Drops privileges (if root) and changes user ID to user and the group ID to 
the primary group of user. 

Obtendremos el siguiente resultado (fijaros en el usuario dueño del proceso):

$ tcpdump -i eth0 port 4444 -Z josemi
$ ps -ef
josemi	 5450  5435  0 13:09 pts/0	00:00:00 tcpdump -i eth0 port 4444 -Z josemi

Si observamos el estado de este proceso veremos (fijaros en el uid y gid):

$cat /proc/5450/status
Name:    tcpdump
State:    S (sleeping)
Tgid:    5450
Pid:    5450
PPid:    5435
TracerPid:    0
Uid:    1000    1000    1000    1000
Gid:    1000    1000    1000    1000

$ cat /etc/passwd | grep -i josemi
josemi:x:1000:1000:JoseMi,,,:/home/josemi:/bin/bash

Si vemos las llamadas al sistema que realiza la aplicación cuando la invocamos con la opción -Z veremos como hace el cambio al usuario “josemi”. Para esto utilizaremos la aplicación strace:

$ strace tcpdump -i eth0 port 4444 -Z josemi

setgroups32(9, [1000, 4, 20, 24, 46, 112, 120, 122, 126]) = 0
setgid32(1000)                      	= 0
setuid32(1000)                      	= 0
write(2, "tcpdump: verbose output suppress"..., 75tcpdump: verbose output 
suppressed, use -v or -vv for full protocol decode) = 75
write(2, "listening on eth0, link-type EN1"..., 73listening on eth0, link-type 
EN10MB (Ethernet), capture size 65535 bytes) = 73
poll([{fd=3, events=POLLIN}], 1, 1000)  = 0 (Timeout)
poll([{fd=3, events=POLLIN}], 1, 1000)  = 0 (Timeout)
poll([{fd=3, events=POLLIN}], 1, 1000)  = 0 (Timeout)
poll([{fd=3, events=POLLIN}], 1, 1000 

La llamadas interesantes que realiza el proceso son setgid32 y setuid32. Estas dos llamadas devuelven 0 cuando todo ha ido bien. Este cambio lo realiza después de haber ejecutado como superusuario todas las operaciones. Leyendo la documentación de estas funciones podemos ver lo siguiente:

“If the user is root or the program is set-user-ID-root, special care must be taken. The setuid() function checks the effective user ID of the caller and if it is the superuser, all process-related user ID’s are set to uid. After this has occurred, it is impossible for the program to regain root privileges.

Thus, a set-user-ID-root program wishing to temporarily drop root privileges, assume the identity of an unprivileged user, and then regain root privileges afterward cannot use setuid().

He remarcado el hecho de que si el usuario es root no se podrá volver a retomar los privilegios originales. Como hemos visto el proceso pertenece al usuario josemi y posee sus privilegios. En el caso de aprovechar un atacante una vulnerabilidad obtendría los privilegios de este usuario y no los de superusuario.

Como siempre esperamos que os sea de utilidad y cualquier apunte o corrección es bienvenido ;-)

Comments

  1. buen detalle :-)

  2. Pero, ¿te permite realizar la captura de paquetes con esos privilegios?

  3. Sí, en las pruebas que he hecho captura paquetes :-)