CLI tool
skelsec/pypykatz avatar
skelsec/pypykatz

pypykatz: the parsing is separated from the data source, and Windows has no entry point

Mimikatz implementation in pure Python

3,361 stars433 forksPythonMIT

At a glance

What is it?
pypykatz is a pure Python reimplementation of Mimikatz that runs wherever Python 3.6 does, and it is built for post-incident analysis rather than only for live machines, because every parser is independent of where the bytes came from. It carries an accuracy warning on DPAPI, an explicit request for credential-bearing memory dumps, and a packaging script that removes its own Windows executable on purpose.
Who is it for?
This tool belongs in a lab, on a machine you own, or on evidence you are authorised to examine, and the ordering matters: read the sections on the Windows entry point removal and on the dump request before you run it anywhere shared.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 179 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 5, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The Windows executable is removed on purpose, and the comment says why

The most unusual thing in this repository is a line of packaging logic. The console script that registers the command is defined, then discarded on Windows:

python
entry_points=ep if platform.system().lower() != 'windows' else {}

The comment above it is blunt about the reason. It says there is no more convenient executable entry point thanks to someone who used the code without modification in a state-backed trojan, and it thanks the people who ran it for everyone.

That is a defensive decision rather than a technical one, and it has a visible cost: on Windows there is no installed command, so the tool has to be invoked as a module or through another path, while every other system gets the normal console script. It is also a statement about how the code gets reused. A tool that reads credentials from memory will be copied, and a packaging-level deterrent at least changes the shape of what a careless copy produces.

The rest of the packaging is ordinary. The version is read out of a file inside the package with a regular expression, and a missing version string raises at build time rather than installing a nameless release.

Parsing is separated from the data source, which is what makes offline work possible

The stated difference from the original tool is not that it reimplements the same commands, but that the command set differs while the architecture improves on it. This project parses the secrets held in the LSASS process, and its main difference is that all the parsing logic is separated from the data source, so defining a new reader object is enough to perform the same parsing from anywhere.

That single design choice is what turns this from a live-machine tool into a forensic one. The listed sources for LSASS material are: live, which reads the process memory directly and is Windows only; a minidump produced by dumping the process; the Rekall fork, which processes essentially any Windows memory dump that Rekall can parse; pcileech, listed as no longer supported; a remote source described as another project still to be done; and a placeholder inviting other projects, with the remark that integration is simple.

Every command also comes in a live and a normal form where that applies, with the normal form being platform independent. That pairing is why the project runs on any operating system with a suitable Python while its most interesting sources are Windows-specific.

Registry hives are read for stored hashes, cached domain credentials and LSA secrets

The second capability is registry parsing, and its target list is specific: stored credentials including NT and LM hashes, domain cached credentials in both generations, and LSA secrets.

The design point again is the separation. Live parsing has two techniques. The first works in memory and does not touch disk at all, which matters when the machine under examination is one you cannot write to, or when an incident response policy forbids creating files on it. The second dumps the hives and then parses those files with the offline parser, which is the same code path used for a hive file you were handed from somewhere else. The offline source is listed alongside those two.

Read together with the previous section, the pattern is consistent: every capability has an in-memory form and a file form, and the file form is a first-class input rather than a fallback. That is the difference between a tool that only works on a live Windows session and one that can be used on evidence months later.

The third listed source for this section repeats the invitation to integrate, which tells you the reader interface is the extension point the author cares about.

DPAPI support is documented as not completely correct

The third capability covers the Data Protection API, which the file describes as the protector of local secrets of many kinds. Four artefact types are supported: master keys, DPAPI blobs, credential files and vault files.

The accuracy statement comes before the source list and is worth quoting in full. The results are not completely correct, because there is not much documentation on most of these things, and pull requests are welcomed.

That caveat covers the whole section, including the most operationally interesting source, which is a valid-credentials offline path where a master key file can be decrypted by supplying the correct SID and password. The remaining sources are live, drawing master keys from LSASS or the user and machine keys from the live registry, hive files offline, and that credential-based path.

The last entry in the list is a request rather than a source: do not integrate this part into your project, because it is beta. So the section describes four supported artefact types, an accuracy caveat on all of them, and one component the author would rather you did not build on.

The project asks for memory dumps, and warns against sending the wrong kind

There is a HELP WANTED section that asks readers to submit minidumps of the LSASS process to a third-party file sharing address, and it opens with the reason. Creating structure definitions for the large number of Windows structures involved is work that would normally be checked by a native compiler's built-in parser, and pure Python has no such safety net. A single byte of misalignment makes the whole parse fail, and the alignment differences between 32-bit and 64-bit builds are the main source of that, which is why 32-bit dumps are requested as well.

The warning is the most important sentence in the file. Readers are told explicitly not to send dumps from their own machine, because the maintainer would then be able to see the secrets in them, including hashes and passwords, and are asked to send material from virtual test systems they do not mind being read, with a test domain using Kerberos described as ideal.

The closing summary is practical rather than technical: the maintainer needs data to verify the parsers against and to make changes until they work, and issues filed without the file would not help, since a dump is hundreds of megabytes and the forge will not take an attachment that size.

Every one of those dumps contains live credentials by definition, which is why this section is worth reading twice.

Rekall integration needs a virtualenv and a hand-edited plugin file

Two routes into the memory parsing exist: a command in this tool that takes the memory file to parse, or Rekall's own command line. The second route has three conditions, and the first of them is marked as important.

Rekall must be run in a virtual environment, and this tool has to be installed into that same virtual environment. Rekall's own command line is not suitable for showing everything the parsing acquires, so the output file and Kerberos directory switches are the ones to use instead.

The integration is manual. A plugin file sits in the plugins folder of this project, has to be copied into Rekall's own plugins folder for Windows and renamed, and then the init file in that same folder has to be edited to add an import line for it. Once that is done the command is available from Rekall directly.

There is one parsing option documented, a timestamp override taking the value zero or one. Its stated reason is that choosing the correct structure for parsing needs the timestamp information of the msv library file, that Rekall does not always have that information, and that parsing may therefore be failing. The example command for it carries a misspelling of memory in its placeholder, which is a small sign of how informally the section is maintained.

Install from pip or from a clone, and the author warns about the master branch

Installation has two routes. Pip, with a single command, or a clone of the repository followed by installing the prerequisites and running the setup script directly. Either way the installer places a pypykatz executable in the Python Script directory, and the file notes it should be on your path.

The warning that follows is the author's own and it is blunt: the GitHub master version might fail, because versions are not put on separate branches, with a promise to try creating a stable branch. If you are installing from source, that is the reason to pin a commit rather than take the tip of a branch.

The dependency list explains the scope. Five packages are named as prerequisites for the source route, and the install requirement list in the setup script adds a few more, all of them pinned with both a lower and an upper bound. The floor is Python 3.6, the same floor the file states.

The repository itself is small: the package directory, a tests directory, a builder directory, a manifest file, a makefile with clean, build, rebuild and publish targets, and a pyproject file that contains nothing but a build system table, leaving all metadata in the setup script. The publish target builds a source distribution and a wheel and uploads them with twine. The release history skips a number between 0.6.11 and 0.6.13, and the last published version is from January 2026.

Editorial conclusion

This tool belongs in a lab, on a machine you own, or on evidence you are authorised to examine, and the ordering matters: read the sections on the Windows entry point removal and on the dump request before you run it anywhere shared. It earns its place for forensics, because separating the parsers from their data source means the same code path handles a minidump, a full memory image or a hive file, and because the formats it reads are the ones a Windows incident leaves behind. Three things to weigh. The DPAPI results are stated by the author to be not completely correct, so treat output as investigative rather than evidentiary. The master branch is warned about by the project itself as possibly broken. And the request for sample dumps goes to a third-party file share, which is a reminder that credential material is exactly what these files contain.

Frequently asked questions

What is pypykatz?

A Mimikatz implementation written in pure Python that runs on any operating system supporting Python 3.6 or later. Its stated difference from the original is that the parsing logic is separated from the data source, so a new reader object is enough to parse LSASS material from anywhere.

Which data sources can pypykatz read LSASS secrets from?

Live process memory on Windows, a minidump file, and memory dumps that the Rekall fork can parse. Pcileech is listed as no longer supported, and a remote source is listed as another project still to be done.

Does pypykatz decrypt DPAPI protected data correctly?

The file states plainly that the results are not completely correct, because there is little documentation on most of these formats. Supported artefact types are master keys, DPAPI blobs, credential files and vault files, and one of the sources is described as beta with a request not to integrate it.

Why does pypykatz not install a command on Windows?

The packaging script deliberately drops the console script on Windows, with a comment saying it is because the code was used without modification in a state-backed trojan. Other systems get the pypykatz command registered normally.

How do I install pypykatz?

With pip3 install pypykatz, or by cloning the repository, installing the listed prerequisites and running python3 setup.py install. The installer creates a pypykatz executable in the Python Script directory, and the file warns that the master branch might fail.

What does pypykatz read out of the Windows registry?

Stored credentials including NT and LM hashes, domain cached credentials of both generations, and LSA secrets. Live parsing works either in memory without touching disk, or by dumping the hives and parsing them with the offline parser.

Official sources

  1. Issues
  2. License: MIT
  3. README
  4. Releases
  5. skelsec/pypykatz on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/skelsec-pypykatz.svg)](https://hysenlabs.com/projects/skelsec-pypykatz)