La semana pasada hablamos sobre la extracción de claves privadas SSH en Windows 10 como un nuevo método para el Hacking de Windows. Hoy quería enseñar lo sencillo que es crear un módulo de ibombshell, el cual será liberado este mes en cuanto Álvaro Nuñez y yo terminemos unos detalles. Recordando que ibombshell tiene dos modos de ejecución, uno el denominado "everywhere" con Powershell y el denominado "silently" gracias a un C2 escrito en Python.
Cuando hablamos de módulos hablamos de la posibilidad de incorporar funcionalidad al C2 de Python. En el caso de querer crear una nueva funcionalidad para el modo everywhere se debe añadir en el Github correspondiente, en nuestro caso será el GitHub de ElevenPaths, la función de Powershell necesaria. Como se explicó en el artículo dedicado a ibombshell es necesario tener clara la estructura de directorios y ficheros en el Github, ya que la consola hará uso de dicha estructura.
Primera parte. Creación de la función
En primer lugar, vamos a crear una función para extraer las claves privadas SSH en Windows 10. Esta función se obtiene del conocimiento de esta técnica y tiene un requisito importante y es que el proceso dónde se ejecute dicha función se esté ejecutando con integridad alta. Es lógico aplicar una serie de comentarios en la función o en la ayuda de la función sobre este tema.
El aspecto de la función puede ser algo parecido a lo que se puede ver en la imagen. La función extract-sshprivatekey comprueba en primer lugar si existe el path HKCU:\Software\OpenSSH\Agent\Keys. En caso de existir, recorre el número de claves almacenadas en la ruta. Por cada clave, se lista el valor de Comment que es el nombre de la clave en ASCII. Por último, se recupera el valor de clave en binario y se codifica en Base64. Aquí acaba la función.
Hay que recordar que, posteriormente, habría que hacer uso del script parse_mem.py para obtener el valor ASCII de la clave privada. Lo importante sería poder utilizar esta información en una vía remota, pero cabe la posibilidad de utilizar en el modo everywhere de ibombshell.
Si listamos las funciones disponibles en la shell con el comando showcommands nos aparece la siguiente ruta post/extract-sshprivatekey. Esto es gracias al mapeo que se puede encontrar en la raíz del repositorio, en el fichero functions.txt, en el que se relaciona las funciones con las rutas del repositorio.
Una vez descargada a memoria la función, ésta se queda en el provider de funciones con el nombre sshprivatekey. Como he comentado anteriormente, si el entorno dónde se ejecuta la función tiene privilegios podremos ejecutarla, si no nos devolverá un error, tal y como se puede visualizar en la imagen.
Ahora, vamos a suponer que tenemos privilegio en el proceso. Realizando el mismo proceso comentado anteriormente, el resultado es distinto, la función ejecutada en ibombshell devuelve los nombres de las claves y el base64 del binario de la clave privada.
Con ese base64 se debe ejecutar parse_mem.py para obtener la clave privada en ASCII. La función extract-sshprivatekey es una versión nuestra que se ha realizado para este artículo y que queda dentro del repositorio para su uso en auditoría o un proyecto de Ethical Hacking.
Segunda parte. Creando el módulo para nuestro panel en Python
Lo primero es entender el formato que tiene un módulo de ibombshell en Python. La idea es sencilla, que cuando el pentester ejecute el módulo en Python éste genere la función de Powershell y la instrucción para invocarla. Esta información es almacenada en un fichero que el "warrior", o proceso que ejecuta ibombshell en remoto, leerá mediante una petición HTTP.
Recuperando el esquema con el que jugamos en nuestro panel en Python y la interacción con el warrior de ibombshell vemos la siguiente imagen. En esta imagen, se puede ver que es el warrior el que, cuando es ejecutado en la máquina remota, realiza una petición hacia nuestro C2 registrando la dirección IP y el nombre o ID. Esto es a través de una petición HTTP, a través de un GET. Posteriormente, tras el registro, el warrior realiza una petición HTTP para verificar si hay algún tipo de función o funciones que deba, primero cargar en memoria y posteriormente ejecutar.
El usuario del C2 al configurar un módulo y ejecutar el run, lo que está haciendo es almacenar en un fichero la función correspondiente y las instrucciones que se deben ejecutar en el warrior de ibombshell en Powershell. Cuando el warrior lee el fichero, ya carga la función y las instrucciones las ejecuta. Posteriormente, el warrior envía los resultados a través de un POST que se realiza al mismo recurso en el panel de Python.
Ahora, entendamos qué partes tiene un módulo de ibombshell en Python. Se proporcionará una clase denominada CustomModule. El cual tiene el constructor y un método run_module. Como se puede ver, un módulo no será algo complejo.
En el constructor tenemos una variable information, la cual es un diccionario que proporciona varios atributos y varios valores. Suele ser tema informativo, nombre del módulo, autor, descripción, etcétera. Por otro lado, se tiene la variable options. Esta variable es un diccionario que tiene los atributos del módulo. Por cada atributo se tiene una lista en el que se indica si el atributo tendrá algún valor, su descripción y si es obligatorio.
El método run_module implementará lo que se va a ejecutar cuando el pentester haga ‘run’, una vez configurado el módulo. Lo primero que se hace en esta función es verificar si el warrior configurado por el usuario existe. Para ello se comprueban los ficheros creados por ibombshell sobre los que se comunicará el warrior ejecutado en remoto. El ID de dicho warrior debe existir en forma de fichero.
Por último, se añade a la variable function la instrucción que hará que el warrior remoto ejecute la función cargada. No es más que el propio nombre de la función. En este caso, depende de la configuración del módulo, ya que una función puede tener N formas de ser ejecutada.
Es decir, una función puede ser ejecutada con varios parámetros o argumentos, por lo que utilizaremos selectores o bifurcaciones para los diferentes casos y acabaremos agregando a la variable function la instrucción necesaria, en función de la configuración del módulo.
Conclusión final: PoC en Vídeo
A continuación, os dejo un video dónde se puede ver el funcionamiento del nuevo módulo y los resultados que éste proporciona.
Pronto liberaremos la primera versión beta de ibombshell, será la 0.0.1 y esperamos el feedback. Recuerda ‘the first boom, but two ways…”
Autor: Pablo González Pérez (@pablogonzalezpe), escritor de los libros "Metasploit para Pentesters", "Hacking con Metasploit: Advance Pentesting" "Hacking Windows", "Ethical Hacking", "Got Root" y “Pentesting con Powershell”, Microsoft MVP en Seguridad y Security Researcher en ElevenPaths
Figura 1: ibombshell: Crear un módulo para extracción de claves privadas SSH en Windows 10 |
Cuando hablamos de módulos hablamos de la posibilidad de incorporar funcionalidad al C2 de Python. En el caso de querer crear una nueva funcionalidad para el modo everywhere se debe añadir en el Github correspondiente, en nuestro caso será el GitHub de ElevenPaths, la función de Powershell necesaria. Como se explicó en el artículo dedicado a ibombshell es necesario tener clara la estructura de directorios y ficheros en el Github, ya que la consola hará uso de dicha estructura.
Primera parte. Creación de la función
En primer lugar, vamos a crear una función para extraer las claves privadas SSH en Windows 10. Esta función se obtiene del conocimiento de esta técnica y tiene un requisito importante y es que el proceso dónde se ejecute dicha función se esté ejecutando con integridad alta. Es lógico aplicar una serie de comentarios en la función o en la ayuda de la función sobre este tema.
El aspecto de la función puede ser algo parecido a lo que se puede ver en la imagen. La función extract-sshprivatekey comprueba en primer lugar si existe el path HKCU:\Software\OpenSSH\Agent\Keys. En caso de existir, recorre el número de claves almacenadas en la ruta. Por cada clave, se lista el valor de Comment que es el nombre de la clave en ASCII. Por último, se recupera el valor de clave en binario y se codifica en Base64. Aquí acaba la función.
Figura 2: Función extract-sshprivatekey |
Hay que recordar que, posteriormente, habría que hacer uso del script parse_mem.py para obtener el valor ASCII de la clave privada. Lo importante sería poder utilizar esta información en una vía remota, pero cabe la posibilidad de utilizar en el modo everywhere de ibombshell.
Si listamos las funciones disponibles en la shell con el comando showcommands nos aparece la siguiente ruta post/extract-sshprivatekey. Esto es gracias al mapeo que se puede encontrar en la raíz del repositorio, en el fichero functions.txt, en el que se relaciona las funciones con las rutas del repositorio.
Una vez descargada a memoria la función, ésta se queda en el provider de funciones con el nombre sshprivatekey. Como he comentado anteriormente, si el entorno dónde se ejecuta la función tiene privilegios podremos ejecutarla, si no nos devolverá un error, tal y como se puede visualizar en la imagen.
Figura 3: Extracción de clave privada con ibombshell genera error |
Ahora, vamos a suponer que tenemos privilegio en el proceso. Realizando el mismo proceso comentado anteriormente, el resultado es distinto, la función ejecutada en ibombshell devuelve los nombres de las claves y el base64 del binario de la clave privada.
Figura 4: Extracción correcta |
Con ese base64 se debe ejecutar parse_mem.py para obtener la clave privada en ASCII. La función extract-sshprivatekey es una versión nuestra que se ha realizado para este artículo y que queda dentro del repositorio para su uso en auditoría o un proyecto de Ethical Hacking.
Segunda parte. Creando el módulo para nuestro panel en Python
Lo primero es entender el formato que tiene un módulo de ibombshell en Python. La idea es sencilla, que cuando el pentester ejecute el módulo en Python éste genere la función de Powershell y la instrucción para invocarla. Esta información es almacenada en un fichero que el "warrior", o proceso que ejecuta ibombshell en remoto, leerá mediante una petición HTTP.
Recuperando el esquema con el que jugamos en nuestro panel en Python y la interacción con el warrior de ibombshell vemos la siguiente imagen. En esta imagen, se puede ver que es el warrior el que, cuando es ejecutado en la máquina remota, realiza una petición hacia nuestro C2 registrando la dirección IP y el nombre o ID. Esto es a través de una petición HTTP, a través de un GET. Posteriormente, tras el registro, el warrior realiza una petición HTTP para verificar si hay algún tipo de función o funciones que deba, primero cargar en memoria y posteriormente ejecutar.
Figura 5: Intercambio de mensajes |
El usuario del C2 al configurar un módulo y ejecutar el run, lo que está haciendo es almacenar en un fichero la función correspondiente y las instrucciones que se deben ejecutar en el warrior de ibombshell en Powershell. Cuando el warrior lee el fichero, ya carga la función y las instrucciones las ejecuta. Posteriormente, el warrior envía los resultados a través de un POST que se realiza al mismo recurso en el panel de Python.
Ahora, entendamos qué partes tiene un módulo de ibombshell en Python. Se proporcionará una clase denominada CustomModule. El cual tiene el constructor y un método run_module. Como se puede ver, un módulo no será algo complejo.
En el constructor tenemos una variable information, la cual es un diccionario que proporciona varios atributos y varios valores. Suele ser tema informativo, nombre del módulo, autor, descripción, etcétera. Por otro lado, se tiene la variable options. Esta variable es un diccionario que tiene los atributos del módulo. Por cada atributo se tiene una lista en el que se indica si el atributo tendrá algún valor, su descripción y si es obligatorio.
Figura 6: CustomModule |
El método run_module implementará lo que se va a ejecutar cuando el pentester haga ‘run’, una vez configurado el módulo. Lo primero que se hace en esta función es verificar si el warrior configurado por el usuario existe. Para ello se comprueban los ficheros creados por ibombshell sobre los que se comunicará el warrior ejecutado en remoto. El ID de dicho warrior debe existir en forma de fichero.
Figura 7: Método run_module |
Por último, se añade a la variable function la instrucción que hará que el warrior remoto ejecute la función cargada. No es más que el propio nombre de la función. En este caso, depende de la configuración del módulo, ya que una función puede tener N formas de ser ejecutada.
Figura 8: Módulo cargado en ibombshell |
Es decir, una función puede ser ejecutada con varios parámetros o argumentos, por lo que utilizaremos selectores o bifurcaciones para los diferentes casos y acabaremos agregando a la variable function la instrucción necesaria, en función de la configuración del módulo.
Conclusión final: PoC en Vídeo
A continuación, os dejo un video dónde se puede ver el funcionamiento del nuevo módulo y los resultados que éste proporciona.
Figura 9: PoC en vídeo de nuevo método de ibombshell
Pronto liberaremos la primera versión beta de ibombshell, será la 0.0.1 y esperamos el feedback. Recuerda ‘the first boom, but two ways…”
Autor: Pablo González Pérez (@pablogonzalezpe), escritor de los libros "Metasploit para Pentesters", "Hacking con Metasploit: Advance Pentesting" "Hacking Windows", "Ethical Hacking", "Got Root" y “Pentesting con Powershell”, Microsoft MVP en Seguridad y Security Researcher en ElevenPaths
Hola señor Chema Alonso le admiro bastante por su pasión, su determinación, sus logros y su amor por la informática. Bendiciones y saludos.
ResponderEliminar