¿Cómo uso capsh? Estoy tratando de ejecutar un ping sin privilegios, con capacidades mínimas.

13

Estoy experimentando con capacidades, en Debian Gnu / Linux.

Copié / bin / ping en mi directorio de trabajo actual. Como se esperaba, no funciona, originalmente era setuid root.

Luego le doy a mi ping las capacidades mínimas (no root) haciendo sudo /sbin/setcap cap_net_raw=ep ./ping, y mi ping funciona, como se esperaba.

Luego sudo /sbin/setcap -r ./pingrevocar esa capacidad. Ahora no funciona como se esperaba.

Ahora trato de hacer que el ping funcione usando capsh.

capsh no tiene privilegios, por lo que necesito ejecutarlo como root, pero luego descartar root y, por lo tanto, todos los demás privilegios.

Creo que también necesito secure-keep-caps, esto no está documentado capsh, pero está en el manual de capacidades. Tengo los números de bit de /usr/include/linux/securebits.h. Parecen correctos, ya que la salida de --printmuestra que estos bits son correctos.

He estado jugando durante horas, hasta ahora tengo esto.

sudo /sbin/capsh --keep=1 --secbits=0x10 --caps="cap_net_raw+epi" == --secbits=0x10 --user=${USER} --print -- -c "./ping localhost"

Sin embargo, pingerrores con ping: icmp open socket: Operation not permittedesto es lo que sucede cuando no tiene la capacidad. También los --printespectáculos Current: =p cap_net_raw+i, esto no es suficiente lo que necesitamos e.

sudo /sbin/capsh --caps="cap_net_raw+epi" --print -- -c "./ping localhost"establecerá la capacidad para que Current: = cap_net_raw+eipesto sea correcto, pero nos deja como root.

Editar-1

Ahora he intentado sudo /sbin/capsh --keep=1 --secbits=0x11 --caps=cap_net_raw+epi --print -- -c "touch zz; ./ping -c1 localhost;"

Esto produce:

touch: cannot touch `zz': Permission denied
ping: icmp open socket: Operation not permitted

El primer error se espera como secure-noroot: yes Pero el segundo no esCurrent: = cap_net_raw+eip

Editar-2

Si lo puse ==antes --print, ahora se muestra Current: = cap_net_raw+i, por lo que eso explica el error anterior, pero no por qué estamos perdiendo capacidad al cambiar de raíz, pensé que eso secure-keep-capsdebería solucionarlo.

Editar-3

Por lo que puedo ver, estoy perdiendo Efectivo (e) y Permitido (p), cuando se llama a exec. Esto es de esperarse, pero pensé que seguro-topes, debería evitar que se pierdan. Me estoy perdiendo de algo.

Editar-4

He estado investigando más y leyendo el manual nuevamente. Parece que normalmente ey las pcapacidades se pierden cuando: cambias de usuario root(o aplicas secure-noroot, haciendo que la raíz sea un usuario normal), esto puede ser anulado secure-keep-caps; cuando llamas exec, por lo que puedo decir, esto es invariante.

Por lo que puedo decir, está funcionando de acuerdo con el manual. Por lo que puedo decir, no hay forma de hacer nada útil capsh. Por lo que puedo decir, para usar las capacidades que necesita: use las capacidades de archivo o tenga un programa que tenga en cuenta las capacidades, que no usa exec. Por lo tanto, no hay contenedor privilegiado.

Así que ahora mi pregunta es qué me estoy perdiendo, para qué sirve capsh.

Editar-5

He agregado una respuesta sobre las capacidades ambientales. Tal vez capshtambién se pueda usar con capacidades heredadas, pero para ser útiles, estas deberían establecerse en el archivo ejecutable. No puedo ver cómo Capsh puede hacer algo útil sin capacidades ambientales, o para permitir capacidades heredadas.


Versiones

  • capshde la libcap2-binversión del paquete1:2.22-1.2
  • antes de editar-3 Agarré la última capshde git://git.debian.org/collab-maint/libcap2.gity empecé a usarlo.
  • uname -a Linux richard-laptop 3.2.0-4-amd64 #1 SMP Debian 3.2.65-1+deb7u2 x86_64 GNU/Linux La tierra del usuario es de 32 bits.
ctrl-alt-delor
fuente
1
¿Probaste el ejemplo de Lekensteyn con un lanzamiento posterior ? Obteniendo capshdel repositorio collab-maint no le habría dado lo "más reciente" capsh, el paquete Debian todavía no admite capacidades ambientales. Upstream 2.27 hace.
Stephen Kitt
1
@StephenKitt es bueno saberlo, pero la pregunta original es para qué sirve capsh, en ausencia de ambiente (como era originalmente). Qué me estoy perdiendo. Debe tener un uso.
ctrl-alt-delor

Respuestas:

11

Las capacidades son propiedades de los procesos. Tradicionalmente hay tres conjuntos:

  • Capacidades permitidas ( p ): capacidades que pueden "activarse" en el proceso actual.
  • Capacidades efectivas ( e ): capacidades que se pueden utilizar actualmente en el proceso actual.
  • Capacidades heredables ( i ): capacidades de archivo que pueden heredarse.

Los programas que se ejecutan como root siempre tienen capacidades completas permitidas y efectivas, por lo que "agregar" más capacidades no tiene un efecto notable. (El conjunto de capacidades heredables normalmente está vacío). Con setcap cap_net_raw+ep pingusted habilita estas capacidades de manera predeterminada para cualquier usuario que ejecute este programa.

Desafortunadamente, estas capacidades están vinculadas al archivo ejecutado y no se retienen después de ejecutar un nuevo proceso secundario. Linux 4.3 introdujo capacidades ambientales que permiten que los procesos secundarios hereden las capacidades. (Consulte también Transformación de capacidades durante execve () en capacidades (7)) .

Mientras juega con capacidades, tenga en cuenta estas trampas:

  • Cuando se cambia el usuario de root a no root, se borran las capacidades efectivas y permitidas (consulte Efecto de los cambios de ID de usuario en las capacidades de las capacidades (7) ). Puede usar la --keep=1opción de capshpara evitar borrar los conjuntos.
  • El conjunto de capacidades ambientales se borra al cambiar las ID de usuario o grupo. Solución: agregue las capacidades ambientales después de cambiar la ID de usuario, pero antes de ejecutar un proceso secundario.
  • Una capacidad solo se puede agregar al conjunto de capacidades ambientales si ya está en el conjunto de capacidades permitidas y heredables.

El capshprograma de libcap 2.25 aún no tiene la capacidad de modificar las capacidades ambientales, pero las versiones posteriores agregan nuevas opciones. Tenga en cuenta que el orden de las opciones es significativo. Ejemplo de uso:

sudo capsh --caps="cap_net_raw+eip cap_setpcap,cap_setuid,cap_setgid+ep" \
    --keep=1 --user=nobody --addamb=cap_net_raw -- \
    -c "./ping -c1 127.0.0.1"

Consejo: puede agregar la --printopción en cualquier lugar de la capshlínea de comando y ver su estado actual de capacidades.

Nota: cap_setpcapse necesita por un --addambtiempo cap_setuid,cap_setgidpara la --useropción.

Lekensteyn
fuente
6

La respuesta de Lekensteyn parece precisa y completa, pero intentaré proporcionar otra explicación desde un ángulo diferente que tratará de enfatizar el problema que resuelve el conjunto de capacidades ambientales.

Cuando ejecuta sudo capsh --user=<some_user> --Hay 2 llamadas de interés del sistema que hacen que las capacidades se vuelvan a calcular (y posiblemente se eliminen):

  1. setuid: Según man capabilities:

SECBIT_KEEP_CAPS La configuración de este indicador permite que un subproceso que tiene uno o más 0 UID retenga sus capacidades cuando cambia todos sus UID a un valor distinto de cero. Si este indicador no está configurado, entonces dicho interruptor UID hace que el hilo pierda todas las capacidades.

En otras palabras, en nuestro capshcomando anterior, debemos asegurarnos de que SECBIT_KEEP_CAPS esté configurado durante la setuidllamada al sistema. De lo contrario, se pierden todas las capacidades. Esto es lo que --keep=1hace. Entonces ahora el comando se conviertesudo capsh --user=<some_user> --keep=1 --

  1. execve: Si usamos la --keep=1opción, todos los conjuntos de capacidades (efectivos, permitidos, heredables) se conservan hasta la execvellamada del sistema, sin embargo execve, también se recalculan las capacidades (para usuarios no root), y de una manera no tan obvia. En resumen, antes de la adición del conjunto de capacidades ambientales , para que una capacidad esté en el conjunto "permitido" de un hilo después de una execvellamada, ya sea:

    • El archivo debe tener esa capacidad en su conjunto "permitido" . Esto se puede hacer con setcap cap_net_raw+p /bin/bash. Hacer esto hace que todo el ejercicio sea inútil ya que los conjuntos de capacidades del hilo (que no sean el conjunto delimitador) ya no tienen ningún efecto.
    • Tanto el archivo como el hilo deben tener esa capacidad en sus conjuntos "heredables" . Puede pensar que eso funcionaría setcap cap_net_raw+i, pero resulta que execvehace que los permisos inherentes de un hilo se eliminen cuando son llamados por usuarios sin privilegios (a los que actualmente estamos agradecidos setuid). Por lo tanto, no hay forma de satisfacer esta condición como usuario sin privilegios.

Las capacidades ambientales introducidas en Linux 4.3 hacen posible que un hilo retenga sus capacidades incluso después setuidde un usuario no privilegiado seguido de un execve, sin tener que depender de las capacidades del archivo.

catanman
fuente
2

Puede haber un error / característica en el núcleo. Ha habido alguna discusión:

No tengo idea, si se ha hecho algo, para solucionarlo.

No me malinterpreten: el comportamiento actual es seguro. Pero es tan seguro que obstaculiza las cosas que deberían funcionar.

Editar: según http://man7.org/linux/man-pages/man7/capabilities.7.html hay un nuevo conjunto de capacidades Ambient (desde Linux 4.3). Parece que esto permitirá lo que se necesita.

ctrl-alt-delor
fuente