Active Directoryを探ってみる

MicrosoftのTechNetを見て自分なりに頭の中を整理した・・・つもりなんだけどやっぱり実際のパケットの流れを見ないと解らないところもあります。
今回は、ドメインに参加したPCにログオンする際、Windowsサーバがどのような挙動をしているか、パケットからその動きを追ってみました。

# ドメインPCログオンの流れ
ドメインに参加しているPCを起動し、ログオンする際のおおまかな流れです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/107228/e5122a67-eb25-3276-186f-081bac594efe.png)


## 1. DNS問い合わせ・応答
1. PCが起動すると、DNSサーバに登録されたLDAPサーバレコード(SRV)を検索します。
（例）nmr.localドメインに参加している場合
![image.png](https://qiita-image-store.s3.amazonaws.com/0/107228/a58d9435-f8d2-4286-fe31-5eba946c95c6.png)


2. 複数のドメインコントローラーがある場合、それらのレコードが全て返されます。
（例）nmr-dcとnmr-dc3というドメインコントローラがある場合
![image.png](https://qiita-image-store.s3.amazonaws.com/0/107228/ba50c815-64e6-607e-4331-b2225d31ab41.png)



## 2. LDAP問い合わせ・応答
1. CLDAP（LDAPのUDP版）にてコンピュータ（起動したPC）オブジェクトをドメインコントローラーから検索します。「LDAP Ping」と言うようです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/107228/1d771ed7-959e-5a88-236c-33f1dcc23876.png)

2. 検索に成功した場合、ドメインコントローラーは検索成功フラグをPCに返します。返したパケットにはドメインコントローラーの情報も含まれます。主に以下のような情報が含まれます。
  - Time Serviceが稼働しているか
  - ドメインコントローラーの時刻はKerberos認証が可能な時刻範囲内か
  - Kerberosをサポートしているか
  - LDAPをサポートしているか
  - プライマリドメインコントローラーか etc...
![image.png](https://qiita-image-store.s3.amazonaws.com/0/107228/6560c853-f9fb-67f3-5618-e7dc229e581d.png)

## 3. セキュアチャネルの確立
PCとドメインコントローラーとの間でセキュリティで保護されたチャネルを確立します。このチャネルを使用して、パスワード等のAD関連情報のやり取りを行います。

1. MS-RPCを使用してポートマッピングを行います。ポートマップリクエストを出すと、ドメインコントローラーからマッピングされたポート番号が返ってきます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/107228/d9250237-c93f-8ff6-c20b-44c79577cd5d.png)
2. GSS-APIを使用してドメインコントローラーとネゴシエーションを行い暗号化用の情報を交換します。GSS-API、SPNEGO、Kerberos v5の関係については長くなりそうなので別の回で。。。実はこの前に、Kerberos認証を行っておりその認証基盤を使ってGSS-APIを使っています。立て込んできそうなので、こちらも詳細は別の回で。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/107228/b468cf46-810b-a434-071a-3cd6619e12e7.png)
3. 情報交換完了後、SPNEGOという認証方式を使用して、必要な情報を取得します。情報取得にはDSCrackNamesを使います。なお、SPNEGOの通信内は暗号化されているのでパケットを取得しても何やっているかはわかりません。。。ポリシーのロード等でしょうか。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/107228/153ee009-15f7-8777-6299-ff6635e6f641.png)
4. DSCrackNameによる情報取得の後、DsWriteAccountSpnを使用してPCのSPNをサーバに登録します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/107228/0e76ac94-5a16-22a0-ab1b-561bdc2dd1a9.png)
5. 2～4まではSPNEGOという認証方式を使用しましたが、ここは使いません。NetrServerReqChallengeによるPCとサーバのチャレンジレスポンス認証を行います。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/107228/e5b9d9fe-659c-95f5-4952-8c888255af70.png)
6. チャレンジレスポンス認証完了後、以降のセキュアチャネルに使用するセッションキーの認証をPCとサーバ相互にNetrServerAuthenticate3を使用して行います。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/107228/780b2346-b90d-7a74-ea26-e695f8f79652.png)
7. ここでようやくセキュアチャネルを確立し、NetrLogonGetDomainInfoを使ってドメインコントローラー関連の情報を取得します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/107228/92e9c3c9-76df-363f-6e0f-62048d19d707.png)

本当はセキュアチャネル確立前にSASLとかあったんだけれど、気力が続かなくなったのでとりあえずここまで。。。

## 4. Kerberos認証
PCが起動すると、自身のコンピュータアカウントをKDCに問い合わせ、サービス用チケットを取得します。チケットの問い合わせ元はコンピュータアカウントになります。<br>
（例）nmr-cli10-01というコンピュータアカウントの場合
![image.png](https://qiita-image-store.s3.amazonaws.com/0/107228/254ad824-03a9-4ff4-1e74-cc50adca329e.png)

### コンピュータアカウント認証（TGT）
Kerberos認証では、最初にTGT(Ticket Granting Ticket)というチケット発行の大元となるチケットがKDCより配布されます。ここでは、TGT取得の流れを説明します。

1. 【AS-REQ】最初に事前認証を行います。事前認証はKerberosプロトコルの「PA(Pre-Authentication)-DATA」フィールドに必要な認証情報が保存されます。事前認証の際、PA-DATAフィールドに「PA-PAC(Privilege Attribute Certificate)-REQUEST」という事前認証要求命令を保存し、KDCに送ります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/107228/5550ab85-aed6-c55e-f80b-6ebe1a0cf0bf.png)

2. 【ERR-PREAUTH-REQUIRED】通常、PA-PAC-REQUESTを受け取ると、KDCはエラーを返します。これは、PA-DATAつまり事前認証情報が空っぽなためです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/107228/7cc05622-2708-44d4-6b10-e0d489899c71.png)

3. 【AS-REQ】エラーを受け取ったPCはPA-DATAに「PA-ENC-TIMESTAMP」という時刻同期による事前認証方式を使用して、KDCに再度認証を要求します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/107228/c65ae38d-964a-d856-a87c-d3ec68c8b099.png)

4. 【AS-REP】KDCはチケット認証チケットであるkrbtgtをPCに返します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/107228/6f3316b8-f048-79d8-fee5-abc8e0c964b5.png)


### コンピュータアカウント認証（TGS）
TGTを受け取ったPCは、TGTを使用してサービス用のチケットを取得します。

1. 【TGS-REQ】取得したいサービス名を指定してKDCにチケットを要求します。リクエスト要求のSNAMEフィールドにサービス名の指定をします。<br>
（例）LDAP用のサービスチケットを取得したい場合
 ![image.png](https://qiita-image-store.s3.amazonaws.com/0/107228/17eb7b9e-5f36-8217-a0d6-8be359bcc311.png)
2. 【TGS-REP】KDCがサービス用チケットをPCに返します。<br>
（例）LDAP用のサービスチケットを返す場合
![image.png](https://qiita-image-store.s3.amazonaws.com/0/107228/b16d653f-f2ae-3e6b-e88c-8b00a2a40d86.png)
3. 上記1および2のTGS取得を、以下のサービスについてそれぞれ実施します。
 - LDAP
 - 自分のコンピュータアカウント
 - CIFS


### ユーザアカウント認証（TGS）
コンピュータアカウントの認証完了後、ユーザアカウントのKerberos認証を行います。認証方法はコンピュータアカウントの時と同じです。異なるのは下図のようにチケットの要求元がユーザアカウントになっている点です。<br>
（例）nmropeというユーザアカウントの場合
![image.png](https://qiita-image-store.s3.amazonaws.com/0/107228/9794ab9c-cb33-e033-699e-c26aa38509a2.png)

TGTの取得方法は同じなので省略します。サービスチケットとしては、以下を取得します。

 - ログオンホスト
 下図で示すNT-SRV-HSTがログオンホストになります。
 ![image.png](https://qiita-image-store.s3.amazonaws.com/0/107228/3b9aca84-cffc-7541-353f-e7fde1eed854.png)

 - LDAP

パケット見ながらなんとなく追っかけてみましが、そろそろ気力が尽きそう。
次回はもう少し詳しくやります。

# 参考リンク
 - https://technet.microsoft.com/en-us/library/cc772815(v=ws.10).aspx
 - https://blogs.technet.microsoft.com/makeiteasy/2013/01/14/kdc_err_preauth_required-vs-kdc_err_preauth_failed/
 - https://www.ipa.go.jp/security/rfc/RFC1510-09JA.html
 - http://crypto-protocol.nict.go.jp/AKE_zoo/Kerberos-preauth/Kerberos-preauth_Abstract.pdf
 - https://www.ibm.com/support/knowledgecenter/ja/SS9H2Y_7.1.0/com.ibm.dp.doc/spnego_protocol.html
 - https://technet.microsoft.com/ja-jp/library/bb742590.aspx