CVE-2012-どさにっき 〜2012年7月中旬〜

by やまや
<< = >>

2012年7月11日(水)

libbind が壊れている件。

_ こんなスクリプト。

#!/bin/sh
suffix=blog1.fc2.com
while [ ${#a} -lt 63 ]; do
    a=a$a
    getent hosts $a.$suffix || echo "$a.$suffix failed($?)"
done
a.blog1.fc2.com から aaa......blog1.fc2.com までアドレスを調べるだけ。dig のように DNS に直接問い合わせるのではなく、スタブレゾルバとして gethostbyname(3) などを使って名前解決する。これに使う getent は glibc のオマケなので linux でしか動きません。

_ で、*.blog1.fc2.com はワイルドカード A を持っているので、a.blog1.fc2.com でも aaaaaaaaaa.blog1.fc2.com でもどんな名前を聞いても同じ答が返ってくる。はず。だが。CentOS5 で LD_PRELOAD=/usr/lib64/libbind.so.4 を環境変数に設定してこのスクリプトを実行したときの結果。

...
208.71.105.158  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.blog1.fc2.com
208.71.105.158  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.blog1.fc2.com
208.71.105.158  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.blog1.fc2.com
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.blog1.fc2.com failed(2)
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.blog1.fc2.com failed(2)
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.blog1.fc2.com failed(2)
...
長さが63バイト以上になるとコケる。LD_PRELOAD を指定せず名前解決を libc にやらせるとまったく問題ない。DNS ではラベルひとつあたりの長さは最大63バイトに制限されてるけど、全体では253バイトまでいけるはずなんだけどなぁ。そのへんを間違えて実装しちゃったのかしら。

_ C で書き直してみる。

#define SUFFIX ".blog1.fc2.com"
#include <netdb.h>
#include <stdio.h>
main(){
    int i, j;
    char name[256];
    for(i=0; i<63;){
        name[i++]= 'a';
        for(j=0; j<sizeof(SUFFIX); ++j) name[i+j] = SUFFIX[j];
        printf("%s %s\n", gethostbyname(name) != NULL ? "OK" : "NG", name);
    }
}
もちろん結果は同じ。gcc -lbind でコンパイルする、あるいは LD_PRELOAD で libbind を指定すると一定以上の長さでコケる。libbind を使わず libc 内の gethostbyname() を使えば問題ない。

_ まあ、そもそも libbind.so なんて存在しないのがふつーなんだけどな。libc で十分用は足りるからわざわざこんなの使う必要ない。libbind は名前のとおり BIND のオマケだけど、named その他の動作にはまったく必要ないし、というか --enable-libbind で configure しないとビルドすらされないし、最近の BIND にはオマケですらなく存在しないし。ただ、ふつーでない環境というのがあって、それが RHEL5/CentOS5。クソ古い BIND 9.3 を使っていて、dig をインストールすると依存性で自動的に libbind.so がインストールされてしまう。で、libbind を見つけるとそいつを優先的に使ってしまうアプリというのが存在しているとこの問題を踏む、と。glibc には getipnodebyname(3) が存在せず、libbind には存在するので、getaddrinfo(3) ではなくこいつを使うような古い v6 対応アプリでは libbind が必要になるかも。そして cent5 の libbind は getipnodebyname() もやはり長い名前を扱えないっぽい…。

_ 今の BIND に libbind はないけど、9.6 相当のものが 単体配布されている。こいつを FreeBSD 上で試したところ、長い名前も問題なく扱えるようだ。BIND 9.3 の libbind が壊れてるのか、あるいは cent5 の libbind だけが壊れてるのかどっちかは知らん。

_ RFC1123 section 2.1

Host software MUST handle host names of up to 63 characters and SHOULD handle host names of up to 255 characters.
63バイトまでは MUST だけど、それを越える分は SHOULD なので、そんな長い名前でコケたとしてもただちに問題があるとは言えないってことか。むしろ長い名前でコケる環境が存在することを想定しないでそんな名前をつける方が悪い、ともいえる。

_ 結論。rhel5/cent5 の bind まわりはクソ。bind 関連の RPM はぜんぶ削除して libbind を含まない bind97 なパッケージに入れ替えるべき。libbind を使うようにコンパイルしてあるバイナリが動かなくなるけど、libbind を使わないようにコンパイルしなおせばいい。あんな古いのを使い続ける意味はまったくない。


2012年7月16日(月) 海の日

八ヶ岳

_ 天気予報を見ながら直前まで迷いに迷って、3連休は北八ヶ岳に決める。森と苔で知られるところだから晴れてなくてもそれなりに楽しめるだろうし、むしろ苔は濡れてるぐらいが美しいだろう、と。

_ ということで、金曜の夜うちを出て、深夜に麦草峠に到着、そのまま車中泊。明けて土曜の早朝。濃霧。10m 先が見えません。えー。たしかに天候には期待してなかったけどそれはねーよ。あまり睡眠も取れてなかったのであきらめて二度寝。昼前に起きだしたころにはだいぶガスは薄くなってたけど、それでもいいとこ 50m 先がなんとか見えるぐらいか。山に入るのはあきらめて八ヶ岳山麓を車で一周。夕方ふたたび麦草峠まで上がって車中泊。

_ 日曜早朝。やっぱりガス。きのうの昼ごろと同じぐらいの視界。予報だと3連休ではいちばんマシな天気になるはずなので信じて出発。…のはずが、しばらくして雨に。景色ははじめから期待してなかったけど、雨の中泥んこになって歩くのもつまらんなぁ。たしかに苔は見事だけれど何時間もそればっかりというのは飽きる。ということで、当初考えていたより大幅に短縮して麦草峠-茶臼山-縞枯山-縞枯山荘-雨池-麦草峠というコースでおしまい。ほんとは北横岳〜双子池の方まで行くつもりだったんだけど、萎えた。聞けばきのうは1日降らずにもったそうで、なんだよそれ。昼近くになってだいぶ天候は回復したんで、わしが歩いてた時間帯がいちばんひどかったみたい。

_ ちっとも楽しめなくて消化不良なんだけど、心が折れた。休みはもう1日あるけど、さっさと帰宅。で、今日月曜日。なんで晴れてるかな。山の天気とは違うとはいえ、なんか腹立つ。来週またどっか行くか。

_ 縞枯山の名前の由来にもなってる 縞枯現象の起きてるあたり

天候が回復してきてほんの数秒だけ薄日の射したこともあった

無題

_ おたよりいただきました。「 getentは linux 専用じゃねーよボケ」

_ …え? まじで?
OSX Lion。

$ getent hosts www.google.com
bash: getent: command not found
ほらない。って、macosx は NSS を使ってないからあるはずないか。
FreeBSD5
% getent hosts www.google.com
getent: コマンドが見つかりません.
ほらない。…FreeBSD 5 って NSS が入った直後のころのものだから周辺ツールが揃ってなくてもしかたないか(←なんでそんな環境がまだ動いてるんだよ)。
FreeBSD9
>  getent hosts www.google.com
173.194.38.83     www.l.google.com  www.google.com
うわぁ。なんであるの? man によると NetBSD3.0、FreeBSD7.0 かららしい。まったく気がついてなかった。

_ linux で man getent しても glibc のために書いたと自信マンマンに書いてあるんで、こいつがオリジナルだとずっと勘違いしちゃってたのかなぁ。調べてみると、どうやら少なくとも Solaris 2.5 にはすでにあったらしい。そんなに古くからあるもんだったのか。知らなかったよ。ふだん使う機会はまずないからなぁ。つーか、linux の man はどーしてどいつもこいつも HISTORY の項目が抜けてるんだろうか。


2012年7月20日(金)

NSD 3.2.12

_ 外から落とせる穴があるから入れかえろってさ。うぇー。

_ ここのところ毎年7月になると DNS 関連の脆弱性が見つかっててんやわんやだよ! でも今年の7月はまだないよ!ってなネタをつい昨日社内 LT で話したばっかりなのに、その日のうちに NSD の穴が公表されるとかどういう間のわるさなんだか。

_ まあ、今のところ仕事では使ってないからそれほど大騒ぎにはならんで済むけどね。自宅ドメインが NSD なので入れ替えなきゃいかんけど。いまの NSD はドメインの追加削除が設定のリロードではできず、プロセスをいったん止めて起動しなおさなきゃいけないので、そういうことがしばしばあるようなところでは使いづらい。将来のバージョンで直される予定はあるみたいだけど。


<< = >>
やまや