getaddrinfo() stack-based buffer overflow について

2016年 02月 17日 に JVN によってクリティカルレベルの glibc 脆弱性情報が公開されました。

概要glibc にバッファオーバーフローの脆弱性が存在する。
対象glibc 2.9 ~ 2.22 まで。
詳細glibc の send_dg() と send_vc() 処理によって発生するスタックベースのバッファオーバーフロー脆弱性。
影響範囲遠隔から任意のコードを実行、またはサービス運用妨害攻撃 (DoS 攻撃) を受ける可能性がある。
対策方法glibc をアップデートする。

RHEL 3・4・5 (CentOS 3・4・5) は対象外でした。

ディストリビュータ脆弱性対象 OS バージョン
RedHatRHEL Server EUS (v. 6.6)
RHEL Server AUS (v. 6.5)
RHEL Server AUS (v. 6.4)
RHEL Server AUS (v. 6.2)
RHEL Server EUS (v. 7.1)
RHEL 6
RHEL 7
Debiansqueeze
wheezy
jessie
UbuntuUbuntu 15.10
Ubuntu 14.04 LTS
Ubuntu 12.04 LTS

いつものように外部に公開しているサーバを優先的に glibc のアップデートを実施して行くと思いますが、その内容についてご紹介します。

  • glibc に依存するサービスリスト確認
  • 脆弱性対象か確認
  • glibc アップデート
  • 再起動

Step 1. glibc に依存するサービスリスト確認

lsof コマンドを使って、glibc に依存するサービス・バイナリ実行ファイル一覧を確認します。

普通に lsof コマンドを実行すると出力結果が重複するので、sort でアルファベット順に並べ替えてから uniq で重複を排除しています。

出力結果は環境によって違うので、glibc をアップデートした後に出力されたリストを参考に再起動するかしないか各自判断してください。

glibc 依存サービスリスト確認Raw Code(S)Raw Code(T)
# lsof | fgrep "libc-" | awk '{print $1}' | sort | uniq
acpid
agetty
awk
bash
crond
dhclient
fgrep
init
irqbalanc
lsof
mingetty
mysqld
mysqld_sa
rsyslogd
sendmail
sort
sshd
su
udevd
uniq

lsof は、root ユーザで実行する

lsof コマンドは、一般ユーザでも実行出来ますが、表示される結果が全然違うので、root ユーザで実行してください。

また、lsof が入ってない場合には、以下のコマンドを実行し、インストールしてください。

# yum -y install lsof

Step 2. 脆弱性対象か確認

まずは、rpm コマンドで、システムにインストールされている glibc が脆弱性対象か確認します。

glibc-2.9 ~ 2.22 までが対象なので、以下の場合には、脆弱性対象になります。

CentOS 6 : glibc バージョン確認
$ rpm -qa | grep "glibc"
glibc-common-2.12-1.149.el6_6.5.x86_64
glibc-2.12-1.149.el6_6.5.x86_64
glibc-headers-2.12-1.149.el6_6.5.x86_64
glibc-devel-2.12-1.149.el6_6.5.x86_64

$ cat /etc/redhat-release
CentOS release 6.4 (Final)
CentOS 7 : glibc バージョン確認
$ rpm -qa | grep "glibc"
glibc-common-2.17-78.el7.x86_64
glibc-2.17-78.el7.x86_64
glibc-headers-2.17-78.el7.x86_64
glibc-devel-2.17-78.el7.x86_64

$ cat /etc/redhat-release
CentOS Linux release 7.1.1503 (Core)

Step 3. glibc アップデート

各 OS のディストリビューション毎に最新パッチが出ているはずなので、パッケージ管理コマンドでインストールします。

各ディストリビュータのパッチ情報は、以下を参考にしてください。

以下は、RHEL (CentOS) の yum コマンドで glibc をアップデートする例です。

CentOS 6 : glibc アップデート
# yum clean all

# yum update glibc
・・・
Running Transaction Test
Transaction Test Succeeded
Running Transaction
  Updating   : glibc-common-2.12-1.166.el6_7.7.x86_64          1/8
  Updating   : glibc-2.12-1.166.el6_7.7.x86_64                 2/8
  Updating   : glibc-headers-2.12-1.166.el6_7.7.x86_64         3/8
  Updating   : glibc-devel-2.12-1.166.el6_7.7.x86_64           4/8

  ・・・

Updated:
  glibc.x86_64 0:2.12-1.166.el6_7.7

Dependency Updated:
  glibc-common.x86_64 0:2.12-1.166.el6_7.7
  glibc-devel.x86_64 0:2.12-1.166.el6_7.7
  glibc-headers.x86_64 0:2.12-1.166.el6_7.7

Complete!
CentOS 7 : glibc アップデート
# yum clean all

# yum update glibc
・・・
Running transaction test
Transaction test succeeded
Running transaction
  Updating   : glibc-2.17-106.el7_2.4.x86_64                   1/8
  Updating   : glibc-common-2.17-106.el7_2.4.x86_64            2/8
  Updating   : glibc-headers-2.17-106.el7_2.4.x86_64           3/8
  Updating   : glibc-devel-2.17-106.el7_2.4.x86_64             4/8

  ・・・

Updated:
  glibc.x86_64 0:2.17-106.el7_2.4

Dependency Updated:
  glibc-common.x86_64 0:2.17-106.el7_2.4
  glibc-devel.x86_64 0:2.17-106.el7_2.4
  glibc-headers.x86_64 0:2.17-106.el7_2.4

Complete!
CentOS 6 : glibc アップデート確認
# rpm -qa | grep glibc
glibc-headers-2.12-1.166.el6_7.7.x86_64
glibc-2.12-1.166.el6_7.7.x86_64
glibc-devel-2.12-1.166.el6_7.7.x86_64
glibc-common-2.12-1.166.el6_7.7.x86_64
CentOS 7 : glibc アップデート確認
# rpm -qa | grep glibc
glibc-headers-2.17-106.el7_2.4.x86_64
glibc-2.17-106.el7_2.4.x86_64
glibc-devel-2.17-106.el7_2.4.x86_64
glibc-common-2.17-106.el7_2.4.x86_64

CentOS 7 systemctl 状態更新

CentOS 7 の場合には、yum update 後、以下のコマンドを実施し、systemd サービスマネージャの状態を更新してください。

# systemctl daemon-reexec

glibc アップデートが失敗する場合の対処

# yum update glibc

Loaded plugins: fastestmirror, security

Loading mirror speeds from cached hostfile

Error: Cannot retrieve metalink for repository: epel. Please verify its path and try again

remi、epel などのリポジトリを無効化し、nss をアップデートしてからリトライしてみてください。

# yum --disablerepo=epel update nss

# yum update glibc

Step 4. 再起動

後は、lsof コマンドで glibc アップデート後にもまだ古いバージョンの glibc を使っているプロセスを確認し、再起動する必要があるか判断してください。

出来る限り、再起動することをオススメしますが、事情により再起動が難しい状況であれば、必要なプロセスだけでも再起動してください。

旧バージョンの glibc を使っているプロセス確認Raw Code(S)Raw Code(T)
# lsof | fgrep "libc-" | grep "DEL"
acpid
agetty
crond
dhclient
init
irqbalanc
mingetty
mysqld
mysqld_sa
rsyslogd
sendmail
udevd
glibc アップデート適用 : 再起動Raw Code(S)Raw Code(T)
# sync
# sync
# shutdown -r now

終わりに

VPS 借りてウェブサイト運営している方も少なくないと思いますが、事前にアップデートだけしておいて、アクセスが少ない深夜時間帯に再起動するように cron を仕込むのもいいかなと思います。 (再起動後にもウェブサービスが提供できる環境前提)

cron : 2月 19日の 04:30 に OS 再起動Raw Code(S)Raw Code(T)
# crontab -e
30 4 19 2 * /sbin/shutdown -r now

会社で多数のサーバを管理している場合には、再起動時に借用が発生するかもしれないですし、簡単に再起動できない場合がほとんどだと思いますが。。

サーバの台数が多いと確認と対策に稼動取られるからいやですね。

以上、CVE-2015-7547 : glibc 脆弱性対策 でした。