
Utilidad de línea de comandos de Windows para leer, escribir y ejecutar código en modo kernel desde el contexto de Administrador mediante una técnica de redirección de ejecución de validación de fuentes, lo que permite la depuración avanzada del kernel y la resolución de problemas del sistema.
r0ak es una utilidad de línea de comandos de Windows que permite leer, escribir y ejecutar código en modo kernel (con algunas limitaciones) desde el símbolo del sistema, sin necesidad de nada más que privilegios de Administrador.
r0ak v1.0.0 -- Ring 0 Army Knife
http://www.github.com/ionescu007/r0ak
Copyright (c) 2018 Alex Ionescu [@aionescu]
http://www.windows-internals.com
USAGE: r0ak.exe
[--execute <Address | module.ext!function> <Argument>]
[--write <Address | module.ext!function> <Value>]
[--read <Address | module.ext!function> <Size>]

El kernel de Windows es un entorno rico en el que cientos de controladores se ejecutan en un sistema típico, y donde están presentes miles de variables que contienen estado global. Para la resolución de problemas avanzada, los expertos en TI suelen utilizar herramientas como el Depurador de Windows (WinDbg), herramientas de SysInternals, o escribir las suyas propias. Desafortunadamente, el uso de estas herramientas es cada vez más difícil, y ellas mismas están limitadas por su propio acceso a las API de Windows y a las características expuestas.
Algunos de los desafíos actuales incluyen:
En un entorno así, quedó claro que una herramienta simple que pueda usarse como un parche/arreglo rápido de emergencia y para solucionar rápidamente problemas a nivel de kernel/sistema que puedan ser evidentes mediante el análisis del estado del kernel podría ser valiosa para la comunidad.

r0ak funciona redirigiendo el flujo de ejecución de las comprobaciones de validación de fuentes de confianza del administrador de ventanas al intentar cargar una nueva fuente, reemplazando la rutina de comparación de la tabla de fuentes de confianza con una función alternativa que programa un elemento de trabajo ejecutivo (WORK_QUEUE_ITEM) almacenado en el nodo de entrada. Luego, el hijo derecho de la tabla de fuentes de confianza (que sirve como nodo raíz) se sobrescribe con un búfer de escritura de una tubería con nombre (NP_DATA_ENTRY) en el que se almacena un elemento de trabajo personalizado. La función de trabajo subyacente de este elemento y su parámetro eventualmente serán ejecutados por un ExpWorkerThread dedicado en PASSIVE_LEVEL una vez que se intente cargar una fuente y se ejecute la rutina de comparación, recibiendo el nodo padre respaldado por la tubería con nombre como su entrada. Se utiliza un evento de seguimiento de Eventos para Windows (ETW) en tiempo real para recibir una notificación asíncrona de que el elemento de trabajo ha terminado de ejecutarse, lo que hace seguro desmantelar las estructuras, liberar los búferes del modo kernel y restaurar la operación normal.
Al usar la opción --execute, esta función y parámetro son proporcionados por el usuario.
Al usar --write, se utiliza un gadget personalizado para modificar valores arbitrarios de 32 bits en cualquier lugar de la memoria del kernel.
Al usar --read, el gadget de escritura se utiliza para modificar el puntero y el tamaño del búfer HSTI del sistema (N.B.: Este es un comportamiento destructivo en términos de cualquier otra aplicación que solicite los datos HSTI. Como este es un comportamiento opcional de Windows, y esta herramienta está destinada para depuración/experimentación de emergencia, esta pérdida de datos se consideró aceptable). Luego, la API de consulta HSTI se utiliza para copiar los datos de vuelta al espacio de direcciones en modo usuario de la herramienta, y se muestra un volcado hexadecimal.
Debido a que solo se utiliza funcionalidad integrada de Windows firmada por Microsoft, y todas las funciones llamadas son parte del mapa de bits KCFG, no hay violación de ninguna verificación de seguridad, y no se requieren banderas de depuración, ni el uso de controladores de terceros mal escritos.
No. Dado que esta herramienta — y la técnica subyacente — requieren un token privilegiado a nivel de SYSTEM, que solo puede obtenerse por un usuario que ejecuta bajo la cuenta de Administrador, no se están eludiendo límites de seguridad para lograr el efecto. El comportamiento y la utilidad de la herramienta solo son posibles debido al contexto de seguridad elevado/privilegiado de la cuenta de Administrador en Windows, y se entiende que es un comportamiento por diseño.
¡Por supuesto! Es importante reportar siempre los problemas de seguridad a Microsoft incluso cuando parece que no ha ocurrido una violación de límites privilegiados; sus equipos de investigadores y desarrolladores podrían encontrar vectores novedosos y formas de alcanzar ciertas rutas de código que un investigador externo podría no haber considerado.
Como tal, en noviembre de 2014, se presentó un caso de seguridad al Centro de Investigación de Seguridad de Microsoft (MSRC) que respondió: "[…] no entra en el ámbito de un problema de seguridad que abordaríamos a través de nuestro vehículo tradicional de boletines de seguridad. […] presupone privilegios de administrador, un lugar donde, arquitectónicamente, no definimos actualmente un límite de seguridad defendible. Como tal, no buscaremos solucionar esto."
Además, en abril de 2015 en la conferencia Infiltrate, se presentó una charla titulada Insection : AWEsomely Exploiting Shared Memory Objects detallando este problema, incluso a desarrolladores de Microsoft presentes, quienes acordaron que esto estaba actualmente fuera del alcance de los límites de seguridad arquitectónicos de Windows. Esto se debe a que hay literalmente docenas — si no más — de otras formas en que un Administrador puede leer/escribir/ejecutar memoria en Anillo 0. Esta herramienta simplemente permite una mercantilización fácil de uno de esos vectores, con fines de depuración y solución de problemas del sistema.
Empaquetar este código como una biblioteca requeriría eliminar cuidadosamente todo el análisis interactivo de línea de comandos y la salida estándar, en cuyo punto, sin reescrituras importantes, el 'kit':
_NT_SYMBOL_PATH sensata haya sido configurada en la máquina objetivo, y que aproximadamente 15 MB de datos de símbolos se descarguen y almacenen en caché como archivos PDB en algún lugar del discoLos atacantes interesados en usar este enfoque particular — en comparación con muchas otras técnicas más multiplataforma y que no requieren derechos de SYSTEM — probablemente ya adaptaron su propio código basado en la Prueba de Concepto de abril de 2015, hace más de 3 años.
Debido al uso del Motor de Símbolos de Windows, debes tener instalado el Kit de Desarrollo de Software de Windows (SDK) o el Kit de Controladores de Windows (WDK) con las Herramientas de Depuración para Windows. La herramienta buscará automáticamente tu ruta de instalación y aprovechará los archivos DbgHelp.dll y SymSrv.dll que están presentes en ese directorio. Como estos archivos no son redistribuibles, no pueden incluirse con la versión de la herramienta.
Alternativamente, si obtienes estas bibliotecas por tu cuenta, puedes modificar el código fuente para usarlas.
El uso de símbolos requiere una conexión a Internet, a menos que los hayas almacenado en caché localmente. Además, debes configurar la variable _NT_SYMBOL_PATH apuntando a un servidor de símbolos apropiado y una ubicación de caché.
Se asume que un Experto en TI u otro solucionador de problemas que aparentemente tiene la necesidad de leer/escribir/ejecutar memoria del kernel (y tiene conocimiento de las variables de kernel apropiadas a las que acceder) ya está más que íntimamente familiarizado con los requisitos de configuración anteriores. Por favor, no reportes problemas preguntando qué es el SDK o cómo establecer una variable de entorno.
¿Algún controlador filtró un pool del kernel? ¿Por qué no llamar a ntoskrnl.exe!ExFreePool y pasar la dirección del kernel que está filtrando? ¿Qué tal una referencia a un objeto? Ve a llamar a ntoskrnl.exe!ObfDereferenceObject y haz que se limpie.
¿Quieres volcar el registro DbgPrint del kernel? ¿Por qué no volcar el búfer circular interno en ntoskrnl.exe!KdPrintCircularBuffer
¿Te preguntas qué tan grandes son las pilas del kernel en tu máquina? Intenta mirar ntoskrnl.exe!KeKernelStackSize
¿Quieres volcar la tabla de llamadas al sistema para buscar ganchos? Ve a imprimir ntoskrnl.exe!KiServiceTable
Estos son solo algunos ejemplos: todas las direcciones de Anillo 0 son aceptadas, ya sea mediante la sintaxis module!symbol o pasando directamente el puntero del kernel si se conoce. El Motor de Símbolos de Windows se utiliza para buscarlos.
La herramienta requiere ciertas variables y funciones del kernel que solo se sabe que existen en versiones modernas de Windows 10, y solo se diseñó para funcionar en sistemas de 64 bits. Estas limitaciones se deben al hecho de que en sistemas más antiguos (o sistemas x86), estos requisitos de seguridad más estrictos no existen y, por lo tanto, se pueden usar enfoques más tradicionales. Esta es una herramienta personal que estoy poniendo a disposición, y no necesitaba estos sistemas más antiguos, donde podría usar un controlador simple. Dicho esto, este repositorio acepta solicitudes de extracción, si alguien está interesado en portarlo.
En segundo lugar, debido a los casos de uso y mis propias necesidades, se aplican las siguientes restricciones:
Obviamente, estas limitaciones podrían solucionarse eligiendo programáticamente un enfoque diferente, pero se ajustan a las necesidades de una herramienta de línea de comandos y a mis casos de uso. Nuevamente, se aceptan solicitudes de extracción si otros desean contribuir con sus propias adiciones.
Ten en cuenta que toda la ejecución (incluyendo la ejecución de los comandos --read y --write) ocurre en el contexto de un Hilo de Trabajo del Sistema en PASSIVE_LEVEL. Por lo tanto, no se deben pasar direcciones en modo usuario como parámetros/argumentos.
Las solicitudes de extracción son bienvenidas. Para cambios importantes, abre primero un issue para discutir lo que te gustaría cambiar.
Copyright 2018 Alex Ionescu. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided
that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and
the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions
and the following disclaimer in the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY ALEX IONESCU ``AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ALEX IONESCU
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those of the authors and
should not be interpreted as representing official policies, either expressed or implied, of Alex Ionescu.