Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
dpapi-ng — Python DPAPI NG Decryptor for non-Windows Platforms | Kitploit
Инструменты/GitHubGitHub/jborean93/dpapi-ng
Encryption/Decryption ToolsDigital ForensicsCryptographyAuthenticationRed Teaming
GitHubjborean93/dpapi-ng

dpapi-ng

Python DPAPI NG Decryptor for non-Windows Platforms

Репозиторий
7161 год назадПроверено Kitploit

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

dpapi_ng — библиотека Python для де-/зашифрования DPAPI-NG

Test workflow codecov PyPI version License

Библиотека для де-/зашифрования DPAPI NG, также известного как CNG DPAPI, в Python. Она предназначена для воспроизведения поведения функций NCryptUnprotectSecret и NCryptProtectSecret. Её можно использовать на хостах, отличных от Windows, для де-/зашифрования защищённых секретов DPAPI NG, таких как защищённый пароль PFX-пользователя или зашифрованный пароль LAPS. Она может либо расшифровать любые BLOB-объекты DPAPI NG с помощью автономной копии корневого ключа домена, либо де-/зашифровать их, используя учётные данные указанного пользователя для получения необходимой информации по RPC.

В настоящее время поддерживаются только следующие дескрипторы защиты:

ТипНазначение
SIDРасшифровать секрет может только пользователь SID или члены группы SID

Данная библиотека реализует протокол распространения групповых ключей MS-GKDI.

Требования

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

Как установить

Чтобы установить dpapi-ng со всеми базовыми возможностями, выполните

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

Аутентификация Kerberos

Поддержка аутентификации Kerberos не устанавливается по умолчанию, поскольку она зависит от наличия системных библиотек и рабочего компилятора. Библиотеку krb5 и компилятор можно установить, установив следующие пакеты:

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

После установки дополнительные зависимости Kerberos для Python можно установить с помощью

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

Kerberos также необходимо настроить для взаимодействия с доменом, но это выходит за рамки данной страницы.

Из исходного кода

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

Примеры

Для де-/зашифрования BLOB-объекта доступен как синхронный, так и асинхронный API (asyncio).

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)

Чтобы расшифровать BLOB-объект, необходимо получить ключ, указанный в BLOB-объекте, от контроллера домена, который создал этот BLOB-объект. Чтобы зашифровать BLOB-объект, необходимо получить групповой ключ указанного целевого SID. Для расшифрования имя хоста контроллера домена автоматически определяется с помощью DNS-запроса SRV для _ldap._tcp.dc._msdcs.{domain_name}, где имя домена берётся из BLOB-объекта DPAPI-NG или из значения, указанного в аргументе server. Для зашифрования имя хоста контроллера домена определяется либо с помощью аргумента domain_name для DNS-запроса SRV, либо напрямую через аргумент server, либо с использованием поискового домена системы (если он доступен). Будет предпринята попытка аутентификации с использованием идентификатора текущего пользователя, который в Linux существует только в том случае, если для получения билета пользователя уже был вызван kinit. Если же идентификатор недоступен, для указания другого пользователя можно использовать аргументы username и password.

Следующие аргументы можно использовать для ncrypt_unprotect_secret, async_ncrypt_unprotect_secret, ncrypt_protect_secret и async_ncrypt_protect_secret.

  • server: используйте этот сервер в качестве цели RPC, если необходимо получить ключ
  • username: имя пользователя для аутентификации при RPC-подключении
  • password: пароль для аутентификации при RPC-подключении
  • auth_protocol: протокол аутентификации (negotiate, kerberos, ntlm), используемый для RPC-подключения
  • cache: кэш для хранения полученных ключей для последующих операций

Кроме того, ncrypt_protect_secret и async_ncrypt_protect_secret принимают следующий дополнительный аргумент.

  • domain_name: имя домена/леса, используемое при поиске цели RPC для получения информации о ключе
  • root_key_identifier: UUID идентификатора корневого ключа, необходимый для работы кэша с этими функциями

Также можно зашифровать и расшифровать BLOB-объект DPAPI-NG, указав корневой ключ, хранящийся в домене. Его можно получить либо с помощью автономной атаки, либо через LDAP-запрос, если вы работаете от имени администратора домена. Чтобы получить корневые ключи домена с помощью PowerShell, можно выполнить следующее:

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

Следующую команду ldapsearch можно использовать за пределами 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

Примечание: для успешного выполнения ldapsearch, скорее всего, потребуются параметр -H и информация о привязке пользователя.

Полученную информацию можно сохранить в кэше и использовать для последующих вызовов ncrypt_protect_secret и 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)

В настоящее время проверены на работоспособность алгоритм KDF SP800_108_CTR_HMAC и алгоритмы согласования ключей DH, ECDH_P256 и ECDH_P384. Алгоритм согласования ключей ECDH_P521 также должен работать, но он не тестировался, поскольку сейчас для него невозможно создать тестовую среду.

Особая благодарность

Я хотел бы поблагодарить следующих людей (указаны ники GitHub или Twitter в скобках) за их помощь в этом проекте:

  • Георг Зибер (@schorschii) за реализацию поддержки шифрования
  • Гжегож Творек (@0gtweet) и Михал Гжегожевский за предоставление дополнительной информации о внутреннем процессе работы API BCrypt*, используемого в DPAPI-NG
  • Марк-Андре Моро (@awakecoding) за помощь в реверс-инжиниринге некоторых Windows API и обсуждение ряда теорий
  • SkelSec (@SkelSec) за помощь с RPC-вызовами и готовность быть собеседником при обсуждении моих теорий
  • Стив Сайфус (@SteveSyfuhs) за то, что связал меня с некоторыми инженерами Microsoft, чтобы помочь понять недокументированную логику

Без их терпения и знаний это, вероятно, было бы невозможно.

Скачать инструмент