Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
dpapi-ng — Python DPAPI NG Decryptor for non-Windows Platforms | Kitploit
Outils/GitHubGitHub/jborean93/dpapi-ng
Encryption/Decryption ToolsDigital ForensicsCryptographyAuthenticationRed Teaming
GitHubjborean93/dpapi-ng

dpapi-ng

Python DPAPI NG Decryptor for non-Windows Platforms

Voir le dépôt
716il y a 1 anVérifié par Kitploit

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

dpapi_ng - Bibliothèque Python de dé-/chiffrement DPAPI-NG

Test workflow codecov PyPI version License

Bibliothèque pour le dé- et le chiffrement de DPAPI NG, également connu sous le nom de CNG DPAPI, en Python. Elle est conçue pour reproduire le comportement de NCryptUnprotectSecret et NCryptProtectSecret. Elle peut être utilisée sur des hôtes non-Windows pour dé-/chiffrer des secrets protégés par DPAPI NG, comme le mot de passe protégé par l'utilisateur d'un PFX, ou le mot de passe chiffré de LAPS. Elle peut soit déchiffrer n'importe quel blob DPAPI NG à l'aide d'une copie hors ligne de la clé racine du domaine, soit dé-/chiffrer en utilisant les informations d'identification de l'utilisateur fourni pour récupérer les informations requises via RPC.

Actuellement, seuls ces descripteurs de protection sont pris en charge :

TypeObjectif
SIDSeul l'utilisateur SID ou les membres du groupe SID peuvent déchiffrer le secret

Ceci implémente le protocole MS-GKDI Group Key Distribution Protocol.

Prérequis

  • CPython 3.9+
  • cryptography >= 3.1
  • dnspython >= 2.0.0
  • pyspnego >= 0.9.0

Comment installer

Pour installer dpapi-ng avec toutes les fonctionnalités de base, exécutez

root@kitploit:~
python -m pip install dpapi-ng

Authentification Kerberos

La prise en charge de l'authentification Kerberos n'est pas installée par défaut car elle dépend des bibliothèques système et de la présence d'un compilateur valide. Les bibliothèques krb5 et le compilateur peuvent être installés en installant ces paquets :

root@kitploit:~
# Debian/Ubuntu
apt-get install gcc python3-dev libkrb5-dev

# Centos/RHEL
yum install gcc python-devel krb5-devel

# Fedora
dnf install gcc python-devel krb5-devel

# Arch Linux
pacman -S gcc krb5

Une fois installé, les extras Python Kerberos peuvent être installés avec

root@kitploit:~
python -m pip install dpapi-ng[kerberos]

Kerberos doit également être configuré pour communiquer avec le domaine, mais cela dépasse le cadre de cette page.

Depuis la source

root@kitploit:~
git clone https://github.com/jborean93/dpapi-ng.git
cd dpapi-ng
pip install -e .

Exemples

Il existe à la fois une API synchrone et une API asyncio pour dé-/chiffrer un blob.

root@kitploit:~
import dpapi_ng


### DÉCHIFFREMENT ###
dpapi_ng_blob = b"..."
decrypted_blob = dpapi_ng.ncrypt_unprotect_secret(dpapi_ng_blob)

# équivalent asynchrone de ce qui précède
decrypted_blob = await dpapi_ng.async_ncrypt_unprotect_secret(dpapi_ng_blob)


### CHIFFREMENT ###
data = b"..."
target_sid = "S-1-5-21-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXXX-XXXX"
dpapi_ng_blob = dpapi_ng.ncrypt_protect_secret(data, target_sid)

# équivalent asynchrone de ce qui précède
dpapi_ng_blob = await dpapi_ng.async_ncrypt_protect_secret(data, target_sid)

Pour déchiffrer le blob, la clé spécifiée dans le blob doit être récupérée auprès du contrôleur de domaine qui a généré le blob. Pour chiffrer un blob, la clé de groupe du SID cible spécifié doit être récupérée. Pour le déchiffrement, le nom d'hôte du contrôleur de domaine est automatiquement récupéré via une recherche DNS SRV de _ldap._tcp.dc._msdcs.{domain_name} avec le nom de domaine trouvé dans le blob DPAPI-NG ou avec la valeur spécifiée dans l'argument server. Pour le chiffrement, le nom d'hôte du contrôleur de domaine est déterminé soit en utilisant l'argument domain_name pour une recherche DNS SRV, soit l'argument server directement, soit en utilisant le domaine de recherche du système (si disponible). Il tentera de s'authentifier avec l'identifiant utilisateur actuel qui, sur Linux, n'existera que si kinit a déjà été appelé pour récupérer le ticket d'un utilisateur. Sinon, si aucune identité n'est disponible, les arguments username et password peuvent être utilisés pour spécifier un utilisateur personnalisé.

Les arguments suivants peuvent être utilisés pour ncrypt_unprotect_secret, async_ncrypt_unprotect_secret, ncrypt_protect_secret et async_ncrypt_protect_secret.

  • server : Utiliser ce serveur comme cible RPC si une clé doit être récupérée
  • username : Le nom d'utilisateur avec lequel s'authentifier pour la connexion RPC
  • password : Le mot de passe avec lequel s'authentifier pour la connexion RPC
  • auth_protocol : Le protocole d'authentification (negotiate, kerberos, ntlm) à utiliser pour la connexion RPC
  • cache : Un cache pour stocker les clés récupérées pour une utilisation ultérieure

En plus de cela, ncrypt_protect_secret et async_ncrypt_protect_secret acceptent l'argument supplémentaire suivant.

  • domain_name : Le nom du domaine/forest à utiliser lors de la recherche de la cible RPC pour récupérer les informations de clé
  • root_key_identifier : L'UUID de l'identifiant de la clé racine, nécessaire pour faire fonctionner le cache pour ces fonctions

Il est également possible de chiffrer et de déchiffrer le blob DPAPI-NG en fournissant la clé racine stockée dans le domaine. Celle-ci peut être récupérée soit par une attaque hors ligne, soit via une requête LDAP si vous exécutez en tant qu'utilisateur Admin de domaine. Pour récupérer les clés racines du domaine à l'aide de PowerShell, la commande suivante peut être exécutée :

root@kitploit:~
$configurationContext = (Get-ADRootDSE).configurationNamingContext
$getParams = @{
    LDAPFilter = '(objectClass=msKds-ProvRootKey)'
    SearchBase = "CN=Master Root Keys,CN=Group Key Distribution Service,CN=Services,$configurationContext"
    SearchScope = 'OneLevel'
    Properties = @(
        'cn'
        'msKds-KDFAlgorithmID'
        'msKds-KDFParam'
        'msKds-SecretAgreementAlgorithmID'
        'msKds-SecretAgreementParam'
        'msKds-PrivateKeyLength'
        'msKds-PublicKeyLength'
        'msKds-RootKeyData'
    )
}
Get-ADObject @getParams | ForEach-Object {
    [PSCustomObject]@{
        Version = 1
        RootKeyId = [Guid]::new($_.cn)
        KdfAlgorithm = $_.'msKds-KDFAlgorithmID'
        KdfParameters = [System.Convert]::ToBase64String($_.'msKds-KDFParam')
        SecretAgreementAlgorithm = $_.'msKds-SecretAgreementAlgorithmID'
        SecretAgreementParameters = [System.Convert]::ToBase64String($_.'msKds-SecretAgreementParam')
        PrivateKeyLength = $_.'msKds-PrivateKeyLength'
        PublicKeyLength = $_.'msKds-PublicKeyLength'
        RootKeyData = [System.Convert]::ToBase64String($_.'msKds-RootKeyData')
    }
}

La commande ldapsearch suivante peut être utilisée en dehors de Windows :

root@kitploit:~
ldapsearch \
    -b 'CN=Master Root Keys,CN=Group Key Distribution Service,CN=Services,CN=Configuration,DC=domain,DC=test' \
    -s one \
    '(objectClass=msKds-ProvRootKey)' \
    cn \
    msKds-KDFAlgorithmID \
    msKds-KDFParam \
    msKds-SecretAgreementAlgorithmID \
    msKds-SecretAgreementParam \
    msKds-PrivateKeyLength \
    msKds-PublicKeyLength \
    msKds-RootKeyData

Remarque : ldapsearch aura très probablement besoin des options -H et des informations de liaison utilisateur pour réussir.

Les informations récupérées peuvent être stockées dans un cache et utilisées pour les appels ultérieurs à ncrypt_protect_secret et ncrypt_unprotect_secret :

root@kitploit:~
import uuid

import dpapi_ng

cache = dpapi_ng.KeyCache()

root_key_id = uuid.UUID("76ec8b2d-d444-4f67-9db7-2f62b4358b35")
cache.load_key(
    b"...",                             # msKds-RootKeydata
    root_key_id,                        # cn
    version=1,
    kdf_algorithm="SP800_108_CTR_HMAC", # msKds-KDFAlgorithmID
    kdf_parameters=b"...",              # msKds-KDFParam
    secret_algorithm="DH",              # mskds-SecretAgreementAlgorithmID
    secret_parameters=b"...",           # msKds-SecretAgreementParam
    private_key_length=512,             # msKds-PrivateKeyLength
    public_key_length=2048,             # msKds-PublicKeyLength
)

dpapi_ng.ncrypt_unprotect_secret(b"...", cache=cache)

Actuellement, l'algorithme KDF SP800_108_CTR_HMAC et les algorithmes d'accord secret DH, ECDH_P256 et ECDH_P384 ont été testés et fonctionnent. L'algorithme d'accord secret ECDH_P521 devrait également fonctionner mais n'a pas été testé car un environnement de test ne peut pas être créé avec celui-ci pour le moment.

Remerciements particuliers

Je tiens à remercier les personnes suivantes (identifiants GitHub ou Twitter entre parenthèses) pour leur aide sur ce projet :

  • Georg Sieber (@schorschii) pour avoir implémenté la prise en charge du chiffrement
  • Grzegorz Tworek (@0gtweet) et Michał Grzegorzewski pour avoir fourni plus d'informations sur le flux de travail interne de l'API BCrypt* utilisé dans DPAPI-NG
  • Marc-André Moreau (@awakecoding) pour son aide dans la rétro-ingénierie de certaines API Windows et pour avoir discuté de certaines théories
  • SkelSec (@SkelSec) pour son aide sur les appels RPC et pour avoir servi de caisse de résonance à mes théories
  • Steve Syfuhs (@SteveSyfuhs) pour m'avoir mis en relation avec certains ingénieurs Microsoft afin de comprendre certaines logiques non documentées

Sans leur patience et leurs connaissances, cela n'aurait probablement pas été possible.

Télécharger l’outil