web-dev-qa-db-ja.com

カナリアをバイパスするホークスの手法について

カナリアをバイパスするためのこの参照を見つけました: http://sota.gen.nz/hawkes_openbsd.pdf

カナリアバイトをバイトごとにブルートフォースにすることをお勧めします。これがどのように機能するのかわかりません:「テクニックは、カナリアの各バイトを時間分析とともに個別にブルートフォースにすることです」。どのようにしてバイト単位で時間分析を行うことができますか?カナリア全体を一度に比較しませんか? 4バイトは1つの命令だけと比較されると思いました。

この攻撃は http://www.phrack.org/issues.html?issue=67&id=1 でも参照されています

5
mikezed

アイデアは、攻撃の長さを制御して、カナリアの最初のバイトのみを上書きすることです。次に、このバイトに対して256の可能な値をブルートフォースし、ある種のサイドチャネル図を使用して正しい値を算出できます。これを取得したら、2番目のバイトをブルートフォースし、カナリア全体を取得するまで続行できます。

4
paj28

このトピックも同様に私を混乱させました。そのPhrackの問題には、バッファオーバーランの長さをインテリジェントに制御することさえ言及している文が1つか2つしかありません(おそらくこれが典型的な手法であるためです)。 Paj28は正しい答えを持っているように見えますが、これを実際に機能させるのに十分な正確なサイドチャネルを取得する方法については、まだあいまいです。統計分析を行うために多数の試行が必要な場合、これは明らかに攻撃の有効性を低下させます(特に、すべての試行に対して新しいネットワーク接続とfork()システムコールが発生するリモートの場合)。

Common SSPメソッドは、保護されたセクションに格納されているプログラム全体の変数からスタックにコピーされる単一のカナリアを使用します。この初期化は実行可能ロード中に発生します。この初期化の3つの既知のバリアントは(a )exec *()syscall中のカーネルによる、(b)静的にリンクされた実行可能ファイルの起動コードによる、または(c)動的にリンクされた実行可能ファイルのランタイムイメージに挿入されるダイナミックローダーのコードフラグメントによる。

最も重要なのは、このバイト単位のトリックを無効にできることです。以下を検討してください。

{01} 1つの64ビットワードにスペースを割り当てる代わりに、スタックフレームに2つのワード長のスペースを残すことができます。そのような可変スロットの1つは、オーバーフローで変更できない可能性が高いバッファーの前に配置されます。

{02}関数プロローグを実行すると、固定カナリアをこれらの2つのスロットにコピーする代わりに、実際に2つの値から動的カナリアを導き出します(それら自体はある程度動的になる場合があります)。ほとんどの場合、ソース値は、古いカナリアが確立された方法と同様に、事前に初期化されたランダム保護メモリのブロックから取得されます。

{03}導出方法couldは暗号でさえも任意に強くできますが、この手法が機能する必要はありません。

{04}単純な戦略は、攻撃者の生活を非常に困難にする可能性があります。導出方法がA + B = Cのようなものであるとします。ここで、AとBは64ビットの疑似ランダム値です。チェック値であるCも同様に64ビットです。

{05}さて、攻撃者がカナリアを上書きしようとすると、Bにしか到達できません。下位の仮想アドレスに存在するため、スタックにそのまま残ります。

{06} A + B!= Cなので、予想通りカナリアチェックは失敗します。

{07}しかし、攻撃はBの最初のバイトを上書きすることから何を学びましたか? A + BがCと等しくないのは当然です。攻撃にはAおよびCが実際に何であるかについての情報がないため、これによりBに多数の可能な値が作成されます。

{08}このスキームでは、単純にWord値をバイトに細分し、それらすべてを個別に攻撃することはできません。モジュラー(ラッピング)演算の性質上、A [0] + B [0] = C [0]はA + B = Cを保証しません。下位バイトのビットは上位バイトに、上位バイトのビットはバイトは下位バイトにオーバーフローする可能性があります。攻撃者はBの最初のバイトが何であるかを理解できる可能性がありますが、後続の各バイトで大幅に難しくなります。

{09}この3つの64ビットWordの例を妥当な時間内に打ち破る手段が見つかるとすると、この概念は、モジュール式算術よりも洗練された、より多くの変数と関数の導出方法に任意に拡張されます。実際の使用に十分な速さであり、ほとんどすべてのもっともらしい攻撃を阻止するのに十分に安全なスキームがあることは、事実上自明のようです。

{10}カナリア入力を格納するためのメモリ領域を予約して確保すると、この手法はさらに改善されます。バッファオーバーランを検出するために実際にスタックに表示する必要があるのは、カナリア計算値の1つだけです。他のすべては他の場所に存在する可能性があるため、攻撃者が別の関数実行コンテキストでスタックをオーバーランした場合でも、簡単に読み取ることができません。

この攻撃や類似の攻撃から身を守るためにスタック破壊保護スキームを大幅に改善できることに私が最初に気づいたことはほとんどありません。私は、これを「念のため」の些細な概念実証として提示するだけです。

1
kagerato