こんにちは、or2です。
最近サイドチャネル攻撃の一種、電力解析(PowerAnalysis)という攻撃の実験をしていました。
非常に面白いもので、デバイスの消費電力から内部動作を推定したり、扱っているデータを推測することができます(条件はありますが)。
「消費電力から内部のことなんてわかるはずない!」などと侮っていたのですが、現実的な時間で重要な情報を特定できることがわかりました。
今回は電力解析の一種、Simple Power Analysis(SPA)についての実験結果をまとめたいと思います。
攻撃対象は自作したパスワード認証をのせたAtmega328pです。
※Atmega328pはArduinoに搭載されているマイコンです。
免責事項
当記事の内容は教育・学習およびセキュリティの向上目的で執筆されており、サイバー攻撃行為を推奨するものではありません。 第三者が所有する資産に管理者の許可なく攻撃行為を行うと各種の法律に抵触する可能性があります。 当記事の内容を使用して起こるいかなる損害や損失に対し、当社は一切責任を負いません。
※当記事の検証では、自身で作成したパスワード認証ファームウェアを使用しております。当記事で紹介している手法を試行する際は、自身の所有する環境に対して実施してください。
構成
今回の実験はAtmega328pに脆弱なパスワード認証ファームウェアを実装し、ハードコードされているパスワードを消費電力から推定していきます。
パスワードはUARTで入力し、
正しいパスワードを入力した場合はPasswd OK!!!
。
間違っている場合はPasswd Invalid!!!
を出力するようにしています。
また、Atmega328pはパスワード入力を検知すると特定のPinをHighにするように設計しているので、これをトリガーとして利用します。
消費電力の測定はChipWhisperer Liteを使いました。オシロスコープで測定することもできます。(測定デバイスのクロック周波数に対して十分な測定能力があれば何でも大丈夫です。)
電源は安定化電源を使います。
消費電力の変化は非常に小さいので、なるべくノイズが乗らないように構成することが重要になります。(安定化電源を使いましょう)
※ChipWhisperer: サイドチャネル攻撃(電力解析、フォルトインジェクション)を目的に作られたOSSの攻撃ツールです。
ごちゃごちゃしていますが物理配線は以下のようになります。
図1. 物理配線図
脆弱なパスワード認証
今回実装したパスワード認証は受け取った平文のパスワードとハードコードされている平文のパスワードを1文字ずつ比較するように設計しています。
この実装が原因でSPAに対して脆弱で、消費電力からパスワードが推定できるようになっています。
攻撃手法
電力解析には3つの有名な攻撃があります。
- SPA(Simple Power Analysis)
- 消費電力の特徴から内部で行っていることを推測する攻撃
- 実行している命令から生じる消費電力の差を見る方法です
- 命令によって発生する消費電力の差は比較的大きいため、ある程度のノイズであれば気にしなくてもよいです
- 消費電力の特徴から内部で行っていることを推測する攻撃
- DPA(Differential Power Analysis)
- 消費電力から扱っているデータを推測する攻撃
- デバイスが扱っているデータによって発生する消費電力の差を見る方法です
- データによって発生する消費電力の差はかなり小さいので、ノイズの影響を大きく受けます
- ノイズの影響をかき消すために大量の測定をして平均をとります
- 消費電力から扱っているデータを推測する攻撃
- CPA(Correlation Power Analysis)
- DPAの高効率版
- 統計的手法(相関分析)によって測定回数を大幅に減らすことができます
- DPAの高効率版
今回はSimple Power Analysis(以下SPAと略します)を扱っていきます。
消費電力とサンプリングポイント(時間)のデータのことをトレースと言うので、以後はこれをトレースと呼んでいきます。
SPAの補足
この攻撃ではデバイス(CPU)が実行している命令によって消費電力の差が発生することを利用し、デバイスが内部で何をやっているかを推測します。
まずは「なぜ実行する命令によって消費電力の差が発生するか」を簡単にまとめます。
これは命令によって利用しているHWが異なるからです。
add命令
とmov命令
の違いを考えてみます。
add命令
は2つのレジスタ
の値をALU(演算装置)
で加算し、その結果をレジスタ
に格納します。
mov命令
はあるレジスタ
から別のレジスタ
に値をコピーします。
両者では利用するHWがそもそも違いますし、処理のフローも異なります。
単純に考えると、add命令
の方がALU(演算装置)
を使う分消費電力が大きくなりそうですよね?
次に、命令の違いから機密情報を特定できる可能性があるロジックについてまとめます。
デバイスにパスワードを入力した時、以下の処理を行っていると考えます(今回の脆弱な実装と同じです)。
- パスワードを先頭から1文字ずつチェックし、ハードコードされている正しいパスワードと比較する
この時、パスワードの1文字目が正しい時/正しくない時の動作には以下の違いがあります。
- 1文字目が正しい時
- 2文字目のチェックに移行する
- 1文字目が間違っている時
- エラー処理に移行する
この処理の違いを「命令の違いから生じる消費電力の差」として観測することが可能というわけです。
SPAは「消費電力から実行している命令の特徴を推定し、内部の処理・状態を推測する」攻撃です。
つまり、デバイスが実行している命令の違いで内部で扱っている機密情報を特定できるような条件分岐がある場合、SPAに対して脆弱であるということになり、今回の実験がこれに該当します。
DPA/CPAの補足
ここでは詳しい説明を割愛します。
本記事の続編でこれらの攻撃についても書く予定ですので、そちらをお待ちくださいませ!
ちなみに弊社の別の情報媒体LAC WATCH
からCPA(Correlation Power Analysis, 相関電力解析攻撃)についての解説記事が出ています。
ご興味があればぜひ読んでみてください。
https://www.lac.co.jp/lacwatch/people/20180601_001617.html
実験
パスワードに関する情報が全く分からない状態からスタートし、以下のフローでパスワードの推定を進めていきます。
- パスワード長の特定
- パスワード1文字目の特定
- パスワード全体の特定
パスワード長の特定
パスワード長の特定のため任意の桁数のパスワードを入力して、その時の消費電力の特徴を見ていきます。
もし間違って1文字目が正しいパスワードと一致してしまったら期待するデータが取れない可能性があるので、入力する文字コードは普段使われないもの("\x01"
)を選択しました。
パスワードフォーマットは以下です。
"\x01" * n(nはパスワード桁数で、1~15とします)
実行結果は以下のプロットです。
プロットの見方ですが、縦軸が消費電力(に比例した値)、横軸が時間です。
今回の設定ではサンプリングレートを128M samples/secとしているので、約7.8n秒ごとに1点測定しています。
図2. 異なるパスワード長のトレース 全体像(パスワード長の特定)
図3. 異なるパスワード長のトレース 特異なトレース(パスワード長の特定)
図2のトレースを拡大して丁寧に見ていくと図3が現れました。
パスワード長を8桁に設定した時、ほかの桁数と比べてトレースが特異な状態にあるため、なにやら特別な処理をしていることを示唆しています。
これによりパスワード長が8桁である可能性が高いと想定できます。
次にパスワード長8桁と仮定してパスワード1文字目を総当たりしてみます。
パスワード1文字目の特定
8文字のパスワードのうちの1文字目を特定していきます。
ターゲットに入力するパスワードフォーマットは以下です。
もし「パスワード1文字目」が正しい場合は2文字目のチェックに遷移するトレースが、間違っている場合はエラー処理に遷移するトレースが取得できることを期待します。
「パスワード1文字目」 + "\x01" * 7
また、ここではちょっとしたテクニックを使います。
先ほどと同じように一つずつトレースをチェックするのもいいのですが面倒です。
なのでトレースの差分を見ていくことにします。
何の差分かというと、絶対に間違っているパスワードを入力した場合のトレースと、試したいパスワード(の1文字目)を入力した時のトレースの差分をとります。
最後に差分トレースの積分をとれば、特異なトレースを示した場合に値が大きくなることが期待できます。(積分はとらず、トレースの差分をプロットして目で確認してもいいです。)
これを実行したのが図4、積分したのが図5です。
図4. 差分トレース(パスワード1文字目の特定)
図5. 差分トレースの積分値(パスワード1文字目の特定)
図5から最も特異なトレースを示したのがp
であることが特定できました。
実験環境によって以下の工夫をするとよいです。
- 何度かトレースをとって平均する
- 積分するサンプリングポイントのレンジを調整する
- ノイズの影響が小さくなるように、目的の差分が現れるポイントに目星を付ける
- 大きな差分が取れた上位何桁を正しいパスワードの候補として扱う
また、実はちょっとしたずるをしています。。。
今回設定したパスワードは英小文字のみで構成しているので、試行した文字もそれに合わせています。
本来は一般的にパスワードで利用可能な全ての文字で試した方がいいです。
パスワード全体の特定
あとは処理を自動化するだけ!
最も大きな差分の文字を正しいパスワードと仮定し、次のパスワード候補を探索していくという処理をパスワード長分ループさせます。
実行結果を図6に示します。
図6. パスワード全体の推測
最後に得られたパスワードをAtmega328pに入力してみると
成功です!
Passwd OK!!!
が出力されました!
図7. 得られたパスワードで認証
失敗例
当たり前ですが、トレースの処理が甘いとパスワードの推測に失敗します。
以下に失敗例を示します。
図8. 失敗例
パスワードの最後の文字がg
になっていますね。
一つ前で正解のパスワードの推定に成功していますが、裏では差分を計算する時の時間幅などのパラメータを微調整して、いい感じの差分が出るようにしています。
これはその調整がうまくできていないときの結果です。
おまけ
今回は消費電力からパスワードを特定する方法についてまとめましたが、デバイス(CPU)が放射する電磁放射(EM放射)からパスワードを特定することも可能でした。
この方法はまだまだ最適化ができておらず、今回と同じ構成でパスワードを特定するのに約50時間ほどかかりました。
ちなみに消費電力から測定する場合は1時間もかからないです。
EM放射で電力解析と同等のことができるとなれば面倒なデバイスの配線などを簡略化できるので、時間があるときにより洗練された方法を模索していきます!
対策
トレースの差異がわかりやすい処理(条件分岐など)に機密情報を組み込まないことが推奨されます。
また、今回の実装で言えばパスワードをハッシュ化するといった対策も有効です。
まとめ
サイドチャネル攻撃に関する日本語文献が少なくなかなか触れる機会がない分野ですが、SPAは簡単な原理に基づく攻撃方法でサイドチャネル攻撃の入り口として良い学習コンテンツだと思います。
ご興味のある方はぜひ、お気に入りのマイコンやデバイスで試してみてはいかがでしょうか!
参考
- Github chipwhisperer
- The Hardware Hacking Handbook by Colin O'Flynn and Jasper van Woudenberg
- 電力解析やフォルトインジェクションについて丁寧にまとめられた書籍です。
- Differential Power Analysis
- SPA/DPAについての理論を提唱した論文です。