2016-02-17

glibc getaddrinfo() 問題 (CVE-2015-7547) について

さて、いつも同じですが、今回もあくまでも個人としての投稿です。会社としては CVE-2015-7547: glibc getaddrinfo stack-based buffer overflow 読んでということで。

脆弱性の内容、各ディストリビューションからのアップデートは各テック系サイトのニュースをご参照ください。

さて、大人の事情によりすぐに直せないよーという場合の緩和策(あくまでも緩和策です)として [PATCH] CVE-2015-7547 --- glibc getaddrinfo() stack-based buffer overflow では以下のものが挙げられてます:

UDP

  1. 513 バイト以上の UDP DNS パケットを firewall で落とす
  2. (略)
  3.  `options edns0` を /etc/resolv.conf で使わない。EDNS0 は 512 バイトより大きいレスポンスを許可するので、正当な DNS レスポンスでも overflow を発生させることが出来てしまいます
  4. (略)
元のメールの想定読者がシステム管理者ではないので、クライアントコードでの mitigation は省略しました。

TCP

  1. DNS リプライを 1024 バイトまでに制限する
これはちょっと理由が分からなかった。なんでこれでいけるん?fragment が発生しない最小値 (MTU の最小値) は IPv4 なら 576 バイト、IPv6 なら 1280 バイト。DNS/TCP パケットを再構成した上で処理する firewall なら、2048 バイトじゃね?

read() のバッファサイズと発行回数の都合で、1 packet が 1024 バイトまでならバッファがあふれる前に処理できる可能性が高い? でも、「パケット」については言及されてない。


ちゃんと読んでから後で訂正するかもですが、単に A と AAAA の合計で 2048 バイト超えないようにしろってことだと思う。

有効でない緩和策


ちなみに、意味のない緩和策として

  1. `options single-request` は内部でのバッファー管理方法に変わりはないので意味なし。
  2. `options single-request-reopen` も 1. と同様。
  3. IPv6 を無効にしても、(AF_UNSPEC が使われていると)AAAA クエリを投げること自体は止められない。
    • だから `sysctl -w net.ipv6.conf.all.disable_ipv6=1` は意味ない
  4. ローカル、または中間のリゾルバで IPv6 をブロックしてもダメ。クエリを並行して投げるところがバッファ管理の問題を引き起こしてるからです。exploit パケット自体は A への応答でも AAAA への応答でもありえる。
が挙げられてます。

その他

不正でない DNS レスポンスで exploit 可能だし、多分中間に cache サーバーがあってもその先まで侵入可能っぽいよ
ってことも書いてあるんで、単にDNSリレー/キャッシュを守るだけじゃクライアントを守れないっぽい (dnsmasq ならレスポンスサイズを制限できる)。

0 件のコメント:

prometheusのrate()関数の罠

 久しぶりのAdventカレンダー挑戦、うまくいく気がしません。 閑話休題。実のところ、rate()関数というよりは、サーバー側のmetric初期化問題です。 さて、何らかのサーバーAがあったとして、それが更に他のサーバーBにRPCを送っているとします。サーバーBの方でホワイトボ...