glibcのgethostbyname関数に存在するCVE-2015-0235(GHOST)脆弱性について

Linux

glibcのgethostbyname系関数に脆弱性の原因となるバグが発見されCVE-2015-0235(GHOST)と命名されたようです。放置した場合は相当多くのアプリケーションがこの脆弱性の影響を受けることが予想されます。

glibcは libcのGNUバージョンです。libcはアプリケーションではなく、事実上全てのアプリケーションが利用しているライブラリです。OSの中ではカーネルに次いで重要な部分と言えます。Linuxシステムでは(ことサーバー用途においては)例外なく glibcが使われています。

この glibcに含まれる gethostbyname系関数の実装に 2000年頃から存在したバグが今になって発見され、CVE-2015-0235 通称 GHOSTと命名されました。ネットワークで何らかの通信を行うアプリケーションは必ずこの関数を使用します

※追記: 名前解決をサポートしないアプリケーション(珍しいですが)もありますし、意識の高いIPv6対応アプリケーションでは getaddrinfoが代わりに使用されるため「必ず」とは言えませんでした。

glibcのバージョン 2.17と2.18の間でこのバグは修正されているのですが(現在の最新版は2.20)、多くの Linuxシステムではバージョン2.17未満の glibcが使用されており脆弱性の影響を受けます。例えば RedHat Enterprise Linux(と CentOS) 6.6は glibc 2.12を使用していますし、Debian Wheezyは glibc 2.13を使用しています。

RedHat Enterprise Linux と CentOSでの対策

RedHat社による glibc セキュリティアップデートの情報

yumコマンドで glibcをアップデートしてください。

yum update glibc

これを書いている時点ではまだ CentOSにはアップデートが来ていないようです。CentOSのフォーラムにおけるやりとり を意訳すると、

  • RedHat社から修正版のソースがリリースされるのを待つ
  • 修正されたglibcをビルドする (でかいので時間がかかる)
  • ↑しかも32bitと 64bitの両方やんなきゃいけない
  • 誰かFOSDEMに行かない奴を探し出してバイナリパッケージに署名してもらう
  • ミラーにプッシュして反映されるのを待つ

という長い道のりがあるようで・・・。

追記

日本のミラーにもアップデートが到着しつつあるようです。パッケージ管理システムのキャッシュをクリーンにしてからアップデートを実行してください。

yum clean all
yum update glibc

Debian GNU/Linux での対策

Debianによる CVE-2015-0235 についての情報

apt-getコマンドで glibcをアップデートしてください。

apt-get update
apt-get upgrade glibc

glibcのバージョンを確認する方法は?

libc.so.6 をコマンドラインから実行すると glibcに関する詳細な情報が得られます。libc.so.6の在処は Linuxディストリビューションによって違いますが、

  • /lib/libc.so.6
  • /lib64/libc.so.6
  • /lib/i386-linux-gnu/libc.so.6
  • /lib/x86_64-linux-gnu/libc.so.6

といったあたりです。

アップデートしたのに glibcのバージョンが 2.12やら13のままなんだけど?

glibc全体をいきなり最新版に入れ替えるとほぼ間違いなくシステムが動かなくなりますので、Linuxディストリビューションの配布元はそのようなアップデートを提供しません。アップデート後のgilbcは 「2.12の修正版」や「2.13の修正版」となります。

再起動は必要?

共有ライブラリを更新しても、既に起動しているアプリケーションはまだ古いコードを読み込んだまま動作しているはずなので、脆弱性の影響を受ける可能性のあるアプリケーションは全て再起動するべきだと思います。といっても、かなり多くのアプリケーションが gethostbyname系の関数を使用しているでしょうから、万全を期するならシステムごと再起動したほうが良さそうです。

glibcはC言語のライブラリだから (Perl/PHP/Python/Ruby ...)のアプリケーションは大丈夫だよね?

残念ながらそれらの言語も結局内部ではC言語のAPIを呼び出すことで動いているので絶対に影響を受けないとは言い切れません。

具体的には脆弱性によって何が引き起こされる?

今回発見されたglibcの問題は、攻撃者がリモートから細工されたホスト名文字列を(例えばURLのホスト名部分などに埋め込んで)与えることによって、アプリケーション側のメモリを数バイト上書きできてしまうことです。といっても任意の値で上書きできるわけではないので、それで具体的に何ができるかというと何でも出来るわけではないと思うのですが、アプリケーションによっては任意コードの実行につなげることが出来てしまうだろうと予想されています。多くの場合は任意コードの実行にまでは至らなくても、ランダムな誤作動をさせるくらいのことは出来るんじゃないでしょうか。C言語のコードが読める方でスタックやらヒープやらのマップが脳内に描ける人はこの後に引用しているコードから想像して下さい。

実際に、Exim(メールサーバ)に対して攻撃を行い任意コードの実行が出来る実証コードを作成できたそうです。32bit/64bitの両方が攻略可能で、CPUの不正命令実行防止機構(ASLR, PIE, and NX)は役に立たないとのこと。

自分のシステムが脆弱かどうかを調べるには?

調査用のプログラムをコンパイル・実行してください。

oss-security - Qualys Security Advisory CVE-2015-0235 - GHOST: glibc gethostbyname buffer overflow から引用

#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#define CANARY "in_the_coal_mine"

struct {
  char buffer[1024];
  char canary[sizeof(CANARY)];
} temp = { "buffer", CANARY };

int main(void) {
  struct hostent resbuf;
  struct hostent *result;
  int herrno;
  int retval;

  /*** strlen (name) = size_needed - sizeof (*host_addr) - sizeof (*h_addr_ptrs) - 1; ***/
  size_t len = sizeof(temp.buffer) - 16*sizeof(unsigned char) - 2*sizeof(char *) - 1;
  char name[sizeof(temp.buffer)];
  memset(name, '0', len);
  name[len] = '\0';

  retval = gethostbyname_r(name, &resbuf, temp.buffer, sizeof(temp.buffer), &result, &herrno);

  if (strcmp(temp.canary, CANARY) != 0) {
    puts("vulnerable");
    exit(EXIT_SUCCESS);
  }
  if (retval == ERANGE) {
    puts("not vulnerable");
    exit(EXIT_SUCCESS);
  }
  puts("should not happen");
  exit(EXIT_FAILURE);
}

上記を GHOST.c という名前で保存し、

gcc -o GHOST GHOST.c

でコンパイル(GHOSTという名前の実行ファイルが生成される)したのちに

./GHOST

として実行してください。root権限は必要ありません。vulnerable(脆弱)か not vulnerable(脆弱でない)かが表示されます。コンパイラの入っていない(インストールできない・したくない)環境の場合は、他のマシンでコンパイルして実行ファイルだけコピーすれば良いでしょう。当然ですが 64bit OS上でコンパイルした実行ファイルは32bit OS上で動かないので注意して下さい。どうしても 32bit環境で動作する実行ファイルを64bit環境で作りたければ gccに -m32 オプションをつけてください。

あと、GHOSTなんて名前の実行ファイルが放置されていると後であらぬ誤解による騒ぎになる可能性があるので用が済んだら削除しておきましょう。

追記

この脆弱性について、即座に対策しなければあっという間にサーバーを乗っ取られてしまうかのような論調が一部で見られますが、そうでもありません。(かといって放置していいわけではないことに注意して下さい)

GHOST脆弱性の問題を緩和する要素について( GHOST脆弱性勧告書の一部を翻訳)

こちらに、この脆弱性を使用した攻撃がそう簡単には成立しない(よって、一刻も早く対策をしなければならないとまでは言えない)ことの説明がまとまっています。

同じカテゴリの記事

DFSがどうこうと言われて Sambaの共有にアクセスできなくなった時の対処 2015年1月21日
Linuxをクラッシュさせられるバグが権限昇格のバグに進化した件 2014年12月18日
Linux 3.18リリース 2014年12月8日
BASHの脆弱性でCGIスクリプトにアレさせてみました 2014年9月25日

お勧めカテゴリ

英語でアニメ観ようず
なじみ深い日本製アニメの英語版DVDで、字幕と音声から英語を学びましょうという趣旨のシリーズ記事です。
ScalaのようでJavaだけど少しScalaなJSON API
Scalaと Spring Frameworkを使って REST的なJSON APIを実装してみましょう。
ドクジリアン柔術少女 すから☆ぱいそん
代表 嶋田大貴のブログです。写真は神仏に見せ金をはたらく罰当たりの図