hacktricks/binary-exploitation/common-binary-protections-and-bypasses/stack-canaries/README.md

8.2 KiB
Raw Blame History

スタックキャナリー

htARTEHackTricks AWS Red Team Expert を通じてゼロからヒーローまでAWSハッキングを学ぶ

HackTricksをサポートする他の方法

StackGuardとStackShield

StackGuardは、EIPExtended Instruction Pointerの前に特別な値であるキャナリーを挿入します。具体的には、バッファオーバーフローから保護するために0x000aff0dヌル、改行、EOF、復帰を挿入します。ただし、recv()memcpy()read()bcopy()などの関数は脆弱のままであり、**EBPベースポインタ**を保護しません。

StackShieldは、グローバルリターンスタックを維持することで、StackGuardよりも洗練されたアプローチを取ります。このセットアップにより、オーバーフローが害を引き起こさないように、格納された実際のリターンアドレスと比較してオーバーフローの発生を検出できます。さらに、StackShieldはリターンアドレスを境界値と比較して、EIPが予想されるデータスペースの外を指しているかどうかを検出できます。ただし、この保護はReturn-to-libc、ROPReturn-Oriented Programming、ret2retなどのテクニックによって回避できるため、StackShieldもローカル変数を保護しません。

スタックスマッシュプロテクタProPolice-fstack-protector:

このメカニズムは、EBPの前にキャナリーを配置し、ローカル変数を再配置してバッファをより高いメモリアドレスに配置し、他の変数を上書きするのを防ぎます。また、スタック上に渡された引数を安全にコピーし、これらのコピーを引数として使用します。ただし、8つ未満の要素を持つ配列やユーザー構造体内のバッファを保護しません。

キャナリーは、/dev/urandomから派生したランダムな数値またはデフォルト値の0xff0a0000から取得されます。これは**TLSスレッドローカルストレージに保存され、スレッド間で共有されるメモリスペースを持つことができます。これらの変数は最初に親プロセスからコピーされ、子プロセスはデータを変更することなく自分のデータを変更できます。ただし、新しいキャナリーを作成せずにfork()**を使用すると、すべてのプロセス(親プロセスと子プロセス)が同じキャナリーを共有するため、脆弱になります。i386アーキテクチャでは、キャナリーはgs:0x14に、x86_64ではfs:0x28に保存されます。

このローカル保護は、攻撃に脆弱なバッファを持つ関数を特定し、これらの関数の先頭にキャナリーを配置し、最後にその整合性を検証するためのコードを挿入します。

Webサーバーがfork()を使用すると、キャナリーバイトを1バイトずつ推測するブルートフォース攻撃を有効にします。ただし、fork()の後にexecve()を使用すると、メモリスペースが上書きされ、攻撃が無効化されます。vfork()は、子プロセスが書き込みを試みるまで複製を作成せずに実行できるようにするため、プロセスの作成とメモリの処理に異なるアプローチを提供します。

長さ

x64バイナリでは、キャナリークッキーは**0x8バイトのqwordです。最初の7バイトはランダムで、最後の1バイトはヌルバイト**です。

x86バイナリでは、キャナリークッキーは**0x4バイトのdwordです。最初の3バイトはランダムで、最後の1バイトはヌルバイト**です。

{% hint style="danger" %} 両方のキャナリーの最下位バイトはヌルバイトです。これは、下位アドレスから来るスタックの最初のバイトであり、したがって文字列を読み取る関数はそれを読み取る前に停止します。 {% endhint %}

バイパス

キャナリーを漏洩してから、それを上書き(例:バッファオーバーフロー)する。

  • 子プロセスでフォークされた場合、1バイトずつブルートフォースできる可能性がある:

{% content-ref url="bf-forked-stack-canaries.md" %} bf-forked-stack-canaries.md {% endcontent-ref %}

  • バイナリ内に興味深い漏洩または任意の読み取り脆弱性がある場合、漏洩する可能性があります:

{% content-ref url="print-stack-canary.md" %} print-stack-canary.md {% endcontent-ref %}

  • スタックに格納されたポインタを上書き

スタックがスタックオーバーフローに脆弱であり、スタックキャナリーに到達する必要がない場合、文字列や関数へのアドレスが含まれている可能性があり、これらを上書きして脆弱性を悪用できます。次を確認してください:

{% content-ref url="../../stack-overflow/pointer-redirecting.md" %} pointer-redirecting.md {% endcontent-ref %}

  • マスターキャナリーとスレッドキャナリーの両方を変更

キャナリーで保護されたスレッド関数内のバッファオーバーフローを使用して、スレッドのマスターキャナリーを変更できます。その結果、チェックに使用される2つのキャナリーが同じであるため、対策は無効になります変更されていても

この攻撃は、次の解説で実行されます:http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads

  • __stack_chk_failのGOTエントリを変更

バイナリがPartial RELROを持っている場合、__stack_chk_failのGOTエントリを変更して、キャナリーが変更されてもプログラムをブロックしないダミー関数にすることができます。

この攻撃は、次の解説で実行されます:https://7rocky.github.io/en/ctf/other/securinets-ctf/scrambler/

参考文献

**HackTricks** * **HackTricks**および[**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud)のGitHubリポジトリにPRを送信して、あなたのハッキングテクニックを共有してください。