KeePassはパスワードデータベースファイルを暗号化するだけでなく、メモリに保持されているパスワードも暗号化できることを確認しました。これは単なる例です。機密性の高い/個人データを扱う新しいプロジェクトを考えており、メモリ内のデータホールドも暗号化する必要があるかどうかを考えています。このプロジェクトはJava SEと追加のAndroidアプリケーションで実装されます。この特別な場合、クラウドやサーバーにデータは保存されません。 Androidからのデータは、Java SEデスクトップアプリケーションによってケーブル接続経由でインポートされます。
しかし、なぜこれが必要なのでしょうか。最新のオペレーティングシステムは仮想メモリ管理で動作しないので、ユーザー空間/ユーザーモードプロセスが他のプロセスメモリにアクセスすることはできませんか?
外部メモリアクセスを可能にするOSの脆弱性がある場合、それは単なる別の防衛線ですか?その場合、メモリアクセスを介してデータを盗むよりも、データファイルを盗み、ユーザーが入力したパスワードをキーロガーを使用して取得する方がはるかに簡単だと思います。
完璧な世界では、あなたは正しいです。RAMでデータを暗号化しておく意味はありません。 OSはプロセス間の強力な分離を維持する必要があります。RAMが別のプロセスに再割り当てされた場合、それをクリアします。攻撃モデルで、攻撃者が後でデバイスを盗んでハードディスク分析を行うことができる場合、 swap(またはswapをまったく使用しない。これは、フラッシュベースのストレージを備えたデバイスにとってより意味のある場合があります)。
オペレーティングシステムとシステム管理が人間の努力であり、本質的に完璧ではない現実的な世界では、RAMでデータを暗号化しておくことやOSnotスワップスペースにデータを書き込む(Unixのようなシステムでは、これはmlock()
で行われます)。 RAMのものは本当の防御というより心理的な儀式であり、その主な長所は開発者の気分を良くすることです。
とにかく、Javaでそれを行うことを気にしないでください。 ガベージコレクター は、オブジェクトをRAMに透過的にコピーします(これは最も効率的なGCアルゴリズムの一部であり、防止することはできません)。そのため、アプリケーションによる暗号化のレベルはありません。キーの明確なバージョンがRAM=に常に存在しないことを保証します。
最新のオペレーティングシステムは仮想メモリ管理で動作するため、デフォルトでは、ユーザー空間/ユーザーモードプロセスが他のプロセスメモリに直接アクセスすることはできません。
しかし、Windows(これがLinuxにも当てはまるかどうかはわかりません)には、標準ユーザーが同じ資格情報で実行されている他のプロセスのプロセスメモリにアクセスできるようにするインターフェイスがあります。
このインターフェースを使用するプログラムはたくさんあります。非常に簡単な例は HxD -他のプロセスのプロセスメモリを表示および編集できるフリーウェアの16進エディタです。
メモリは、次の方法で他のプロセスから見えるようになります。
malloc()
を実行して、以前に実行されていたプロセスに属する情報を取得できます(注 第8章 Linuxデバイスドライバー-特に最初の脚注)ページ)その結果、暗号化されていないメモリが他のプロセスから見えるようになる可能性があります。
これ は非常に興味深いリンクであり、この引用に注意してください。
ただし、このボラティリティは問題のコンピュータに大きく依存します。コンピュータが何も実行していない場合、匿名メモリが長期間持続する可能性があります。たとえば、一部のコンピュータでは、パスワードやその他の事前計算されたデータは、入力またはメモリにロードされた後、何日も簡単に復元されました
Java世界に固有の問題がいくつかあります。考慮する必要があります。技術的な問題が発生した場合、JVMのヒープダンプを作成するのが通常の習慣です。私はそのための専用UIを備えたアプリです。これは、たとえばメモリリークを見つけるために非常に役立つ可能性があります。そうです-そうです-そうです-機密情報がダンプに含まれます。注射:))...:X。または、管理ユーザーが好奇心旺盛な人であれば...:X
これは「理想的な世界」では起こらないはずです。
また、メモリ不足の例外をダンプするようにJVMを構成することもできます。 Java 1.4なので、次のようになります:
-XX:-HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=<path to dump file>
攻撃者は、メモリ不足でアプリをクラッシュさせるエクスプロイトを見つけ、ダンプを盗む別のエクスプロイト(ファイルパストラバーサルバグなど)を見つける可能性があります。
もう1つ考慮すべきことは、一部の機密データが何らかの形でアプリに侵入する必要があることです。したがって、特定の瞬間にそれをメモリに保持します。それについてあなたができることはほとんどまたは何もありません。しかし、あなたができることはそれをより速くきれいにすることです。たとえば、ユーザーパスワードを取得します。これをStringインスタンスに格納すると、ガベージコレクションのタイミングをあまり制御できなくなります。したがって、通常、Nice APIはそのようなデータを文字配列(char [])で処理し、使用後にゼロにできます。
Googleには、 RowHammer と呼ばれるエクスプロイトがあり、ユーザーはRAMに書き込まれているデータに隣接しています)の内容を読み取ることができます。RAMは、この悪用をさらに困難にします。
「ロウハンマー」は、メモリの行に繰り返しアクセスして、隣接する行でビットフリップを引き起こす可能性がある最近の一部のDRAMデバイスの問題です。選択したラップトップをテストしたところ、一部のラップトップで問題が発生していることがわかりました。この効果を利用する2つの有効な権限昇格エクスプロイトを構築しました。 1つのエクスプロイトは、非特権ユーザーランドプロセスとして実行されたときに、x86-64 Linuxでカーネル特権を取得するためにロウハンマーによって引き起こされたビットフリップを使用します。 Rowhammerの問題に対して脆弱なマシンで実行すると、プロセスはページテーブルエントリ(PTE)でビットフリップを引き起こすことができました。これを使用して、独自のページテーブルへの書き込みアクセスを取得し、すべての物理メモリへの読み取り/書き込みアクセスを取得できました。
この攻撃に対して脆弱なマシンの数、または修正可能な既存の脆弱なマシンの数は、はっきりとはわかりません。私たちのエクスプロイトは、x86 CLFLUSH命令を使用して、基礎となるDRAMへの多くのアクセスを生成しますが、x86以外のシステムでも他の手法が機能する可能性があります。
PTEベースのエクスプロイトが他のオペレーティングシステムで動作する可能性があることを期待しています。これは本質的にLinux固有ではありません。 PTEでビットフリップを引き起こすことは、悪用の1つの手段にすぎません。ビットフリップを利用する他の方法も実用的です。他のエクスプロイトは、Native Clientサンドボックスからエスケープすることでこれを示しています。
KeePassには特にchrome拡張機能があるため、他のChrome拡張機能はKeePassが使用しているのと同じメモリを読み取ることができます。OSのメモリ保護はそのためには役立ちませんしたがって、暗号化。
一般に、メモリ暗号化のもう1つの理由は、誰かがメモリにアクセスできるハードウェア攻撃があるためです。
補足: IntelとAMDはどちらも、機能としてRAM暗号化 を提供しています。
それが良い考えのように思える理由は、メモリに常駐している間にデータが盗まれるのを防ぎたいからです。これは、実際のデータベースのデータは(すべてのPIIがそうであるように)暗号化されていることを前提としていますが、処理中は暗号化されずにメモリ内に置かれます。これは、他のコメンテーターによって概説されているさまざまな理由で実行するのは非常に困難であり、アプリケーションがメモリ内の暗号化されたデータを処理する方法の点で、かなり複雑になります。
より適切で実現可能なソリューションは、データベース/システムへの適切なアクセス制御を確実にし、DBMSがSYSTEMなどの昇格されたアカウントではなく、「通常の」ユーザーアカウントで実行されるようにすることです。追加の検出制御もあります。機密性の高いテーブルなどの大規模な選択を調べ、異常なものについて報告するように構成できるDBMS監視ツールなどを導入できます。このようにして、大量のデータを取り出そうとしている選択またはプロセスがあるかどうかを確認できます。