今日は、Apacheが本稿執筆時点での最新版 2.4.41 であるかを確認する方法を公開しちゃいます。
はじめに
脆弱性診断の一環で、サーバーソフトウェアのバージョンを確認したいというニーズがあります。今どき、Apache等のServerヘッダにバージョンが出ていることはまずない(…とも言えず実はよくある)ので、Serverヘッダ以外からソフトウェアのバージョンを確認する方法が知られています。以下はその例です。2番目の、とある診断員さんの記事は、Apache 2.2のすべてのバージョンをビルドして確認する方法が具体的に説明されています。そして、上の2つの記事はApache 2.2を題材にしていますが、2.2はとっくにサポートが終了しており、2.4系のバージョン確認の方法が求められますよね。
実は、Apacheの最新版 2.4.41 になって、エラーメッセージの表示内容が微妙に変わりましたので、バージョン確認に使えます。まずは、404 Not Foundの表示を用いて説明します。
試してみよう
以下は、Apache 2.4.39(2.4.40は欠番)における存在しないパス /xx に対するレスポンスの例です。
HTTP/1.1 404 Not Found
Date: Thu, 30 Jan 2020 01:48:04 GMT
Server: Apache/2.4.39 (Unix) PHP/5.3.3
Content-Length: 200
Connection: close
Content-Type: text/html; charset=iso-8859-1
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL /xx was not found on this server.</p>
</body></html>
以下は、Apache 2.4.41(最新版)における /xx に対するレスポンスの例です。2.4.39までと比べると、パス名(/xx)が省略されていることがわかります。これを使ってApache 2.4.41か、それより前のバージョンであるか判別できます。HTTP/1.1 404 Not Found Date: Thu, 30 Jan 2020 01:50:08 GMT Server: Apache/2.4.41 (Unix) PHP/5.3.3 Content-Length: 196 Connection: close Content-Type: text/html; charset=iso-8859-1 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>404 Not Found</title> </head><body> <h1>Not Found</h1> <p>The requested URL was not found on this server.</p> </body></html>
404ページをカスタマイズしている場合
ただ、404 Not foundのページは通常カスタマイズされているのでApacheが生成するレスポンスボディを見ることはできないケースが多いと思います。その場合は、他のステータスを用いることができます。たとえば、TRACEメソッドは禁止されているケースが多いと思いますが、この禁止されている場合のレスポンスが使える場合があります。まずは 2.4.39の場合(リクエストとレスポンス)
TRACE /xx HTTP/1.1
Host: apacheall:2439
HTTP/1.1 405 Method Not Allowed
Date: Thu, 30 Jan 2020 01:59:48 GMT
Server: Apache/2.4.39 (Unix) PHP/5.3.3
Allow:
Content-Length: 225
Content-Type: text/html; charset=iso-8859-1
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>405 Method Not Allowed</title>
</head><body>
<h1>Method Not Allowed</h1>
<p>The requested method TRACE is not allowed for the URL /xx.</p>
</body></html>
次に、2.4.41の場合(リクエストとレスポンス)
TRACE /xx HTTP/1.1
Host: apacheall:2441
HTTP/1.1 405 Method Not Allowed
Date: Thu, 30 Jan 2020 02:03:11 GMT
Server: Apache/2.4.41 (Unix) PHP/5.3.3
Allow:
Content-Length: 222
Content-Type: text/html; charset=iso-8859-1
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>405 Method Not Allowed</title>
</head><body>
<h1>Method Not Allowed</h1>
<p>The requested method TRACE is not allowed for this URL.</p>
</body></html>
やはり、2.4.39まであったパス名が2.4.41では省略されています。脆弱性診断実務では、TRACEメソッドの許可を調べているケースが多い(参照)と思うので、一石二鳥ですよね!ステータスの405までカスタムエラーページを用意してあればこの方法でもダメですけどね。Apacheのソースコード(./modules/http/http_protocol.c)の差分で見る限り、以下のメソッドがチェックに使えそうです。
Code | Reason-Phrase |
---|---|
305 | Use Proxy |
403 | Forbidden |
404 | Not Found |
405 | Method Not Allowed |
406 | Not Acceptable |
410 | Gone |
412 | Precondition Failed |
413 | Request Entity Too Large |
451 | Unavailable For Legal Reasons |
501 | Not Implemented |
506 | Variant Also Negotiates |
これらのステータスには、引き起こすのが難しいケースもありますが、403, 404, 405, 501あたりが使いやすそうです。
ただし、404を観察するくらいならともかく、エラーを故意に起こす通信は不正アクセスの予備行為と見なされ得るものですので、許可を得ていないサーバーで勝手に試すことは慎みましょう。
どうやって調べたか
Apache の2.2、2.4のすべてのバージョンをビルドして、それぞれポート番号を変えて実行する環境を作りました。先のリクエストで、apacheall:2441 というHost名が見えていましたか、ポート番号 2441 = Apache 2.4.41 という意味です。最終的にソースコードを確認する場合でも、動的解析であたりをつけておくと作業が楽ですよね。まとめ
Apache 2.4.41以降か、それ未満かをチェックする方法について説明しました。まだApache のバージョンを2.4.41にしているサイトはそこまで多くないと思いますので、脆弱性診断等で「Apacheが最新版ですないです!! ドヤー」とすることができます…というのは冗談で、この程度でドヤ顔はよくないですw ApacheはLinuxディストリビューションのパッケージで導入していて見かけのバージョンは古いがパッチが適用されているケースが多いですからね。現実的なリスクを踏まえて適切なアドバイスを心がけましょう。