Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
1 contributor

Users who have contributed to this file

190 lines (136 sloc) 10.7 KB

BIND メモリリーク脆弱性とRoot KSK Rollover

DNS温泉番外編2にて発表できなかったBINDのメモリリーク脆弱性の説明です。

脆弱性の概要

脆弱性の対象

権威サーバ、フルリゾルバのいずれでも対象になります。また、コンパイル時の設定(./configureのオプション)や実行時の設定(設定ファイル)では回避できません。

対象のバージョンは以下のとおりです。

  • 9.10.7 -> 9.10.8-P1
  • 9.11.3 -> 9.11.5-P1(ESV)
  • 9.12.0 -> 9.12.3-P1

対象Linuxディストリビューションは以下の通りです。

上記の通り、主にISCが配布しているソースからインストールしているサーバが対象になります。 また回避策は存在しないため、対象バージョンを使用中のサーバはすべて対象になります。

攻撃容易性

脆弱性の発見時において、Exploitの存在は確認されていません。しかし、メモリリークの原因は修正版のリリースノートに 原因が記載されていてかつ検証コードの作成は非常に容易なため、Exploitを欲しい人がいればすぐに出てくるでしょう。

しかし実際にこの脆弱性を利用してサービスを妨害することは容易ではありません。 数個のDNSクエリ程度ではサーバ上のメモリを使い切らせることはできず、対象のサーバのメモリ容量と同程度のDNSメッセージを送信する必要があります。 いわゆる”BINDころり”と呼ばれる脆弱性とは異なり、DNSパケットひとつでサービスを止めることはできず、パケットをばらまくことによる無差別攻撃は不可能です。 そして特定のDNSサーバを対象として攻撃する場合でも、攻撃側にも大きな帯域が必要でコストが嵩み、 それで得られる結果がメモリ消費によるDoSとなり攻撃側が得る利益が比較的小さいため、実際に利用する人は存在しないでしょう。

詳細(BIND 9.11.x)

BINDはOPTレコード内のオプションを、process_optにて処理します。 EDNS KeyTag Optionがある場合、関数 process_keytagを呼びますが、EDNS KeyTagオプションが複数ある場合、process_keytagも複数回呼ばれ、その際Key Tag用のメモリを確保済みかどうかを確認せずに、メモリを確保しポインタclient->keytagへ代入します。したがって、2度目以降のEDNS KeyTag Optionを処理する前に、以前に確保したメモリを開放することができなくなり、メモリリークします。

process_opt

static isc_result_t
process_opt(ns_client_t *client, dns_rdataset_t *opt) {

// snip

        case DNS_OPT_KEY_TAG:
				result = process_keytag(client, &optbuf,
							optlen);
				if (result != ISC_R_SUCCESS) {
					ns_client_error(client, result);
					return (result);
				}

process_keytag

static isc_result_t
process_keytag(ns_client_t *client, isc_buffer_t *buf, size_t optlen) {

	if (optlen == 0 || (optlen % 2) != 0) {
		isc_buffer_forward(buf, (unsigned int)optlen);
		return (DNS_R_OPTERR);
	}

	client->keytag = isc_mem_get(client->mctx, optlen);
	if (client->keytag != NULL) {
		client->keytag_len = (uint16_t)optlen;
		memmove(client->keytag, isc_buffer_current(buf), optlen);
	}
	isc_buffer_forward(buf, (unsigned int)optlen);
	return (ISC_R_SUCCESS);
}

対策

本脆弱性の対策はBINDのバージョンアップのみで、回避策はありません。

経緯

本脆弱性の対応の経緯は以下の通りです。当初はこの脆弱性についてJANOG 43のライトニングトークで発表しようと準備していましたが、 脆弱性公表が遅れたため申し込むことはできませんでした。次にDNS温泉番外編での発表を準備しましたが、 さらに脆弱性の公表が遅れ発表できませんでした。DNS温泉の発表資料にある"CVE-次作をお楽しみに" は本脆弱性のことです。 公表の遅れの原因は、本脆弱性と同時に対応しようとした別の脆弱性 (CVE-2018-5743: Limiting simultaneous TCP clients is ineffective) の対応に問題があり、修正版のリリースを取り消したためです。

  • 2018/12/09 脆弱性発見、即ISCへ報告
  • 2018/12/10 ISCから回答
    • 脆弱性を確認
    • 年末にシステムを更新しない組織があるため、公開は1月の上中旬の予定
  • 2018/12/13 脆弱性修正?
  • 2018/12/28 ISCより報告
    • 他の脆弱性の対応もあり、公開は1月の後半
  • 2019/01/15 BIND 9.11.5-P2/9.12.3-P2 ASNへ公開?
    • ftp.isc.org/isc/bind9/private の更新
  • 2019/01/23 更新後のBINDの不具合修正?
  • 2019/01/23-25 JANOG 43
  • 2019/01/29 BIND 9.11.5-P3/9.12.3-P3 ASNへ公開?
    • ftp.isc.org/isc/bind9/private の更新
  • 2019/01/24 更新後のBINDの不具合修正?
  • 2019/02/07 BIND 9.11.5-P4/9.12.3-P4 ASNへ公開?
    • ftp.isc.org/isc/bind9/private の更新
  • 2019/02/16 DNS温泉番外編
  • 2019/02/22 脆弱性公開

KeyTag Option(RFC 8145)

先に説明したとおり、KeyTag Optionを実装する際に本脆弱性が埋め込まれました。KeyTag OptionとはRFC8145にて定義された EDNSオプションで、昨年実施されたRoot KSK Rolloverの進行状況を踏査するために利用されるはずのものでした。

Root KSK Rolloverでは、Root Zoneを署名するためのZSKを署名する鍵であるのKSKを新規に作成し、既存のものと入れ替えます。 その際にDNSSEC Validator側でも新しいトラストアンカー(=KSKの公開鍵)を設定する必要があります。 もしKSK Rollover前に新しいトラストアンカーを設定していなければ、Rollover後そのValidatorでDNSSECの署名検証に失敗し、 名前解決もできなくなります。そこでKSK Rolloverの実施可否の判定材料として新しいトラストアンカーの設定の状況を観測するために、 RFC8145 Signaling Trust Anchor Knowledge in DNS Security Extensions (DNSSEC) が定義され、Validatorで実装されました。

RFC 8145では、設定されているトラストアンカーのKeyTagを権威サーバ(=Root Server)へ通知するため、 以下の2通りの方法を定義しています。

  • EDNSのOPTレコードに Key Tag option を追加
  • QNAMEに _ta-tagXXXXとKey Tagを含むクエリを送信

Open SourceなDNS Resolver/ValidatorのRFC 8145の実装状況は以下の通りになっています。

ただし、すべてQNAMEを使用した実装でEDNS KeyTag Optionは実装されませんでした。

一方BINDは、権威サーバ側の機能として受信したKeyTagの値をログへ出力する機能を実装しましたが、 前述の通りResolver/Validator側で実装されていないEDNS KeyTagオプションをパースする際にメモリリークする脆弱性を追加してしまいました。

Signaling Trust Anchor Knowledge による観測結果

Root KSK Rolloverの際のKey Tagの観測状況が公開されています。

60%

KSK Rollover 2015-2019(https://www.slideshare.net/apnic/ksk-rollover-20152019)より

しかし、結果としてあまり役に立たなかったようです。

60%

KSK Rollover 2015-2019(https://www.slideshare.net/apnic/ksk-rollover-20152019)より

役立たない理由は以下の通りです。

  • Signaling Trust Anchor Knowledgeは新しいvalidatorのみ実装されているため、古い実装の設定状況を観測できません
    • Linuxのディストリビューションのパッケージ等ではほとんど対応しておらず、対応Validatorはほとんど使用されていない可能性が高い
    • それでも対応Validatorを利用しているのは一部の管理者であり、古い実装を利用中の管理者と比較し、トラストアンカーを更新している可能性が高い
  • 過去のBINDにおいてDNSSEC Validationを無効化してもKey Tagを送信していたため、本来は調査する必要のない(Validatorでない)Resolverの状況も観測されていました Suppress trust-anchor-telementry queries if validation is disabled. [RT #46131]

まとめ

  • BINDはKeyTag Optionを実装した際に、メモリリークの脆弱性も追加されました
  • RFC 8145のKeyTag OptionはKSK Rolloverの状況を確認するために導入されてが、実際には利用されませんでした
  • RFC 8145のQNAMEによるKeyTagの通知は利用されましたが、その結果は役に立たなかったようです

さいごに

本脆弱性は

  • BIND
  • EDNS
  • DNSSEC
  • Root KSK Rollover

に関わるもので、これをDNS温泉番外編で発表できなかったことは非常に残念です。

You can’t perform that action at this time.