コンテンツにスキップ

技術目次へ戻る

Windows の秘密情報は、SAM や LSA、NTDS、DPAPI など保存場所と保護方法が 異なります。ここでは Impacket が材料をどこから取得し、どの実装で復号するかを 追います。端末上で資格情報がどこに残るかは Windows の資格情報の解説を参照してください。

秘密情報は「取得経路」と「復号器」が分かれています。CLI は secretsdump がオーケストレーション、 実復号は impacket/examples/secretsdump.py です。DPAPI 単体は dpapi.py / dpapi_ng.py と dpapi コマンド です。

新しい取得方法 (VSS、WMI shadow、Key List) は decoder の中に埋め込まず、 同じ raw record 契約へ接続します。

LocalOperations.getBootKey() / RemoteOperations の同等処理:

  1. Select\Current から ControlSet00N を決める
  2. Control\Lsa\{JD,Skew1,GBG,Data} の クラス名 (UTF-16 hex 16 文字) を連結
  3. 並べ替え [8,5,4,2,11,9,13,3,0,6,1,12,14,10,15,7]

.reg テキストにはクラス名が無いので boot key を計算できません。 secretsdump -system が binary REGF を要求するのはこのためです。

NoLmHash ポリシーは同じ ControlSet の Control\Lsa\NoLmHash です。

SAMHashes が SAM\Domains\Account を読みます。

  • ドメイン鍵は F 値 (DOMAIN_ACCOUNT_F)。古い RC4 (SAM_KEY_DATA) と AES (SAM_KEY_DATA_AES) がある。RC4 経路の定数文字列は !@#$%^&*()qwerty... と 0123456789012345678901234567890123456789
  • ユーザは RID キー配下の V (USER_ACCOUNT_V)。hash は RID から CryptoCommon.deriveKey で作った 2 つの DES 鍵、または AES で保護される
  • SamDecryptNTLMHash / transformKey は crypto.py ([MS-SAMR] 2.2.11.1.1)

出力は domain\user:rid:lmhash:nthash::: です。history は別エントリです。

LSA secrets とキャッシュログオン

Section titled “LSA secrets とキャッシュログオン”

LSASecrets は SECURITY hive を boot key で開きます。

  • 古いホスト: PolSecretEncryptionKey
  • 新しいホスト: PolEKList (AES)
  • Policy\Secrets\*\CurrVal (LSA_SECRET / LSA_SECRET_XP)。 _SC_* (サービス password)、$MACHINE.ACC、DPAPI_SYSTEM、 NL$KM などがここに入る
  • cached logon は Cache の NL_RECORD。NL$KM で復号。Vista 以降は DCC2 (NL$IterationCount)

regsecrets は NTDS を触らず、この SAM + LSA 経路だけを remote registry から取ります。

NTDSHashes は 2 通りの入力を同じ論理レコードへ正規化します。

経路材料特徴
ESE (-ntds / VSS)ntds.ditese.py でテーブルを読む
DRSUAPIIDL_DRSGetNCChangesファイルをコピーしない。resume file で cursor を保持
Key ListRODC krbtgt AES + KERB_KEY_LIST_REQ許可されたアカウントの長期鍵

PEK (Password Encryption Key) は boot key で保護されています。 pekList の先頭で世代が分かれます。

ヘッダOS 目安解き方
\x02...2012 R2 以前MD5(bootkey + KeyMaterial を 1000 回) + RC4 → PEK 列
\x03...2016 以降AES(bootKey, IV=KeyMaterial) → (index, 16-byte PEK)*

各アカウントの NT/LM hash は PEK 層 (RC4。header 8–10 byte が PEK index) を剥がしたあと、RID 由来 DES をもう一段外します。2016 以降の一部は AES です。supplementalCredentials には Kerberos AES/DES key、WDigest、 平文 password が入ることがあります。trust は TDO の auth info から inter-realm 鍵 (AES + RC4) を導出します (-trust-keys)。 AES 導出は FQDN salt {REALM_FQDN}krbtgt{PARTNER_FQDN} に加え、 NetBIOS/flat 名が分かるときはその flat 名で (trust account) 鍵も出します。 flat 名が無いときは DNS ラベルから推測せず、trust-account 鍵を省略します。

DRSUAPI は属性 ID 単位で来るため、欠落属性を「hash が空」と決めつけない ことが必要です。-just-dc-user / -ldapfilter / -skip-user は取得と 出力の両方に効きます。

パスワードが直接すべての secret を守るのではなく、master key が中間に入ります。

構造ファイル / 場所復号に使うもの
MasterKeyFile / MasterKeyProtect\<SID>\GUIDSID+password、NT/SHA1、DPAPI_SYSTEM、domain PVK
DPAPI_BLOBCredential、Vault 属性、汎用 blobmaster key の SHA1 など
CREDHIST_FILECREDHIST過去の user key チェーン
VAULT_VPOL / VAULT_VCRDPolicy / Credentialvpol の Vault key → vcrd 属性
PREFERRED_BACKUP_KEYLSA / BKRPdomain RSA backup key
DPAPI_SYSTEMLSA secretマシン / ユーザ machine key

deriveKeysFromUser(sid, password) は 3 候補を出します。

  1. HMAC-SHA1(SHA1(UTF-16 password), SID+\0)
  2. HMAC-SHA1(MD4(UTF-16 password), SID+\0) — NT hash 経路
  3. Protected Users 用 PBKDF2-SHA256 2 段 + HMAC-SHA1

GUID で blob と master key を対応付けます。MAC が合わない平文候補は 成功として出しません。

Windows LAPS / DPAPI-NG は dpapi_ng.py と GKDI (GkdiGetKey) です。流れは次です。

  1. LDAP の暗号化属性 → EncryptedPasswordBlob + KeyIdentifier (root key id、L0/L1/L2)
  2. 対象 SID の SD を付けて GKDI RPC
  3. GroupKeyEnvelope から KEK (FFC DH または ECDH、SP 800-108)
  4. AES unwrap で CEK、その CEK で password を復号

GetLAPSPassword が この境界 (LDAP → CMS → GKDI → DPAPI-NG) を跨ぎます。legacy LAPS の ms-Mcs-AdmPwd は平文属性なので GKDI は使いません。

domain backup key は dcerpc.v5.bkrp で remote 取得できます (dpapi.py backupkeys)。PVK / PKCS#1 への変換は privatekeyblob_to_pkcs1 です。

RemoteOperations が材料を集めます。

方法何をするか副作用
Remote Registryhive を save一時ファイル
VSS / ntdsutilsnapshotサービス・shadow
WMI shadow (-use-remoteSSWMI)遠隔 snapshot から SAM/SYSTEM/SECURITY(/NTDS) をダウンロードsnapshot
DRSUAPI複製DC 負荷、replication 監査
Key ListRODC 番号 + AESKerberos 監査

cleanup() はサービス、一時ファイル、resume 状態を例外経路でも回収します。

  • boot key のクラス名読みと並べ替えを崩さない
  • AES と RC4 の SAM/LSA/PEK 形式を片方の仮定で読まない
  • 出力スキーマ (SAM / cached / ntds / trust) を混ぜない
  • debug ログに復号済み hash / key を足さない
  • 関連テスト: tests/SMB_RPC/test_secretsdump.py