権威DNSサーバを作ってみよう
ゼロから始めるファジング生活

坂口 俊文
2018/06/27

自己紹介
坂口 俊文
• 4年前までは、ISPのメール・DNS…サーバの管理者• 現在はとあるクラウドサービスのサポート• 本日も個人参加• Twitter: @siskrn• GitHub: https://github.com/sischkg/

2

はじめに
本日は、最近開発・利用しているDNSフルリゾルバ専用のファジングツールについて発表します。
春のJANOG Interimの応募しようとしたが、間に合いませんでした。

3

動機
これまで
• 公開されたDNSサーバの脆弱性を検証• フルリゾルバの脆弱性を検証する場合は、特殊な応答を返す権威サーバを作成
課題• 権威サーバの作成を効率化• DNSSEC validation有効時のみ影響のある脆弱性にも対応
この課題の対応を検討中に、応答の自動生成によるフルリゾルバ専用のファジングツールの作成を思いつく
4

ファジングとは• バグや未知の脆弱性を検出するセキュリティテスト• 問題が起きそうな様々な細工をしたデータを送り、検査対象に異常な動作が起きないかどうかを検査• 問題を起こしそうなデータは、ファジングツールを使うと自動的に作成することができる

詳細
IPA : 情報セキュリティ :ファジング：FAQ
https://www.ipa.go.jp/security/vuln/fuzz_faq.html#001

5

ファジングツールの概要• 最初に権威サーバとして正規の応答を作成し、それを改変してからフルリゾルバへ送信する• 特殊な応答は乱数をもとに作成• フルリゾルバが異常終了（assert/segmentation fault)する不具合を探す• 毒入れなどは検知が困難なため、対象外とする権威サーバとして正規の応答を作成

改変

フルリゾルバ

権威サーバ
6

権威サーバの実装• DNSSECに対応（RRSetの署名/NSEC/NSEC3)• 完全な権威サーバを実装しない– ゾーンはひとつのみ– 以下の機能は未実装• ワイルドカード• NSEC3 Opt-out• TSIGなど

7ファジングの実装
過去の(BINDなどの)脆弱性を参考に実装• RRの追加・変更・削除– RRを追加• CNAME/DNAME– CVE-2017-3137(https://kb.isc.org/article/AA-01466/0/)
A response packet can cause a resolver to terminate when processing an answer containinga CNAME or DNAME• DNSSEC関連 (DNSKEY/RRSIG/DS/NSEC/NSEC3)– DNSSEC validation有効なときの脆弱性があったため– CVE-2017-15908(http://blog.trendmicro.co.jp/archives/16583)"Linux PC に対する DoS 攻撃が可能な「systemd」の脆弱性について解説"• TSIG, TKEYなどのRR– CVE-2016-9131(https://www.fortinet.com/blog/threat-research/analysis-of-isc-bind-tkey-query-response-handling-doscve-2016-9131.html)

Analysis of ISC BIND TKEY Query Response Handling DoS (CVE-2016-9131)• ドメイン名を乱数から自動生成8ファジングの実装– RRのクラスを変更• IN ⇒ CH/HS/NONE/ANY
CVE-2015-8000(https://kb.isc.org/article/AA-01317)
Responses with a malformed class attribute can trigger an assertion failure in db.c

– 乱数をもとに作成したTTL/TYPE/RDATA
未実装のRRに対応– OPT RR
• ペイロードサイズ、拡張RCODEを乱数から生成
CVE-2016-2848(https://kb.isc.org/article/AA-01317)
A packet with malformed options can trigger an assertion ...

• NSID, ECS, COOKIE, TCP-KEEPALIVEを追加• 乱数をもとに作成したOPTION
9ファジングの実装••

RCODEの変更
署名– ファジングで追加・変更したRRSetも署名– OPT, TSIG, RRSIGなども署名•

各セクションでのRRの順序変更•

DNSメッセージの変更– バイナリデータの追加・変更・削除

10ファジングの実装
クライアント（スタブリゾルバ）• 問い合わせの作成– QNAME
権威サーバ側のゾーンデータをもとに生成– QTYPE, QCLASS
乱数から生成– OPT
ペイロードサイズを乱数から生成• 問い合わせを一定間隔でフルリゾルバへ送信
フルリゾルバが異常終了するまで放置
11

例112

例213

調査対象
• フルリゾルバ– BIND 9.12.x, 9.7.x(CentOS 6.x RPM)
– Unbound– PowerDNS 3.x, 4.x– Knot Resolver• ついでに– dnsmasq– dnsdist– coredns

14

調査対象

BIND 9.12.x
BIND 9.7.x

PowerDNS
Recursor 3.x
PowerDNS
Recursor 4.x
fuzz_server

Knot Resolver

fuzz_client

Unbound

Unbounddnsmasq

Unboundcoredns

Unbounddnsdist15

脆弱性発見後の対応原因となる応答の調査• パケットキャプチャしながらファジング• デバッガ上で再度ファジングして解析• クラッシュ時のメッセージやデバッガの出力からフルリゾルバのソースを探索

検証コードや再現手順を開発元へ報告

16

結果• PowerDNS Security Advisory 2017-08: Crafted CNAME answer can cause adenial of service– https://doc.powerdns.com/recursor/security-advisories/powerdns-advisory-2017-08.html• Knot Resolver: fix CVE-2018-1110: denial of service triggered bymalformed DNS messages (2件の問題)
https://lists.nic.cz/pipermail/knot-resolver-announce/2018/000000.html––

https://gitlab.labs.nic.cz/knot/knot-resolver/issues/334
https://gitlab.labs.nic.cz/knot/knot-resolver/issues/335• Knot-Resolver 2.3.0 crashes in module/stats.
libknot(knot-dns)の"knot_dname_to_str memory overflow"に起因––

https://gitlab.labs.nic.cz/knot/knot-dns/raw/v2.6.7/NEWShttps://gitlab.labs.nic.cz/knot/knot-resolver/issues/35417

最後に• ファジングツールにより4件?脆弱性を発見できた。
• 特にQuad9(9.9.9.9)、Cloudflare(1.1.1.1)で利用されているPowerDNS
Recursor/Knot Resolverの脆弱性を発見できた意義は大きい• 過去の(BIND)の脆弱性に類似したものが、他のフルリゾルバでも発見できた(BIND:CVE-2015-8000 →PowerDNS Security Advisory 2017-08)

18