Impacket GetLAPSPassword.py
LDAP から従来の LAPS と Windows LAPS の属性を読み取ります。暗号化された Windows LAPS のパスワードは GKDI 鍵を取得して復号します。
| 項目 | 内容 |
|---|---|
| 実装 | examples/GetLAPSPassword.py |
| カテゴリ | Active Directory / LDAP / アカウント管理 |
| 規模 | 299 行 |
| 配布 | setup.py の scripts=examples/*.py によりスクリプトとしてインストール |
CLI と入力
Section titled “CLI と入力”オプションの最新の定義は python examples/GetLAPSPassword.py -h で確認できます。
| 引数 | 説明 |
|---|---|
target | domain[/username[:password]] |
-computer | Target a specific computer by its name |
-ts | Adds timestamp to every logging output |
-debug | Turn DEBUG output ON |
-outputfile / -o | Outputs to a file. |
-hashes | NTLM hashes, format is LMHASH:NTHASH |
-no-pass | don’t ask for password (useful for -k) |
-k | Use Kerberos authentication. Grabs credentials from ccache file (KRB5CcnAME) based on target parameters. If valid credentials cannot be found, it will use the ones specified in the command line |
-aesKey | AES key to use for Kerberos Authentication (128 or 256 bits) |
-dc-ip | IP Address of the domain controller. If ommited it use the domain part (FQDN) specified in the target parameter |
-dc-host | Hostname of the domain controller to use. If ommited, the domain part (FQDN) specified in the account parameter will be used |
-ldaps / -use-ldaps | Use LDAPS instead of LDAP |
関連技術: LDAP、DPAPI / SAM / LSA / NTDS の DPAPI-NG / GKDI。
詳細な処理フロー
Section titled “詳細な処理フロー”LDAP で computer object と LAPS 属性を検索し、平文属性はそのまま整形します。暗号化属性では CMS blob を ASN.1 decode し、RPC Endpoint Mapper 経由で GKDI に接続、group key から KEK/CEK を導出して DPAPI-NG payload を復号します。結果は表または -o のファイルへ出力します。
仕組みの詳細
Section titled “仕組みの詳細”legacy LAPS と Windows LAPS では、LDAP から得る値の性質が異なります。legacy
LAPS の属性は読み取り権限があれば password value を直接返します。一方、
Windows LAPS の暗号化属性には CMS 形式の envelope と DPAPI-NG metadata が
入り、LDAP 検索だけでは平文になりません。run() はまず computer と属性を
列挙し、属性形式を見て平文経路と暗号化経路を分けます。
暗号化経路では EncryptedPasswordBlob と CMS ASN.1 を解析し、blob 内の
key identifier から必要な GKDI group key を特定します。その後 Endpoint
Mapper で GKDI RPC endpoint を見つけ、許可された呼び出し元として key
material を取得し、KDF で KEK を作り、wrapped CEK と ciphertext を順に
復号します。つまり「LDAP → ASN.1/CMS → GKDI RPC → DPAPI-NG」という複数の
protocol 境界をまたぐ処理です。
復号失敗は、属性を読めない、GKDI 呼び出し権限がない、key generation ID が
一致しない、blob が壊れている、のいずれでも起きます。getLAPSv2Decrypt()
ではこれらを一つの generic error にせず、どの段階まで成功したかが分かる
状態を保つと保守しやすくなります。出力 JSON/表には password だけでなく、
対象 computer と有効期限を対応付けて扱います。
主要な実装要素
Section titled “主要な実装要素”| シンボル | 位置 | 責務を追う入口 |
|---|---|---|
GetLAPSPassword | 41 | __init__()、printTable()、getLAPSv2Decrypt()、getUnixTime()、run() |
Impacket 内部
Section titled “Impacket 内部”| モジュール | 使用する主な名前 |
|---|---|
impacket | version |
impacket.dcerpc.v5 | transport |
impacket.dcerpc.v5.epm | hept_map |
impacket.dcerpc.v5.gkdi | GkdiGetKey, GroupKeyEnvelope, MSRPC_UUID_GKDI |
impacket.dcerpc.v5.rpcrt | RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, RPC_C_AUTHN_LEVEL_PKT_PRIVACY |
impacket.dpapi_ng | EncryptedPasswordBlob, KeyIdentifier, compute_kek, create_sd, decrypt_plaintext, unwrap_cek |
impacket.examples | logger |
impacket.examples.utils | ldap_login, parse_identity |
impacket.ldap | ldap, ldapasn1 |
外部パッケージ(直接使用)
Section titled “外部パッケージ(直接使用)”| import 名 | 配布パッケージ | 経路・宣言状態 |
|---|---|---|
pyasn1 | pyasn1 | 直接 import、宣言済み |
pyasn1_modules | pyasn1_modules | 直接 import、宣言済み |
出力・副作用・必要権限
Section titled “出力・副作用・必要権限”- 照会や認証の試行が中心です。実行回数が多いと監査ログやアカウントロック、対象の負荷に影響します。
- オプションによりローカルファイルを作成または更新します。既存ファイルの扱いと秘密情報を含む出力の権限を確認してください。
失敗経路と後始末
Section titled “失敗経路と後始末”- 失敗時は、名前解決、接続、認証、サービスの状態、権限のどこで止まったかを、プロトコルのステータスから切り分けます。
実装を変更するとき
Section titled “実装を変更するとき”ldap / ldapasn1、dcerpc.v5.gkdi、dpapi_ng、pyasn1、pyasn1_modules.rfc5652 を使用します。getLAPSv2Decrypt() は LDAP と RPC の境界なので、暗号形式変更時の中心です。
- 構文:
python -m py_compile examples/GetLAPSPassword.py - CLI:
python examples/GetLAPSPassword.py -h - 関連テスト:
tests/SMB_RPC/test_ldap.py - 関連テスト:
tests/SMB_RPC/test_rpcrt.py - 関連テスト:
tests/dcerpc/test_epm.py - 関連テスト:
tests/misc/test_dcerpc_v5_ndr.py

