¿Alguna vez se ha publicado un artículo sobre exactamente cómo funciona SuperSu? Después de buscar durante un tiempo, encontré principalmente guías sobre cómo usar la aplicación, no los detalles de implementación.
Sin embargo, encontré este recurso que se dirige principalmente a explicar cómo usar los privilegios de root mediante programación, pero explicó las cosas bastante bien. El artículo brinda información sobre SELinux, pero no tanto sobre cómo se elude su aplicación.
Parece haber muchos cambios de contexto para permitir la ejecución de ciertos eventos (desde el punto de vista de aquellos que usan SuperSu) que de otro modo se negarían bajo SELinux, pero ¿cómo llegó SuperSu al punto en el que pudo " legalmente ", como en lo que respecta a SELinux, ¿parchar las políticas de SEL?
Parece que el objetivo es forzar el proceso de inicio para generar un nuevo shell que ejecute el demonio su, pero no parece haber ningún parche del proceso de inicio , sino del artículo vinculado:
En firmwares que usan SELinux, su generalmente se implementa como un proxy para un demonio iniciado desde init
y
Quizás se pregunte por qué, si ya estamos ejecutando como contexto de inicio, como usuario raíz.
tl;dr ; ¿Cómo se ejecuta SuperSu en el contexto del proceso de inicio?
Dado como:
u:r:init:s0 - Highest init context
u:r:init_shell:s0 - Shell started from init
SuperSU ya no se desarrolla activamente, el nuevo estándar prevaleciente es Magisk, que originalmente se basó en SuperSU (ideas y quizás también algo de código), pero ahora ha avanzado mucho. Así que es mejor optar por una nueva solución de código abierto mantenida activamente siempre que sea posible. O si quieres algo de aventura, prueba esto: ¿ Cómo rootear manualmente un teléfono? .
Mi respuesta a ¿Cómo funciona Magisk? cubre casi todas las partes internas de SuperSU, también algunos detalles adicionales que no son aplicables a SuperSU. Mantengámoslo simple.
0
):Android se basa en el kernel de Linux que, cuando se inicia en el arranque del dispositivo, se ejecuta como usuario root. El espacio del núcleo es invisible para nosotros: el espacio de usuario . init
es el primer proceso iniciado por kernel que podemos ver, también se ejecuta con acceso de root. Inicia muchos servicios/demonios (el sistema operativo), muchos de ellos también se ejecutan con privilegios de root. Finalmente, cuando todos los procesos requeridos están activos, init
nos lleva a un proceso no raíz (sin privilegios): un shell en los sistemas operativos Linux estándar, una aplicación de inicio o una pantalla de bloqueo (que también es una aplicación de interfaz de usuario del sistema ) en Android. Root es el querido usuario del kernel, el superusuario , identificado por su ID de usuario . 0
. Kernel nunca lo restringe haciendo daño o bien a nada en el dispositivo. A los usuarios sin privilegios se 1
les asignan UID 65534
(normalmente). Android divide estos UID para diferentes categorías de aplicaciones y procesos como se explica aquí . Cada proceso y cada archivo tiene un UID , ID de grupo , grupos complementarios y modo de permiso . Estos cuatro parámetros gobiernan cómo un proceso accede a otros procesos y archivos. Todo este fenómeno se denomina C ontrol de acceso discrecional .
Si un proceso sin privilegios quiere acceder a algún archivo o realizar alguna acción que solo está permitida para el usuario root, el primero debe cambiar al segundo. Se hace ejecutando un archivo (generalmente su
) que es set-user-id-root o tiene capacidadessetuid
de / segid
file . Una capacidad es un subconjunto de las autorizaciones del usuario raíz. El archivo ejecutado hace syscallsetuid
por lo que el kernel eleva el estado sin privilegios a privilegiado. Esta es una simplificación, en realidad hay muchos otros factores involucrados. Pero en Android, las aplicaciones se ejecutan eliminando todas las capacidades y privilegios de tal manera que no pueden elevar sus privilegios de ninguna manera (excluyendo vulnerabilidades). Entonces, la aplicación sin privilegios solicita algún otro proceso privilegiado que ya se está ejecutando para realizar la tarea privilegiada en nombre de la anterior. El proceso privilegiado se nombra daemonsu
(o magiskd
) y la solicitud se reenvía cuando una aplicación ejecuta su
un binario especial que interactúa con la aplicación SuperSU para solicitar permiso al usuario humano.
Además de DAC , Android también utiliza SELinux , un control de acceso obligatorio . Al igual que DAC, cada proceso y cada archivo se etiqueta con un contexto SELinux y se define una política para permitir una amplia gama de interacciones entre contextos/etiquetas. La política no contiene Super Contexto , por lo que cada proceso (incluso cuando se ejecuta con UID ) tiene algunas limitaciones. Pero debe ejecutarse con un contexto completamente sin restricciones que debe definirse antes de configurar SELinux (en una etapa de inicio muy temprana) porque después de eso no hay forma de configurarlo o modificar la política. Algunos proveedores construyen sus núcleos sin0
daemonsu
enforcing
init
permissive
SECURITY_SELINUX_DEVELOP
, por lo que el kernel aplica SELinux, incluso antes. En este caso, el núcleo necesita ser reconstruido/parchado. Ver detalles en esta respuesta .
Cuando se muestra SuperSU.zip:
/sepolicy
archivo con un contexto totalmente permisivo u:r:supersu:s0
( supersu
puede ser diferente, no recuerdo qué usó SuperSU en las últimas versiones, Magisk ahora usa u:r:magisk:s0
).init
servicio personalizado en /init.rc
el archivo que comienza daemonsu
con 0
el contexto UID/GID y SELinux u:r:supersu:s0
después de /data
montarlo (o incluso antes).Tanto sepolicy
los init.rc
archivos como han sido parte del ramdisk
interior boot.img
(que también contiene binarios del kernel), pero con Treble, SAR y A/B
Particiones pueden estar en ubicaciones diferentes. Entonces Magisk usa diferentes enfoques para diferentes dispositivos, pero el concepto es el mismo.
Ambos pasos también se pueden sustituir reemplazando el /init
binario real con uno personalizado init
que se hace cargo del proceso de arranque, parchea sepolicy
e inicia el servicio sobre la marcha antes de ejecutar el archivo init
.
Otras cosas que están directamente relacionadas con el proceso de enraizamiento incluyen el desbloqueo del cargador de arranque, boot.img
desempaquetar/reempaquetar, deshabilitar el arranque verificado ( dm-verity
) y FDE/FBE , parchear el kernel para que arranque diferente init
(o para deshabilitar los mecanismos de seguridad específicos del proveedor), enraizamiento sin sistema, (des)configuración de Android propiedades, directorios de montaje de enlace, aislamiento de espacios de nombres de montaje, etc.
andres t
sherrellbc
hanshenrik
Irfan Latif