Locked

CentOS_TIPS_021

CentOS6系における CVE-2016-5195/CVE-2017-6074 暫定対応メモ

Linuxカーネルの脆弱性(Dirty COW)が公開され、PoCも多数公開されていることもあり、対象となるシステムは速やかに対応する必要があります。

CVE-2017-6074 暫定対応についての追記はこちら。

ここでは、主にCentOS6系における対応について記載します。

  • Dirty COWについて

https://dirtycow.ninja/

  • RHELにおける緩和策

https://bugzilla.redhat.com/show_bug.cgi?id=1384344#c13

  • 関連記事

http://jvndb.jvn.jp/ja/contents/2016/JVNDB-2016-005596.html

https://www.agilegroup.co.jp/technote/dirty-cow.html

https://kosukeshimofuji.jp/2016/10/21/CVE-2016-5195/

  • CentOS 7系での検証記事

https://oss.sios.com/security/selinux-security-20161028

最終解決/最新カーネル適用

日本時間2016.10.27未明に、kernel-2.6.32-642.6.2がリリースされていますので、再起動可能なサーバは適用/再起動します。

# yum check-update
...
kernel.x86_64                            2.6.32-642.6.2.el6              updates
kernel-abi-whitelists.noarch             2.6.32-642.6.2.el6              updates
kernel-devel.x86_64                      2.6.32-642.6.2.el6              updates
kernel-firmware.noarch                   2.6.32-642.6.2.el6              updates
kernel-headers.x86_64                    2.6.32-642.6.2.el6              updates

# yum -y update
...
================================================================================
 パッケージ                アーキテクチャ
                                      バージョン             リポジトリー  容量
================================================================================
インストールしています:
 kernel                    x86_64     2.6.32-642.6.2.el6     updates       32 M
 kernel-devel              x86_64     2.6.32-642.6.2.el6     updates       11 M
更新:
 kernel-abi-whitelists     noarch     2.6.32-642.6.2.el6     updates      3.6 M
 kernel-firmware           noarch     2.6.32-642.6.2.el6     updates       28 M
 kernel-headers            x86_64     2.6.32-642.6.2.el6     updates      4.4 M
削除:
 kernel                    x86_64     2.6.32-642.1.1.el6     @updates     131 M
 kernel-devel              x86_64     2.6.32-642.1.1.el6     @updates      26 M

トランザクションの要約
================================================================================
インストール         2 パッケージ
アップグレード       3 パッケージ
削除                 2 パッケージ

総ダウンロード容量: 78 M

脆弱性の有無/PoC確認

以下のカーネル環境でPoC確認/緩和策を適用した手順を記載します。

$ uname -r
2.6.32-431.3.1.el6.x86_64

脆弱性の影響を受けるかチェックします。

$ wget https://access.redhat.com/sites/default/files/rh-cve-2016-5195_2.sh

$ bash rh-cve-2016-5195_2.sh
Your kernel is 2.6.32-431.3.1.el6.x86_64 which IS vulnerable.
Red Hat recommends that you update your kernel. Alternatively, you can apply partial
mitigation described at https://access.redhat.com/security/vulnerabilities/2706661 .

PoCが動作することを確認します。

  • 参考にしたPoC公開サイト

https://github.com/dirtycow/dirtycow.github.io

$ wget https://github.com/dirtycow/dirtycow.github.io/raw/master/pokemon.c
$ gcc -pthread pokemon.c -o d

rootユーザで攻撃対象ファイルを作成。

# echo pikachu > pokeball

$ ls -l pokeball
-rw-r--r-- 1 root root 8 10月 26 21:02 pokeball
$ stat pokeball
  File: `pokeball'
  Size: 8               Blocks: 8          IO Block: 4096   通常ファイル
Device: fc03h/64515d    Inode: 1711099     Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2016-10-26 21:02:51.726014730 +0900
Modify: 2016-10-26 21:02:44.260015095 +0900
Change: 2016-10-26 21:02:44.260015095 +0900

$ cat pokeball
pikachu

一般ユーザ権限でPoC実行。

$ ./d pokeball miltank
pokeball
   (___)
   (o o)_____/
    @@ `     \
     \ ____, /miltank
     //    //
    ^^    ^^
mmap 1a669000

madvise 0

ptrace 0

ファイルの内容が書き換わっていることを確認。

$ cat pokeball
miltank

$ stat pokeball
  File: `pokeball'
  Size: 8               Blocks: 8          IO Block: 4096   通常ファイル
Device: fc03h/64515d    Inode: 1711099     Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2016-10-26 21:02:51.726014730 +0900
Modify: 2016-10-26 21:02:44.260015095 +0900
Change: 2016-10-26 21:02:44.260015095 +0900

PoCの実行そのものは、終了までに時間が掛かって見えますが、実際にファイルの内容が書き換わるまでは非常に短い時間で完了しています。

また、このPoCをCGI(bashスクリプト)として実行させてもファイルの書き換えには成功しました。
何らかの形でファイルを送り込みCGI経由等ででも実行が可能であれば、ローカルログインする必要は無い可能性が高いものと思われます。

緩和策の適用

最新のカーネルを速やかに適用出来ない環境においても、必要に応じて緩和策を適用することが可能です。
但し、提示された緩和策は、副作用が全く無いという訳ではありません。
例えば、アンチウイルスソフトの一部機能が使えなくなる等の影響が考えられますので、稼働しているシステムの要件に注意して適用/対応を検討する必要があります。

なお、緩和策の適用により公開されているPoCの実行抑止にはなるものの、他の攻撃手法が無いとも限らないため、計画的にカーネルの更新を適用すべきと考えます。

稼働しているカーネルバージョンのkernel-debuginfoパッケージを取得します。

# yum --enablerepo=base-debuginfo --downloadonly install  kernel-debuginfo-`uname -r`
...
================================================================================
 パッケージ                     アーキテクチャ
                                       バージョン          リポジトリー    容量
================================================================================
インストールしています:
 kernel-debuginfo               x86_64 2.6.32-431.3.1.el6  base-debuginfo 254 M
依存性関連でのインストールをします。:
 kernel-debuginfo-common-x86_64 x86_64 2.6.32-431.3.1.el6  base-debuginfo  40 M

トランザクションの要約
================================================================================
インストール         2 パッケージ

総ダウンロード容量: 294 M
インストール済み容量: 1.7 G
これでいいですか? [y/N]y
パッケージをダウンロードしています:
(1/2): kernel-debuginfo-2.6.32-431.3.1.el6.x86_64.rpm    | 254 MB     00:53
(2/2): kernel-debuginfo-common-x86_64-2.6.32-431.3.1.el6 |  40 MB     00:17
--------------------------------------------------------------------------------
合計                                            4.0 MB/s | 294 MB     01:12
exiting because --downloadonly specified

# cd /var/cache/yum/x86_64/6/base-debuginfo/packages/
# ls kernel-debuginfo-*
kernel-debuginfo-2.6.32-431.3.1.el6.x86_64.rpm
kernel-debuginfo-common-x86_64-2.6.32-431.3.1.el6.x86_64.rpm

稼働しているカーネルバージョンのkernel-develパッケージがインストールされていない場合は別途取得しておきます。

# wget http://vault.centos.org/6.5/updates/x86_64/Packages/kernel-devel-2.6.32-431.3.1.el6.x86_64.rpm

カーネルのバージョンによってパスが異なりますので、適宜サイト内を確認してください。

例) 2.6.32-504.8.1.el6.x86_64 の場合
# wget http://vault.centos.org/6.6/updates/x86_64/Packages/kernel-devel-2.6.32-504.8.1.el6.x86_64.rpm

systemtapパッケージをインストールします。

# yum install systemtap
...
================================================================================
 Package               Arch        Version                   Repository    Size
================================================================================
Installing:
 systemtap             x86_64      2.9-4.el6                 base          23 k
Installing for dependencies:
 kernel-devel          x86_64      2.6.32-642.6.1.el6        updates       11 M
 systemtap-client      x86_64      2.9-4.el6                 base         3.7 M
 systemtap-devel       x86_64      2.9-4.el6                 base         1.7 M

Transaction Summary
================================================================================
Install       4 Package(s)

kernel-debuginfoパッケージをインストールします。

# yum localinstall kernel-debuginfo-2.6.32-431.3.1.el6.x86_64.rpm kernel-debuginfo-common-x86_64-2.6.32-431.3.1.el6.x86_64.rpm
...
================================================================================
 パッケージ
   アーキテクチャ
          バージョン          リポジトリー                                 容量
================================================================================
インストールしています:
 kernel-debuginfo
   x86_64 2.6.32-431.3.1.el6  /kernel-debuginfo-2.6.32-431.3.1.el6.x86_64 1.5 G
 kernel-debuginfo-common-x86_64
   x86_64 2.6.32-431.3.1.el6  /kernel-debuginfo-common-x86_64-2.6.32-431.3.1.el6.x86_64
                                                                          187 M

トランザクションの要約
================================================================================
インストール         2 パッケージ

合計容量: 1.7 G
インストール済み容量: 1.7 G
これでいいですか? [y/N]y

kernel-develパッケージを別途取得している場合は、併せてインストールします。

# yum localinstall kernel-debuginfo-2.6.32-431.3.1.el6.x86_64.rpm kernel-debuginfo-common-x86_64-2.6.32-431.3.1.el6.x86_64.rpm kernel-devel-2.6.32-431.3.1.el6.x86_64.rpm

stapコマンドで適用するファイルを作成します。

--- /dev/null
+++ /usr/local/etc/dcow.stp
@@ -0,0 +1,16 @@
+probe kernel.function("mem_write").call ? {
+       $count = 0
+}
+
+probe syscall.ptrace {
+       $request = 0xfff
+}
+
+probe begin {
+       printk(0, "CVE-2016-5195 mitigation loaded")
+}
+
+probe end {
+       printk(0, "CVE-2016-5195 mitigation unloaded")
+}
+

作成したファイルを引数にstapコマンドを実行/適用し、PoCが効かなくなったことを確認します。
stapコマンドはフォアグラウンドで動作しますので、確認後、一旦Ctrl-Cで終了させています。

# stap -g /usr/local/etc/dcow.stp
Message from syslogd@nazx at Oct 26 21:22:05 ...
 kernel:CVE-2016-5195 mitigation loaded

(PoC再確認)

^C
Message from syslogd@nazx at Oct 26 21:22:31 ...
 kernel:CVE-2016-5195 mitigation unloaded

実運用する上では、stapコマンドをバックグラウンド実行させる必要があります。

# stap -g /usr/local/etc/dcow.stp &

カーネルを更新し、再起動時には最新カーネルを使用される場合は、以上で対応完了です。

カーネルを更新しない/出来ない場合は、再起動時に緩和策が有効になるよう/etc/rc.local等で実行されるようにしておきます。

--- rc.local.org
+++ rc.local
@@ -5,3 +5,11 @@
 # want to do the full Sys V style init stuff.

 touch /var/lock/subsys/local
+#
+rpm --quiet -q kernel-debuginfo-`uname -r`
+if [ $? -eq 0 ]; then
+  if [ -x /usr/bin/stap -a -f /usr/local/etc/dcow.stp ]; then
+    /usr/bin/stap -g /usr/local/etc/dcow.stp &
+  fi
+fi
+

CVE-2017-6074 暫定対応

Linuxカーネル上のローカルユーザによる特権昇格の脆弱性が公開されました。
日本時間2017.2.26未明に、kernel-2.6.32-642.15.1がリリースされていますので、再起動可能なサーバは適用/再起動します。

  • 参考記事

https://oss.sios.com/security/kernel-security-vulnerability-20170223

  • RHELにおける緩和策

https://bugzilla.redhat.com/show_bug.cgi?id=1423071#c18

Ubuntu 4.4.0-62-genericをターゲットとしたPoCも公開されているようです。

https://www.softbanktech.jp/information/2017/20170301-01/

https://github.com/xairy/kernel-exploits/tree/master/CVE-2017-6074

緩和策についてはDirty COW同様の対応が取れるようなので、併せて記載します。

stapコマンドで適用するファイルを作成します。

--- /dev/null
+++ /usr/local/etc/deccp.stp
@@ -0,0 +1,6 @@
+probe module("dccp*").function("dccp_v?_connect") {
+  $addr_len = 0;
+  printf("%s[%d] DCCP socket connect denied\n", execname(), tid())
+}
+probe begin { printf("DCCP band-aid active\n") }
+probe end,error { printf("DCCP band-aid shutdown\n") }

バックグラウンドで実行します。

# stap -g /usr/local/etc/deccp.stp &

カーネルを更新しない(出来ない)場合、再起動によっても適用されるようにしておきます。

--- rc.local.org
+++ rc.local
@@ -11,5 +11,8 @@
   if [ -x /usr/bin/stap -a -f /usr/local/etc/dcow.stp ]; then
     /usr/bin/stap -g /usr/local/etc/dcow.stp &
   fi
+  if [ -x /usr/bin/stap -a -f /usr/local/etc/deccp.stp ]; then
+    /usr/bin/stap -g /usr/local/etc/deccp.stp &
+  fi
 fi

或いは、再起動時にDCCPモジュールを読み込まないようにしておきます。

# echo "install dccp /bin/true" >> /etc/modprobe.d/disable-dccp.conf