Hola a todos Nos unimos activamente al trabajo y en enero estamos preparando muchos lanzamientos poderosos. Entre otros, se ha anunciado un conjunto para una nueva secuencia del curso de Administrador de Linux que todos adoran. En previsión del lanzamiento, tradicionalmente compartimos la traducción de material útil.
Los permisos de archivos ofrecen una alternativa segura a los ejecutables de SUID, pero pueden parecer un poco confusos al principio.
Todos sabemos que los binarios
SUID son una
solución de seguridad deficiente . Afortunadamente, si su aplicación requiere algunos privilegios limitados, hay una forma más eficiente llamada
permisos de archivos .
Le ahorraré tiempo si desea evitar una lectura detallada del artículo anterior: en esencia, los permisos de archivos permiten procesos que se ejecutan como root y, por lo tanto, tienen el derecho de hacer algo, guardar ciertas funciones limitadas por
esta lista cuando restablecer privilegios y ejecutar como un usuario sin privilegios. Esto significa que si un atacante logra comprometer un proceso al desbordar un búfer u otro exploit, no podrá aprovechar nada más que ciertos privilegios mínimos que el proceso realmente necesita.
Los permisos son excelentes para servicios que generalmente siempre se ejecutan como root, pero ¿qué pasa con las utilidades de línea de comandos? Afortunadamente, esto también es compatible siempre que tenga instaladas las utilidades correctas. Si usa Ubuntu, por ejemplo, necesitará el paquete
libcap2-bin
. También deberá ejecutar un núcleo no arcaico (a partir de la versión
2.6.24 ).
Estas funciones le permiten asociar permisos con archivos ejecutables de manera similar a establecer el bit SUID, pero solo para un conjunto específico de permisos. La utilidad
setcap
usa para agregar y eliminar permisos de un archivo.
El primer paso es seleccionar los permisos que necesita. Para este artículo, supongo que hay una herramienta de diagnóstico de red llamada
tracewalk
que debería poder usar
sockets sin procesar . Esto generalmente requiere que la aplicación se ejecute como root, pero al ver la
lista, resulta que solo se
CAP_NET_RAW
permiso
CAP_NET_RAW
.
Suponiendo que está en el directorio donde se encuentra el binario
tracewalk
, puede agregar este permiso de la siguiente manera:
sudo setcap cap_net_raw=eip tracewalk
Por ahora, ignore el sufijo
=eip
para obtener permiso, hablaré de esto en un par de segundos. Tenga en cuenta que el nombre del permiso está en minúsculas. Ahora puede verificar si ha configurado los permisos correctamente con:
setcap -v cap_new_raw=eip tracewalk
O puede enumerar todos los permisos establecidos para este archivo ejecutable:
getcap tracewalk
Como referencia, también puede eliminar todos los permisos del ejecutable usando:
setcap -r tracewalk
En este punto, debería poder ejecutar el ejecutable como un usuario sin privilegios, y él debería poder trabajar con sockets sin procesar, pero no tener otros privilegios que tenga el usuario raíz.
Entonces, ¿qué significa este sufijo extraño
=eip
? Esto requerirá un poco de comprensión de la naturaleza de los permisos. Cada proceso tiene tres conjuntos de permisos:
efectivo, heredable y permitido (efectivo, heredable y permitido) :
- Los permisos efectivos son aquellos que determinan lo que realmente puede hacer un proceso. Por ejemplo, no puede tratar con sockets sin
CAP_NET_RAW
si CAP_NET_RAW
no CAP_NET_RAW
en un conjunto eficiente. - Los permisos permitidos son aquellos que un proceso puede tener si los solicita a través de una llamada apropiada. No permiten que un proceso realmente haga nada a menos que se haya escrito específicamente para solicitar el permiso especificado. Esto le permite escribir procesos para agregar permisos críticos al conjunto efectivo solo para el período en que realmente se necesitan.
- Los permisos heredables son aquellos que se pueden heredar en la colección disponible del proceso secundario. Durante la operación
fork()
o clone()
, el proceso hijo siempre recibe una copia de los permisos del proceso padre, porque en ese momento todavía está ejecutando el mismo archivo ejecutable. Un conjunto heredado se usa cuando se llama a exec()
(o un equivalente) para reemplazar el ejecutable con otro. En este punto, el conjunto de procesos disponible queda enmascarado por el conjunto heredado para obtener el conjunto disponible que se utilizará para el nuevo proceso.
Por lo tanto, la utilidad
setcap
nos permite agregar permisos de estos tres conjuntos independientemente para un archivo ejecutable dado. Tenga en cuenta que el significado de los grupos se interpreta de manera un poco diferente para los permisos de archivos:
- Los permisos de archivo disponibles son aquellos que siempre están disponibles para el ejecutable, incluso si el proceso principal que lo llamó no los tenía. Solían llamarse permisos "forzados".
- Los permisos de archivos heredados definen una máscara adicional que también se puede usar para eliminar permisos del conjunto del proceso de llamada. Se usan además del conjunto heredado del proceso de llamada, por lo que el permiso se hereda solo si existe en ambos conjuntos.
- Los permisos de archivo efectivos son, de hecho, solo un bit, no un conjunto, y si está instalado, significa que todo el conjunto disponible también se copia al conjunto efectivo del nuevo proceso. Esto se puede usar para agregar permisos a procesos que no se escribieron específicamente para solicitarlos. Como esto es un bit, si lo configura para cualquier permiso, debe configurarse para todos los permisos. Puede considerarlo un bit heredado porque se usa para permitir permisos para aplicaciones que no los admiten.
Al especificar permisos a través de
setcap
tres letras
e
,
i
y
p
refieren a conjuntos
eficientes, heredados y accesibles , respectivamente. Entonces, una especificación anterior:
sudo setcap cap_net_raw=eip tracewalk
... indica que el permiso
CAP_NET_RAW
debe agregarse a los conjuntos disponibles y heredados y que el bit efectivo también debe establecerse. Esto reemplazará cualquier permiso previamente establecido en el archivo. Para establecer múltiples permisos a la vez, use una lista separada por comas:
sudo setcap cap_net_admin,cap_net_raw=eip tracewalk
La guía de permisos analiza todo esto con más detalle, pero espero que esta publicación desmitifique un poco el incidente. Queda por mencionar solo algunas advertencias y trucos.
Primero, las capacidades de archivo no funcionan con enlaces simbólicos: debe aplicarlas al binario en sí (es decir, al destino del enlace simbólico).
En segundo lugar, no funcionan con guiones interpretados. Por ejemplo, si tiene un script Python al que desea asignar permiso, debe asignarlo al intérprete Python mismo. Obviamente, este es un problema de seguridad potencial, porque entonces todos los scripts ejecutados con este intérprete tendrán el permiso especificado, aunque esto es mucho mejor que hacer el SUID. La solución más común, aparentemente, es escribir un archivo ejecutable separado en C o un análogo que pueda realizar las operaciones necesarias y llamarlo desde un script. Esto es similar al enfoque utilizado por Wireshark, que utiliza el archivo binario
/usr/bin/dumpcap
para realizar operaciones privilegiadas:
$ getcap /usr/bin/dumpcap /usr/bin/dumpcap = cap_net_admin,cap_net_raw+eip
En tercer lugar, los permisos de archivo se deshabilitan si usa la
LD_LIBRARY_PATH
entorno
LD_LIBRARY_PATH
por razones obvias de seguridad
(1) . Lo mismo se aplica a
LD_PRELOAD
, que yo sepa.
1. Dado que el atacante obviamente puede reemplazar una de las bibliotecas estándar y usar LD_LIBRARY_PATH
para forzar que su biblioteca sea llamada con preferencia sobre el sistema y, por lo tanto, tener su propio código arbitrario ejecutado con los mismos privilegios que la aplicación que realiza la llamada.
Eso es todo. Los detalles sobre el programa del curso se pueden encontrar en el seminario web, que se realizará el 24 de enero.