LDAP と AD セキュリティ記述子
LDAP は AD オブジェクトの検索や属性変更に使われます。Impacket では用途に よって 2 つのクライアント を使い分けます。コードを追うときは、まず 対象コマンドがどちらを呼ぶか確認してください。属性変更の意味や LDIF の例は LDAP の変更操作にまとめています。
| 実装 | 使うコマンド | 向いている操作 |
|---|---|---|
impacket.ldap.LDAPConnection | GetADUsers、GetUserSPNs、GetNPUsers、GetLAPSPassword、findDelegation など | bind、search、簡単な modify |
ldap3 (init_ldap_session) | dacledit、owneredit、rbcd、badsuccessor、addcomputer の LDAPS 経路 | SD control 付きの変更、複雑な modify |
ASN.1 は ldapasn1.py (RFC 4511)。
AD の security descriptor は ldaptypes.py。
拡張権限 GUID は msada_guids.py。
impacket/acl.py は AD ではありません。
SMB ファイルの FileSecInformation と LSARPC による SID 解決です。
nTSecurityDescriptor を触るときは ldaptypes を使います。
URL と接続
Section titled “URL と接続”LDAPConnection(url, baseDN='', dstIp=None, signing=True, timeout=None):
| scheme | ポート | signing 既定 | TLS |
|---|---|---|---|
ldap:// | 389 | オン | 無し |
ldaps:// | 636 | オフ (チャネル自体が TLS) | pyOpenSSL TLS_METHOD |
gc:// | 3268 | オフ | 無し (Global Catalog) |
dstIp は接続先だけを上書きし、Kerberos SPN ldap/<url のホスト> は
名前側を使います。
LDAPS の channel binding は RFC 5929 tls-server-end-point: + ピア証明書の
SHA-256 を構造体に載せ、その MD5 を channel_binding_value にします。
NTLM Type3 の AV_CHANNEL_BINDINGS と、Kerberos AP-REQ の CheckSumField.Bnd
がこれを消費します。CBT 必須の DC では、これを付けないと bind が失敗します。
検査コマンドは CheckLDAPStatus。
login(..., authenticationChoice='sasl'):
| choice | 中身 |
|---|---|
simple | user@domain または DOMAIN\user + password |
sicilyNegotiate | Sicily NTLM (Type1 in negotiate、Type3 in response) |
sasl (既定) | GSS-SPNEGO + NTLMv2。Type3 に MIC を付ける。signing 時は SPNEGOCipher |
kerberosLogin():
CCache.parseFileでldap/<host>を探す- 無ければ
getKerberosTGT→getKerberosTGS - SPNEGO + AP-REQ。checksum
0x8003。signing なら CONF|INTEG、 LDAPS ならBndに CBT - BindRequest SASL
GSS-SPNEGO
signing 有効後の send() は 4 byte 長 + wrap です。Kerberos は
GSS_Wrap_LDAP、NTLM は SPNEGOCipher.encrypt。recv_raw() が復号します。
ldap3 経路 (impacket.examples.utils.init_ldap_session) は
NTLM/Kerberos を ldap3 の SASL に渡し、modify 時の
security_descriptor_control を使います。dacledit 系はこちらです。
Search / modify
Section titled “Search / modify”LDAPConnection.search の既定は wholeSubtree、neverDerefAliases。
フィルタは RFC 4515 (& | !、=、>=、<=、:=、*、\XX)。
ページングは control OID 1.2.840.113556.1.4.319
(SimplePagedResultsControl、既定 size 1000)。サーバ cookie を空になるまで
回します。大きいドメインで -stealth のようにフィルタを外すと、
ページング無しでは切り詰められます。
modify 操作定数: ADD=0、DELETE=1、REPLACE=2、INCREMENT=3。
SD を触るときは control OID 1.2.840.113556.1.4.801 (SDFlagsControl)。
flag: OWNER=1、GROUP=2、DACL=4、SACL=8。dacledit の read は DACL のみ
(0x04) が多いです。
セキュリティ記述子
Section titled “セキュリティ記述子”[MS-DTYP] 2.4.6 の self-relative SD です。
SR_SECURITY_DESCRIPTOR Revision, Control OffsetOwner / OffsetGroup / OffsetSacl / OffsetDacl OwnerSid, GroupSid, Sacl, DaclACL AceCount + ACE[]ACE AceType, AceFlags, AceSize + bodyよく使う ACE:
| AceType | クラス | 用途 |
|---|---|---|
| 0x00 | ACCESS_ALLOWED_ACE | 通常許可。RBCD の SID 列挙もこれ |
| 0x01 | ACCESS_DENIED_ACE | 拒否 |
| 0x05 | ACCESS_ALLOWED_OBJECT_ACE | object GUID 付き。DCSync / ResetPassword |
| 0x06 | ACCESS_DENIED_OBJECT_ACE | object 拒否 |
object ACE は ACE_OBJECT_TYPE_PRESENT / INHERITED_OBJECT_TYPE_PRESENT と
GUID の組み合わせが意味を持ちます。SID が同じだから消してよい、ではありません。
代表的な mask:
| 名前 | 値 | 意味 |
|---|---|---|
WRITE_DACL | 0x40000 | DACL 変更 |
WRITE_OWNER | 0x80000 | owner 変更 |
READ_CONTROL | 0x20000 | SD 読み取り |
ADS_RIGHT_DS_CONTROL_ACCESS | 0x100 | 拡張権限 |
WRITE_PROP | 0x20 | 属性書き込み |
CREATE_CHILD / DELETE_CHILD | 0x1 / 0x2 | 子オブジェクト |
msada_guids.EXTENDED_RIGHTS の例:
00299570-246d-11d0-a768-00aa006e0529— User-Force-Change-Password1131f6aa-9c07-11d1-f79f-00c04fc2dcd2— DS-Replication-Get-Changes1131f6ad-9c07-11d1-f79f-00c04fc2dcd2— Get-Changes-All (DCSync の片側)ab721a53-1e2f-11d0-9819-00aa0040529b— User-Change-Password
RECALC_ACE_SIZE (既定 True) は再シリアライズ時に ACE サイズを計算し直します。
AD が持っていたパディングとずれることがあるので、backup/restore は
元の binary blob を保持します (dacledit の JSON backup)。
コマンドとの対応
Section titled “コマンドとの対応”| 操作 | 属性 / 対象 | コマンド |
|---|---|---|
| DACL 編集 | nTSecurityDescriptor | dacledit |
| owner 変更 | SD Owner | owneredit |
| RBCD | msDS-AllowedToActOnBehalfOfOtherIdentity (中身は SD) | rbcd |
| 委任列挙 | UAC、msDS-AllowedToDelegateTo など | findDelegation |
| LAPS | ms-Mcs-AdmPwd / Windows LAPS + GKDI | GetLAPSPassword |
| dMSA | delegated MSA 属性 | badsuccessor |
RBCD の値は SID 配列ではなく self-relative SD です。create_allow_ace
の mask は 983551 (フルコントロール相当)。flush は属性全体を空にし、
remove は指定 SID の ACE だけを除きます。
変更時の確認
Section titled “変更時の確認”LDAPConnectionとldap3のどちらを直すかを先に決める- SD control 無しで
nTSecurityDescriptorを読むと欠ける - ACE 順序、未知 ACE、inheritance flag を round-trip で失わない
- 関連テスト:
tests/SMB_RPC/test_ldap.py

