PowerDNS Security Advisory 2016-01(CVE-2016-5426)の実験


初めに

PowerDNS Authoritative Server(以後PowerDNS)は、3.4.10がリリースされました。
3.4.9から3.4.10のChangeLogに、

commit 881b5b0: Reject qnames with wirelength > 255, chopOff() handle dot inside labels

があり、これでPowerDNS Security Advisory 2016-01(CVE-2016-5426およびCVE-2016-5427)の対応をしています。ここでは、CVE-2016-5426の影響度について考察します。

注意事項

CVE-2016-5426についてPowerDNS BVおよび発見者から情報を得てはいませんので、ここに記載されている内容は、公開されている情報から推測したものです。

CVE-2016-5426について

CVE-2016-5426の概要は、

  • 細工したDNSクエリを送信することで、バックエンドのCPU使用率が上昇する。

というものです。

PowerDNSはゾーンの情報を、データベースやディレクトリサーバなどのバックエンドに持たせています。PowerDNSは受信したクエリをもとにバックエンドに問い合わせ、その応答を受信してDNSレスポンスを生成し、それを返します。ここで注意しなければならないのは、ひとつのDNSクエリに対して、バックエンドへの複数の問い合わせが発生することです。

実験

環境

  • PowerDNS サーバ(pdns-front)
    • 論理CPU x 4
    • メモリ4GB
    • OS CentOS 6.8 64bit
      • CPUごとの使用率に偏りがでるため、以下の設定を追加
echo "f"   > /sys/class/net/eth0/queues/rx-0/rps_cpus
echo 32768 > /proc/sys/net/core/rps_sock_flow_entries
echo 32768 > /sys/class/net/eth0/queues/rx-0/rps_flow_cnt
  • PowerDNS 3.4.9
    • pdns.confのreceiver-threadとreceiver-threadsを20に変更。デフォルト値では、バックエンドの負荷があまり上昇しないため
  • net-snmp CPU使用率などの取得のためsnmpdを使用

    • バックエンドサーバ(pdns-back)
  • 論理CPU x 4

  • メモリ4GB

  • OS CentOS 6.8 64bit

    • CPUごとの使用率に偏りがでるため、以下の設定を追加
echo "f"   > /sys/class/net/eth0/queues/rx-0/rps_cpus
echo 32768 > /proc/sys/net/core/rps_sock_flow_entries
echo 32768 > /sys/class/net/eth0/queues/rx-0/rps_flow_cnt
  • MySQL 5.1.73(mysql-server-5.1.73-7.el6.x86_64)
    • my.cnfは未修正
  • net-snmp CPU使用率などの取得のためsnmpdを使用

方法

以下のようなDNSクエリをPowerDNSへ送信し、pdns-frontとpdns-backのCPU使用率をSNMPを利用して計測しました。

  • 20qpsまたは50qpsのクエリをpdns-front送信
  • QNAMEはランダムに生成
  • QNAMEの長さを250, 1000を変えて、それぞれの場合を計測
  • QNAMEはバックエンドのクエリが多くなるように工夫
  • クエリに対するレスポンスを待たない。QNAMEの長さが255を超えると、レスポンスのDNSメッセージを作成するときに、例外(C++)が発生してレスポンスがなくなるため

結果

pdns-frontとpdns-backのCPU使用率は以下のようになりました。グラフの山は左から

  1. QNAMEを250として20qpsのクエリを送信
  2. QNAMEを1000として20qpsのクエリを送信
  3. QNAMEを250として50qpsのクエリを送信
  4. QNAMEを1000として50qpsのクエリを送信

ときのものです。QNAMEの長さが1000の場合は、バックエンドサーバのCPUおよびPowerDNSサーバのCPU使用率も高くなりました。

pdns-front

pdns-back

考察

バックエンドサーバのCPU使用率が高くなったのは、PowerDNSから非常に多くのクエリがMySQLへ送信されたためです。QNAMEの長さが1000程度の場合、ひとつのDNSクエリに対して、1000以上のクエリをPowerDNSからバックエンドへ送信させることが可能です。このように多くのクエリが送信される理由については、MySQLのクエリログを参照してみてください。

50qps程度のクエリは一台のPCでも容易に生成することが可能ですので、CVE-2016-5426を利用することにより、PowerDNSのバックエンドサーバを過負荷にすることができます。PowerDNSサーバを利用したサービスをDDoSで落とすことは容易にできてしまうということです。

上記のCPU使用率の増加は、QNAMEの長さを短くすることで抑制することができます。PowerDNS 3.4.10では255以下に制限されているので、CPU使用率は大きくなりません。

まとめ

PowerDNS Authoritative Server 3.4.9以下を利用している場合は、少ないクエリ数で容易にサービスを止められてしまいますので、早急に3.4.10にしましょう。

おまけ

CVE-2015-1868, CVE-2015-5470, CVE-2015-5230, CVE-2016-5426と続いたドメイン名関係の脆弱性も、これで終わってくれるといいですね。