Tengo una pregunta bastante profunda aquí que espero que alguien pueda responder. En macOS, los usuarios normales pueden hacer ping y rootear. Normalmente, se requiere acceso de root para abrir el socket sin formato necesario para ejecutar ping. He notado que en Linux esto generalmente se logra agregando atributos extendidos al archivo del programa ping para permitir el acceso a nivel de raíz para abrir sockets sin procesar (en el pasado, esto se hacía simplemente configurando el bit setuid en el programa ping, permitiéndole hacer cualquier cosa en su programación como root).
Miré /sbin/ping en macOS (High Sierra, específicamente), y no se establecieron tales atributos, y tampoco setuid. Entonces, ¿qué está haciendo macOS para permitir que los usuarios estándar (no root) hagan ping? ¿Están enviando paquetes ICMP a través de TCP o UDP? Si es así (o si hay otro mecanismo que me falta por completo), ¿puede indicarme algunos documentos? Cualquier ayuda sería apreciada.
Echemos un vistazo al código fuente de la implementación de Apple ping
. En particular, vemos esto:
if (getuid())
s = socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP);
else
s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
sockerrno = errno;
getuid
devuelve 0 si es root. Entonces, este código dice: "abra el socket en DGRAM (modo de datagrama) si no somos root. Si somos root, abra como sin procesar".
Entonces, un socket sin formato solo se usa cuando eres root. Un paquete de ping IMCP es un paquete DGRAM estándar y no requiere conectores sin formato.
Sin embargo, hay algunas banderas que se pueden pasar ping
que requieren root, y para ellas obtendrá una "Operación no permitida". Por ejemplo:
>ping -f
ping: -f flag: Operation not permitted
Cuando ejecuto como root, no obtengo la operación no permitida. Entonces, la implementación de Apple le permitirá realizar operaciones de ping estándar que no requieren root, pero requieren que se ejecute como root para ciertas banderas y operaciones.
Dependiendo de si es root, puede establecer algunas opciones de socket adicionales:
if (uid == 0)
(void)setsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *)&hold,
sizeof(hold));
klanomath
bmike
melvin jefferson
le_jawa