Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
dpapi-ng — Python DPAPI NG Decryptor for non-Windows Platforms | Kitploit
Herramientas/GitHubGitHub/jborean93/dpapi-ng
Encryption/Decryption ToolsDigital ForensicsCryptographyAuthenticationRed Teaming
GitHubjborean93/dpapi-ng

dpapi-ng

Python DPAPI NG Decryptor for non-Windows Platforms

Ver Repositorio
716hace 1 añoRevisado por Kitploit

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

dpapi_ng - Biblioteca de des-/cifrado DPAPI-NG para Python

Test workflow codecov PyPI version License

Biblioteca para el des-/cifrado de DPAPI NG, también conocido como CNG DPAPI, en Python. Está diseñada para replicar el comportamiento de NCryptUnprotectSecret y NCryptProtectSecret. Puede utilizarse en hosts que no sean Windows para des-/cifrar secretos protegidos por DPAPI NG, como la contraseña protegida por usuario de un PFX o la contraseña cifrada de LAPS. Puede descifrar cualquier blob de DPAPI NG usando una copia offline de la clave raíz del dominio, o des-/cifrar usando las credenciales del usuario suministrado para recuperar la información necesaria a través de RPC.

Actualmente solo se admiten estos descriptores de protección:

TipoPropósito
SIDSolo el usuario del SID o los miembros del grupo del SID pueden descifrar el secreto

Esto implementa el Protocolo de distribución de claves de grupo MS-GKDI.

Requisitos

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

Cómo Instalar

Para instalar dpapi-ng con todas las funciones básicas, ejecute

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

Autenticación Kerberos

El soporte de autenticación Kerberos no se instalará por defecto, ya que depende de bibliotecas del sistema y de que haya un compilador válido presente. La biblioteca krb5 y el compilador se pueden instalar instalando estos paquetes:

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

Una vez instalados, los extras de Python para Kerberos se pueden instalar con

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

Kerberos también debe configurarse para comunicarse con el dominio, pero eso está fuera del alcance de esta página.

Desde el Código Fuente

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

Ejemplos

Hay una API síncrona y otra asyncio disponibles para des-/cifrar un blob.

root@kitploit:~
import dpapi_ng


### DECRYPTION ###
dpapi_ng_blob = b"..."
decrypted_blob = dpapi_ng.ncrypt_unprotect_secret(dpapi_ng_blob)

# async equivalent to the above
decrypted_blob = await dpapi_ng.async_ncrypt_unprotect_secret(dpapi_ng_blob)


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

# async equivalent to the above
dpapi_ng_blob = await dpapi_ng.async_ncrypt_protect_secret(data, target_sid)

Para descifrar el blob, la clave especificada en el blob debe recuperarse del controlador de dominio que generó el blob. Para cifrar un blob, se debe recuperar la clave de grupo del SID objetivo especificado. Para el descifrado, el nombre de host del controlador de dominio se obtiene automáticamente mediante una consulta DNS SRV de _ldap._tcp.dc._msdcs.{domain_name} con el nombre de dominio encontrado en el blob DPAPI-NG o con el valor especificado en el kwarg server. Para el cifrado, el nombre de host del controlador de dominio se determina mediante el kwarg domain_name para una consulta DNS SRV, el kwarg server directamente, o usando el dominio de búsqueda del sistema (si está disponible). Intentará autenticarse con el identificador de usuario actual, que en Linux solo existirá si ya se ha llamado a kinit para obtener un ticket de usuario. De lo contrario, si no hay una identidad disponible, se pueden usar los kwargs username y password para especificar un usuario personalizado.

Los siguientes kwargs se pueden usar con ncrypt_unprotect_secret, async_ncrypt_unprotect_secret, ncrypt_protect_secret y async_ncrypt_protect_secret.

  • server: Usar este servidor como destino RPC si es necesario recuperar una clave
  • username: El nombre de usuario con el que autenticarse para la conexión RPC
  • password: La contraseña con la que autenticarse para la conexión RPC
  • auth_protocol: El protocolo de autenticación (negotiate, kerberos, ntlm) a usar para la conexión RPC
  • cache: Una caché para almacenar claves recuperadas para operaciones futuras

Además de eso, ncrypt_protect_secret y async_ncrypt_protect_secret aceptan el siguiente kwarg adicional.

  • domain_name: El nombre del dominio/forest a usar al buscar el destino RPC para recuperar la información de la clave
  • root_key_identifier: El UUID del identificador de la clave raíz, necesario para hacer que la caché funcione con estas funciones

También es posible cifrar y descifrar el blob DPAPI-NG proporcionando la clave raíz almacenada en el dominio. Esta se puede recuperar mediante un ataque offline o a través de una consulta LDAP si se ejecuta como usuario Domain Admin. Para recuperar las claves raíz del dominio usando PowerShell, se puede ejecutar lo siguiente:

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')
    }
}

El siguiente comando ldapsearch se puede usar fuera 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

Nota: lo más probable es que ldapsearch necesite la opción -H y la información de vinculación (bind) del usuario para tener éxito.

La información recuperada allí se puede almacenar en una caché y usarse para llamadas posteriores a ncrypt_protect_secret y 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)

Actualmente se ha probado que funcionan el algoritmo KDF SP800_108_CTR_HMAC y los algoritmos de acuerdo secreto DH, ECDH_P256 y ECDH_P384. El algoritmo de acuerdo secreto ECDH_P521 también debería funcionar, pero no ha sido probado ya que no se puede crear un entorno de prueba con él en este momento.

Agradecimientos Especiales

Me gustaría agradecer a las siguientes personas (sus handles de GitHub o Twitter entre paréntesis) por su ayuda en este proyecto:

  • Georg Sieber (@schorschii) por implementar el soporte de cifrado
  • Grzegorz Tworek (@0gtweet) y Michał Grzegorzewski por proporcionar más información sobre el flujo de trabajo interno de la API BCrypt* utilizado en DPAPI-NG
  • Marc-André Moreau (@awakecoding) por su ayuda con la ingeniería inversa de algunas de las API de Windows y por comentar algunas teorías
  • SkelSec (@SkelSec) por su ayuda con las llamadas RPC y por estar disponible como caja de resonancia general para mis teorías
  • Steve Syfuhs (@SteveSyfuhs) por ponerme en contacto con algunos ingenieros de Microsoft para ayudar a entender cierta lógica no documentada

Sin su paciencia y conocimiento, esto probablemente no habría sido posible.

Descargar herramienta