脆弱性の危険度(ざっくり)

まあCVSSの解説見ろよって話なんだけど、ありがちな脆弱性の危険度は個人的にはこんなイメージです。

総合的な危険度 = 条件 × 影響

条件

脆弱性の攻撃に必要な前提条件が「狭い」のであればそれほど問題ないです。

  1. 一番ヤバイ: TCPUDP、IPによりネットワークから送られた通信で攻撃が成立
    • Slammer(しかもハンドシェークが不要なUDPのため被害が拡大)
    • Heartbleed
    • Shellshock、GHOST(ただし一部のミドルウェア)
  2. だいぶヤバイ: 通信路に割り込まないとイケない(MITM) *1
    • アクティブに通信に割り込むかどうかで度合いが変わる
    • POODLEとか
    • FREAK
  3. そこそこヤバイ: ネットワーク経由での攻撃ができるが、認証後でないと成立しない
  4. ヤバイ: ログイン後の一般ユーザーで攻撃が成立
  5. ちょっとヤバイ: 弱い設定をしている場合など限られた条件でのみ攻撃が成立
    • 当初はFREAKもここだと思われていた
  6. まあヤバイ: 物理的に接触された場合にのみ攻撃が成立
    • USB メモリに扮したキーボードデバイスみたいな奴

影響

  1. 即死級: コード実行
    • 送り込まれたプログラムコードを実行してしまう。
    • 発見次第即座にパッチを当てないと死ぬ。攻撃条件次第ではインターネット崩壊
    • Shellshock、GHOSTはここ、ただし、コード実行に至る条件がそれなりに厳しかった
    • 伝説のSQL Slammerもこれ。発生して最初の10分間で、インターネット上の条件を満たすサーバの90%に相当する75000台に感染したらしい。
  2. 超緊急: PKI基盤の毀損
    • 他の攻撃とセットでremote code送り込まれるから可能性が生まれただけでアウトなんだよ!!
    • この前のLenovoSuperfishみたいなやつ。
  3. 緊急: サーバ内容(ディスクやメモリ)の漏洩
  4. 重要: 通信内容の漏洩
    • ログイン情報などが漏れた場合は利用者対応が必要
    • あくまでサービスの機能として可能な範囲に影響は留まる (提供していないことはやられない)
    • 特定のサービスを対象に大規模にMITM等が行われた場合、リスト型攻撃などのリスト作成に使われる可能性もあるにはある。
    • FREAKやPOODLE
  5. 要対応: サービス停止(DoS)
    • サービスが止まること自体の損害のみ
    • ただし、DoSと思っていたら、後になってメモリ漏洩も可能と変身回数を残している場合があるので注意。
    • 今回のOpenSSLとか、ほとんどの環境におけるGHOST

備考

あくまで「ざっくり」なので、エンジニアであればちゃんとCVSSの解説を読んで、どういう判断軸があるか知った方が良いです。

  1. 基本評価基準 (Base Metrics)
    1. AV :攻撃元区分 (Access Vector)
    2. AC :攻撃条件の複雑さ (Access Complexity)
    3. Au :攻撃前の認証要否 (Authentication)
    4. C :機密性への影響 (情報漏えいの可能性、 Confidentiality Impact )
    5. I :完全性への影響 (情報改ざんの可能性、 Integrity Impact )
    6. A :可用性への影響 (業務停止の可能性、 Availability Impact )
  2. 現状評価基準 (Temporal Metrics)
    1. E :攻撃される可能性 (Exploitability)
    2. RL :利用可能な対策のレベル (Remediation Level)
    3. RC :脆弱性情報の信頼性 (Report Confidence)
  3. 環境評価基準 (Environmental Metrics)
    1. CDP :二次的被害の可能性 (Collateral Damage Potential)
    2. TD :影響を受ける対象システムの範囲 (Target Distribution)
    3. CR, IR, AR :対象システムのセキュリティ要求度(Security Requirements)

上では、基本評価基準のうちAV+AC+Auの例を「条件」、C+I+Aの例を「影響」として紹介しました。

実際に、脆弱性対応の緊急度(どれぐらいの間に対応が強いられているか)を判断するには、現状評価基準や環境評価基準の項目を考慮する必要があります。

*1:DNSが脆弱であることが判明しているので、ドメインネームで通信を行うのが一般的な現状では攻撃の条件としてだいぶ容易になっています。

新型MacBookとLaVie Hybrid ZEROの比較

面倒だからLaVieのカスタマイズモデルは入れてない。
あとLaVieの販売価格はヨドバシ通販。

結構良い勝負してると思うんだけどやっぱりNECは宣伝下手だと思う。

LaVie Hybrid ZERO MacBook MacBook Air
11inch
MacBook Air
13inch
MacBook Pro
Retina 13inch
HZ550/AAB HZ750/AAB min max min max
画面 13.3 inch
2560 x 1440
13.3 inch
2560 x 1440
タッチパネル
12 inch
2304 x 1440
11.6 inch
1366 x 768
13.3 inch
1440 x 900
13.3 inch
2560 x 1600
重さ 0.779kg 0.926kg 0.92kg 1.08kg 1.35kg 1.58kg
最大高さ(厚さ) 1.69cm 1.31cm 1.7cm 1.7cm 1.8cm
CPU Core i5-5200U
2.20GHz
2core
Core i7-5500U
2.40GHz
2core
Core M
1.1GHz
2core
Core M
1.3GHz
2core
Core i5
1.6GHz
2core
Core i7
2.2GHz
2core
Core i5
2.7GHz
2core
Core i5
3.1GHz
2core
メモリ 4GB 8GB 8GB 4GB 8GB 8GB 16GB
ストレージ 128GB SSD 256GB PCIe 512GB PCIe 128GB PCIe 256GB PCIe 128GB PCIe 512GB PCIe
Graphics Intel HD Graphics 5500 Intel HD Graphics 5300 Intel HD Graphics 6000 Intel Iris Graphics 6100
バッテリー駆動時間 5.9時間
(JEITA 2.0)
9.0時間
(JEITA 2.0)
9時間
(ワイヤレスインターネット閲覧)
9時間
(ワイヤレスインターネット閲覧)
10時間
(ワイヤレスインターネット閲覧)
販売価格(税抜) 144,528円 184,788円 148,800円 184,800円 102,800円 136,800円 148,800円 208,800円

Superfish/eDellRootが危険な理由

Lenovo製のPCの一部にSuperfishというマルウェアが標準でインストールされていることが確認され、大きな問題となっています。

経緯や影響範囲等については、Kangoさんの記事にまとまっているのでそちらをご覧ください。

この記事では、Superfishというマルウェアがなぜ特別に危険かを解説します。

Superfishの目的

このSuperfishの目に見える目的は、ブラウザで表示しているウェブサイトに広告を挿入することです。言い換えれば、ウェブサーバから取得したHTMLを書き換えて勝手なJavaScriptを挿入するすることにあります。

目的だけ見れば一般的なアドウェアの一つとも言えます(もちろんそれだけでevilだと個人的には思います)が、Superfishはさらに踏み込んで、普通のやり方では書き換えができない暗号化されたウェブサイトを書き換えるために特殊な方法を利用していますが、その実装方法に大きな問題があるために、広告が挿入されるというレベルをはるかに超えた脆弱性となっています。

前提として、TLS──いわゆるSSLは、ウェブサイトの通信内容を秘匿するだけで無く、その内容の改竄を防ぐことも目的としています。そのため、SuperfishではMITM攻撃と呼ばれる手法で、このTLSの暗号化通信に「穴」を開けています。

TLS(いわゆるSSL)による安全な通信

まず、通常の暗号化された通信を見てみます。

安全に通信を行うためには、自分(のPCで動いているブラウザ)と、その通信相手のウェブサーバの他に、様々な基準によって信頼されたCA(認証局)を利用します。

ウェブサーバは、暗号化するための「秘密鍵」とウェブサイトのドメインネーム(このページで言えば「d.hatena.ne.jp」)が書かれた「証明書」を持っていますが、あらかじめこの証明書に、CAの「お墨付き」の判子を押してもらっておきます(図の1)。

その一方で、ブラウザは自分が信頼できるCAの一覧を持っています。これがルート証明書のリストと呼ばれるものです(図の2)。

安全な通信がしたいときに(3)、まずブラウザはウェブサーバから証明書を送ってもらい、そこに押された判子を見ます(4)。そして、その判子を押したCAが、自分のルート証明書のリストに含まれていることを確認します(5)。このときに、証明書に書かれたドメインネームや有効期限についてもあわせてチェックします。

ここで何か一つでも問題があれば、赤いバッテンとかで警告されてしまうわけです。

MITM攻撃

それでは、具体的にSuperfishが何をやっているか見てみます。

ざっくり言うと、2つのことをやっています。

  1. ブラウザとウェブサーバの間の通信を乗っ取るプログラムを動かす
  2. ブラウザに、乗っ取り用のルート証明書を追加する

やはり最初にブラウザがウェブサーバから証明書を送ってもらうのですが(1)、Superfishがその通信を横取りしてしまいます。

Superfishは、そのプログラムの中に小さなCAを持っていて、ブラウザが通信しようとしていたウェブサーバのドメインネームでニセの証明書を作成し、Superfish CAの判子を押してブラウザに返します(2)。本来ならばSuperfish CAなんて得体の知れないCAは信頼されていないので警告が出るのですが、Microsoftの決めた基準に反して、Lenovoが勝手にこのSuperfish CAを信頼するように設定してPCを販売しています。

そのため、ブラウザはSuperfish CAの判子が押された証明書を信じてしまうわけです(3)。

こうなってしまえばもうSuperfishのやりたい放題で、一旦そこで暗号も解かれてしまうので、あらためて本来の通信先ウェブサーバから取得したHTMLにJavaScriptを組み込んでブラウザに返すことができるようになります(4)。

このように、ブラウザとサーバの間に入り込んで暗号化を攻撃するため、MITM──すなわち、Man-in-the-Middle 攻撃と呼ばれています。

Superfishの問題点

TLSの暗号化は、以下のような前提があって初めて機能します。

  1. ブラウザは、信頼できるCAのルート証明書の一覧を持っている
  2. CAの判子(署名)は、第三者が勝手に押せないよう「CAの秘密鍵」を秘密にしなければいけない
  3. サーバは、その秘密鍵を秘密にしている (CAですら各ウェブサーバの秘密鍵のデータは知らない!)

ところが、ブラウザに勝手に追加されてしまったSuperfish CAは、その秘密鍵を適切に管理していません。具体的には、なんとそのPC上に組み込まれたSuperfishのプログラム内にあります!これは、通信時にリアルタイムでニセの証明書を作って判子を押すために仕方無いことではあります。さらに、このSuperfish CAの秘密鍵や証明書はあらかじめ用意されたもので、全世界すべてのSuperfishで共通のものが使われていました。

となれば、あとは様々なソフトウェアのクラック技術を使えば、誰かのPC上に保存されたプログラムを調べるだけでSuperfish CAの秘密鍵を取得することができます。

恐ろしいことに、Lenovoが紹介している対応方法(電子証明書を利用したWEBサイトにログインできないについてのお知らせ)では、Superfishの通信を書き換えてMITM攻撃をしているプログラムは停止、削除しますが、ブラウザに登録されたSuperfish CAのルート証明書は削除をしません。


これが最悪です。

何が起こるか

ブラウザにはSuperfish CAとやらのルート証明書が信頼できるCAとして登録され、このCAの秘密鍵は誰もが知ることができます。

何が起こるかと言えば、誰でも勝手にウェブサーバの証明書を作成して判子を押して、ブラウザに信頼してもらうことができます。

さらに言えば、Windowsではソフトウェアにも判子による作成者チェックがありますが、それすらもすり抜けることができ、たとえば別の手段を併用してWindows Updateに紛れ込ませることで、OSのコンポーネントを差し替えることすら可能かもしれません(あくまで可能性レベルで未検証です)。

こうなってしまえば暗号化も電子署名も何もあったものでは無く、TLSとかSSLとか無かった1990年代初頭に逆戻りです。Heartbleedも裸足で逃げ出すレベル。

そのほかのリスク

また、SuperfishプログラムによるMITM攻撃そのものにも問題があります。本来はウェブサーバの証明書に押された判子の確認(サーバ証明書の検証)をSuperfishプログラムがやっているわけですから、ウェブサーバが送ってきているはずの正しい証明書をブラウザは知ることができません。

そのため、例えば様々な追加情報を表示してくれるはずのEV証明書(いわゆるアドレスバーが緑に染まる奴)も機能しませんし、Superfishの実装が手抜きをしていれば、本来期限切れや、さらに別の第四者による攻撃など別の理由でエラーとなるはずの誤った証明書を知らずに受け付けてしまう可能性もあります。

あとは、Superfishが本来のウェブサーバにアクセスしている暗号化通信に関しても、適切な設定が行われていれば同等ですが、もしブラウザよりも実装の品質が低い場合、暗号化通信の内容自体が解読されやすくなっている可能性もあります(例: DHEにブラウザは対応していたはずなのにSuperfishが非対応のためPFS性が無くなっていた、など)。これはあくまで未検証ですので可能性の話にすぎません。このあたりは、続報が出てくるまで冷静に注視が必要と思います。

どうすれば「まだまし」だったのか

例えばウィルス対策ソフトなど、使用者の適切な同意があったうえでどうしても通信内容を見たいのであれば、ウェブサーバ側から来た証明書のチェックをブラウザと同じように適切に行った上で、Superfish CAのような全世界で共通なんて手抜きをせず、PC別ユーザ別に秘密鍵を生成するのであれば、あきらかな脆弱性ではなくなります。また、EV証明書なども、動的に作るニセ証明書をうまく作り込むことで「それっぽく」見せることは可能かもしれません。

とはいえ、それでもセキュリティ上のリスクが大きく拡大するのは確かなので、MITMなんて手法に頼るのは可能な限り避けるべきだと個人的には考えます。

どうすれば良いか

既にチェックサイトが用意されているので、まずは確認しましょう。

自分のブラウザにSuperfish CAが登録されていなければ、「Good, Superfish is probably not intercepting your connections.」など安全そうな表示が出ることでしょう。表示内容は執筆時点のものなので今後変わる可能性があるのでちゃんと文章を読んでください。

もしSuperfish CAが登録されてしまっていた場合には、ルート証明書を削除する必要があります。
手順についてはたぶん明日になればどっかから出てくと思うのでそれを見てください……。

(2015-02-20 11:22追記) 英語サイトではWindows 8でのルート証明書削除方法が載ったようです。

細かい補足

  • 実際には、今回ターゲットとされているWindowsでは、IEChromeはブラウザ個別ではなく、Windowsが提供しているルート証明書のストアを共用しています。Windows Updateなども対象となる可能性があるのはこのためです。その一方でFirefoxはOSに依存せず個別に持っています。
  • 「判子」まわりは当然ながら公開鍵と電子署名のメタファですが、細かく厳密に書くと一冊の本ができあがるので、今回をきっかけに興味を持った方には以下の本を紹介します。
  • 基本的に、開発者のデバッグ用途を超えるような、特に一般利用者向けのMITMは腹を切って死ぬべきだという立場です。なぜならそのリスクを利用者に十分に説明することが現実的では無いからです。
  • MITM攻撃は、日本語としては中間者攻撃とも呼ばれます。ただでさえ簡略化した説明なので、先入観が無い方が良いという考えから敢えてこちらで表記しています。

Changelogs

InfluxDB のダウンサンプリングの両端

  • N分間隔のダウンサンプリングすると、過去方向のタイムスタンプで丸め込まれる。
    • したがって、5分間隔の取得なら5mで集計しておけば5分間隔の過去側の時刻に正規化できる。
  • time > N や time < N には N が含まれる
    • 不等号は≧≦として扱う。
    • きっかり両端の時刻のデータがあると含まれてしまうので、ダウンサンプリング済みのデータを扱う場合に考慮する。

テストデータ

  • 00:00:00 と 00:30:00 に 0
  • 00:00:10 から5分おきに1から徐々に増える
  • うっかりJSTでやっちゃったので、クエリでは9時間引いているので注意
時刻 time v
2015-01-01 00:00:00 JST 1420038010000 0
2015-01-01 00:00:10 JST 1420038010000 1
2015-01-01 00:05:10 JST 1420038310000 2
2015-01-01 00:10:10 JST 1420038610000 3
2015-01-01 00:15:10 JST 1420038910000 4
2015-01-01 00:20:10 JST 1420039210000 5
2015-01-01 00:25:10 JST 1420039510000 6
2015-01-01 00:30:00 JST 1420039800000 0
2015-01-01 00:30:10 JST 1420039810000 7
2015-01-01 00:35:10 JST 1420040110000 8
2015-01-01 00:40:10 JST 1420040110000 9

検証

SELECT time,mean(v),min(v),max(v) FROM a where time > '2014-12-31 15:00:00.000' and time < '2014-12-31 15:30:00.00' group by time(5m);

時刻 time mean min max
00:00:00 1420038000000 0.5 0 1
00:05:00 1420038300000 2 2 2
00:10:00 1420038600000 3 3 3
00:15:00 1420038900000 4 4 4
00:20:00 1420039200000 5 5 5
00:25:00 1420039500000 6 6 6
00:30:00 1420039800000 0 0 0

00:30:00として、00:30:00のポイントを含む集計値が含まれている。

SELECT time,mean(v),min(v),max(v) FROM a where time > '2014-12-31 15:00:00.000' and time < '2014-12-31 15:35:00.00' group by time(5m);

時刻 time mean min max
00:00:00 1420038000000 0.5 0 1
00:05:00 1420038300000 2 2 2
00:10:00 1420038600000 3 3 3
00:15:00 1420038900000 4 4 4
00:20:00 1420039200000 5 5 5
00:25:00 1420039500000 6 6 6
00:30:00 1420039800000 3.5 0 7

SELECT time,mean(v),min(v),max(v) FROM a where time > '2014-12-31 15:00:00.000' and time < '2014-12-31 15:30:00.00' group by time(15m);

時刻 time mean min max
00:00:00 1420038000000 1.5 0 3
00:15:00 1420038900000 5 4 6
00:30:00 1420039800000 0 0 0

SELECT time,mean(v),min(v),max(v) FROM a where time > '2014-12-31 15:00:00.000' and time < '2014-12-31 15:35:00.00' group by time(15m);

時刻 time mean min max
00:00:00 1420038000000 1.5 0 3
00:15:00 1420038900000 5 4 6
00:30:00 1420039800000 3.5 0 7

glibcを更新しても大丈夫な「正しい」タイムゾーンの設定方法 (2/3追記あり)

RHEL, CentOS, Amazon Linux (6以前)

/etc/localtime を /usr/share/zoneinfo 以下から上書きしたりシンボリックリンク張ったりという手法が横行していますが、 /etc/localtime は glibc パッケージに含まれるためパッケージを更新すると上書きされてESTとかに戻ってしまうわけです。

当然ながら、ディストリビューションとして正しい設定方法が用意されているので、こちらを使います。

  1. /etc/sysconfig/clock にタイムゾーンを書きます。*1
    sudo sed -i -e "s/^ZONE/#ZONE/g" -e "1i ZONE=\"Asia/Tokyo\"" /etc/sysconfig/clock
  2. tzdata-update を実行します。
    sudo /usr/sbin/tzdata-update

これだけです。glibcのパッケージをアップデートした時にも、glibc-commonのトリガスクリプトとしてtzdata-updateが自動で呼ばれます。sysconfigで設定してコマンドで現状に反映させるという普通のRHELの世界観そのままですね。

ちなみに、よりRHELの世界観に沿うために、CUIのグラフィカルインターフェースとして system-config-date が用意されていますが、忘れて良さそうな気がします。

(補足) EL7以降というかsystemd系ディストリビューションはtimedatectl(man)使うとのこと。

Ubuntu, Debian GNU/Linux

Debian系というぐらいでdebconf ベースですが、 /etc/timezone を参照してdebconfのデータベースに反映してくれるようになっています。Debianは使っていないので未確認ですが、同じで良いとのこと。

  1. /etc/timezone にタイムゾーンをベタで書きます。
    echo "Asia/Tokyo" | sudo tee /etc/timezone
  2. dpkg-reconfigureでdebconfの設定処理を走らせます。
    dpkg-reconfigure --frontend noninteractive tzdata

CUIでカーソル選択とかしたくない人がほとんどだと思うので、 noninteractive 積極的に使っていきましょう。

ディストリの世界観

今回の「glibc更新するとタイムゾーンがリセットされる!?」とかそうですが、普通に作業して明らかに面倒とか不便とか問題があったら、そのまま回避策を採るのでは無く、まずその設定方法がディストリビューションの世界観に沿っているかを疑ったほうが「急がば回れ」になります。

というか、こういうの探すときに、「ディストリビューションが提供しようとしている世界観」を意識するかどうかで探し方全然変わるので、誰かまとめて欲しい。

超ざっくりこれ:

  • EL系: 設定は/etc/sysconfig 以下に書く。反映方法は割と適当。
  • Debian系: 設定は debconf のデータベースに登録し、dpkg-reconfigureで反映
  • systemd系: なんちゃらctl
  • Gentoo: emergeがなんとかしてくれる

追記: 2015-01-31 01:21

/etc/sysconfig/clock の既存設定を残すよう、tee -a に変更しました。
「正しい」とか煽りながら非互換だしていてすみませんorz

さらに追記 2015-02-03 17:12

tzdata-update は、/bin/sh等に依存しないようにC言語で書かれた小さなプログラムなのですが、最初のZONE指定が有効になるようです*2。安易にtee -aで追記にしたら反映されないというご指摘を頂きました。

sysconfig 以下のファイルは通常はシェルスクリプトとして解釈されるという思い込みがあったのですが、記事修正するときに検証を怠った結果がこれです。
ざっと確認した範囲では見つけられなかったのですが、自前で /etc/sysconfig/clock を呼んでいるシェルスクリプトがあると危険なので、記事無いの置換コマンドは、単純な追記で無く既存のZONE行を潰してから先頭に追記するようにしました。

というわけで、/etc/sysconfig の一般的な文法(これも「世界観」の一部)から外れることもあるので、盲信せずきちんと検証しましょうという良い教訓でした。記事書いて良かった……。

*1:tzdata-update は最初の記述が有効になりますが、シェルスクリプトとして他のソフトウェアから読まれる可能性があるため、他のZONE行は消して置いた方が良いと思います。

*2:たぶんこの辺。見つかったら即breakしてる。 https://www.sourceware.org/git/gitweb.cgi?p=glibc.git;a=blob;f=fedora/tzdata-update.c;h=33bb8c67e379c88dc4af0fcbf5dc33c55973302f;hb=9da0dd7c81b1cedd383e0eba09c9452d2874f862

あけましておめでとうございます

今年で35歳を迎えるので、引き続きフルスタックエンジニア目指して頑張ります*1

今年の抱負

「明確な成果を出す」
細かい目標はあとで決めます。

読書目標

昨年は無事500冊の目標を505冊で達成できた*2ので、今年も500冊目指して読みます。
ただラノベに偏りすぎたので、サブKPIをいっこ追加で。

  • 月40冊
  • 追加: 技術書(雑誌除く) 10%

ブクログだけだと達成管理できないのどうしようかなあ。