【実務・中級編】 ポート389番(LDAP)およびポート636番(LDAPS):ディレクトリサービスに対する資格情報侵害とドメインコントローラーへの攻撃 – サイバーセキュリティとプライバシー保護実践ガイド

「その389番、開けっ放しじゃないか?」——LDAP/LDAPSを狙う脅威と、現場で生き残るための防御術

ネットワークエンジニアとして現場を渡り歩いていると、いまだに「Active Directoryと連携するから」という理由だけで、何の疑問も抱かずにファイアウォールの穴(TCP/389)を全開放している現場に出くわすことがある。

正直に言おう。LDAPは、現代のインターネットに晒された環境では裸で歩いているようなものだ。

今日は、ディレクトリサービスの心臓部であるLDAP(389)とLDAPS(636)に焦点を当て、なぜこれが攻撃者の格好の標的になるのか、そして明日から君のインフラで何をすべきか、泥臭い実務の視点から解説する。

—

なぜ「平文のLDAP」が命取りになるのか

LDAP(Lightweight Directory Access Protocol)は、RFC 4511で定義される非常に効率的なプロトコルだが、設計思想が「認証のやり取りを暗号化する」ことを前提としていない。

もし、君のWeb APIや社内アプリが ldap:// で通信していたら、ネットワーク上の誰かがパケットキャプチャを仕掛けるだけで、ユーザー名とパスワード(あるいは認証トークン)が平文で筒抜けになる。さらに恐ろしいのは、認証後に送り出される「クエリ結果」だ。ディレクトリ内の構造やユーザー属性が丸見えになれば、攻撃者は次の「Kerberoasting」や「AS-REP Roasting」といった、ドメインコントローラー(DC)を陥落させるための宝探しを始める。

攻撃者が狙う「Kerberoasting」の罠

攻撃者はLDAPを使って、サービスアカウントの「SPN(Service Principal Name)」情報を収集する。これを取得できれば、DCに対して「そのサービスアカウントのTGS(チケット)をくれ」と要求できる。返ってきたチケットには、アカウントのパスワードハッシュが含まれている。これを持ち帰ってGPUでオフライン解析すれば、ドメイン管理者の特権奪取まで一直線だ。

—

現場で実装すべき「防御の三原則」

実務において、LDAP通信を安全にするための鉄則は以下の3つだ。

1. 強制的なLDAPS(TCP/636)への移行: 平文の389は物理的に遮断せよ。
2. LDAP署名とチャネルバインディングの有効化: これにより、中間者攻撃(MitM)を無効化する。
3. セグメンテーション: アプリサーバーとDCの間には、必ずステートフルなファイアウォールを置き、特定のIP以外からのアクセスを拒否せよ。

実践:LDAP接続を安全に記述する(Pythonでの例)

多くのエンジニアが使いがちな ldap3 ライブラリの例を見てみよう。平文の接続は即刻やめるべきだ。

from ldap3 import Server, Connection, Tls, ALL
import ssl

# 1. TLSの設定を明示する(重要)
tls_configuration = Tls(validate=ssl.CERT_REQUIRED, version=ssl.PROTOCOL_TLSv1_2)

# 2. LDAPS(636)を指定する
# IPではなくFQDNで指定し、証明書検証を行うこと
server = Server('ldaps://dc01.example.com', port=636, use_ssl=True, tls=tls_configuration, get_info=ALL)

# 3. 認証情報の取り扱いに注意(環境変数から読み込むのが定石)
import os
username = os.getenv('LDAP_USER')
password = os.getenv('LDAP_PASS')

conn = Connection(server, user=username, password=password, authentication='SIMPLE')

if not conn.bind():
    print(f"接続失敗: {conn.result}")
else:
    print("セキュアなLDAP接続を確立しました")

—

運用中に「攻撃の予兆」を検知するためのTips

攻撃者は、ブルートフォース(総当たり)のログを隠そうとするが、DCのイベントログには確実に爪痕が残る。以下のイベントIDを監視対象にするのは、セキュリティ担当の最低限の教養だ。

  • イベントID 4768: Kerberos TGT リクエスト(異常に多い場合は要注意)
  • イベントID 4769: Kerberos サービスチケットリクエスト(Kerberoastingの検知に不可欠)
  • イベントID 2886: LDAP署名が設定されていない警告(DC側で定期的に確認すること)

動作確認:curlでサーバーの「防御力」をチェックする

まずは自分の環境がセキュアかどうか、curlを使って STARTTLS が通るか確認してみよう。

# LDAPサーバーに対してSTARTTLSを要求し、暗号化されるか確認する
# 平文で通信が始まり、STARTTLSコマンドで暗号化へ移行する挙動を確認できる
curl -v ldap://dc01.example.com:389 --starttls

もしここで「接続が拒否される」のであれば、それは良い傾向だ。「何も答えず、パケットを捨てる」のが、最も堅牢な境界防御の姿だからだ。

—

最後に:エンジニアとしての矜持

「動けばいい」というコードや設定は、数年後に必ず自らの首を絞めることになる。特にディレクトリサービスは、一度侵害されると「ドメイン全体の降伏」を意味する。

LDAPの389番を開けっ放しにしているエンジニアがいたら、まずは「なぜTLSを使わないのか?」と問いかけてほしい。それが、君と君の組織を守るための、最初の一歩になるはずだ。

次は、ADCS(Active Directory Certificate Services)の悪用という、さらに深い闇について話そうか。また現場で会おう。

コメント

タイトルとURLをコピーしました