# スタックキャナリー {% hint style="success" %} AWSハッキングの学習と練習:[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)\ GCPハッキングの学習と練習: [**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)
HackTricksをサポートする * [**サブスクリプションプラン**](https://github.com/sponsors/carlospolop)をチェック! * 💬 [**Discordグループ**](https://discord.gg/hRep4RUj7f)に参加するか、[**telegramグループ**](https://t.me/peass)に参加するか、**Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**をフォロー**してください。 * **ハッキングトリックを共有するためにPRを** [**HackTricks**](https://github.com/carlospolop/hacktricks) **と** [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) **のGitHubリポジトリに提出する。**
{% endhint %} ## **StackGuardとStackShield** **StackGuard**は、**EIP (Extended Instruction Pointer)** の前に特別な値である**キャナリー**を挿入します。具体的には、バッファオーバーフローから保護するために `0x000aff0d`(null、改行、EOF、復帰)を挿入します。ただし、`recv()`、`memcpy()`、`read()`、`bcopy()`などの関数は脆弱のままであり、**EBP (Base Pointer)** を保護しません。 **StackShield**は、**グローバルリターンスタック**を維持することで、StackGuardよりも洗練されたアプローチを取ります。このセットアップにより、オーバーフローが害を及ぼさないように、格納されたリターンアドレス(**EIP**)と実際のリターンアドレスを比較してオーバーフローの発生を検出できます。さらに、StackShieldはリターンアドレスを境界値と比較して、**EIP** が予想されるデータスペースの外を指しているかどうかを検出できます。ただし、この保護はReturn-to-libc、ROP(Return-Oriented Programming)、ret2retなどの手法によって回避できるため、StackShieldもローカル変数を保護しません。 ## **スタックスマッシュプロテクタ(ProPolice)`-fstack-protector`:** このメカニズムは、**EBP** の前に**キャナリー**を配置し、ローカル変数を再配置してバッファをより高いメモリアドレスに配置し、他の変数を上書きするのを防ぎます。また、スタック上に渡された引数をローカル変数の上に配置し、これらのコピーを引数として使用します。ただし、8つ未満の要素を持つ配列やユーザー構造体内のバッファを保護しません。 **キャナリー**は、`/dev/urandom` から派生したランダムな数値またはデフォルト値の `0xff0a0000` から派生したランダムな数値です。これは**TLS (Thread Local Storage)** に保存され、スレッド間で共有されるメモリスペースを持つことができます。これらの変数は最初に親プロセスからコピーされ、子プロセスはデータを変更することなくそのデータを変更できます。ただし、新しいキャナリーを作成せずに **`fork()`** を使用すると、すべてのプロセス(親プrocessと子プロセス)が同じキャナリーを共有するため、脆弱になります。 **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](bf-forked-stack-canaries.md) {% endcontent-ref %} * バイナリ内に興味深い **漏洩または任意の読み取り脆弱性** がある場合、それを漏洩する可能性があります: {% content-ref url="print-stack-canary.md" %} [print-stack-canary.md](print-stack-canary.md) {% endcontent-ref %} * **スタックに格納されたポインタを上書き** スタックがスタックオーバーフローに脆弱である場合、**上書きできる文字列や関数へのアドレスが含まれている可能性があり**、スタックキャナリーに到達する必要がなく脆弱性を悪用できるかもしれません。次を確認してください: {% content-ref url="../../stack-overflow/pointer-redirecting.md" %} [pointer-redirecting.md](../../stack-overflow/pointer-redirecting.md) {% endcontent-ref %} * **マスターキャナリーとスレッドキャナリーの両方を変更** キャナリーで保護されたスレッド関数内のバッファ **オーバーフロー** を使用して、スレッドの **マスターキャナリーを変更** できます。その結果、チェックには2つの同じキャナリーが使用されるため、対策は無効になります(変更された場合でも)。 さらに、キャナリーで保護された **スレッド関数** 内のバッファ **オーバーフロー** を使用して、TLSに保存された **マスターキャナリーを変更** できます。これは、スレッドのスタック内の **bof** を介してTLSが保存されているメモリ位置に到達できる可能性があるためです。\ その結果、チェックには2つの同じキャナリーが使用されるため、対策は無効になります(変更された場合でも)。\ この攻撃は、次の解説で実行されます:[http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads](http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads) また、[https://www.slideshare.net/codeblue\_jp/master-canary-forging-by-yuki-koike-code-blue-2015](https://www.slideshare.net/codeblue\_jp/master-canary-forging-by-yuki-koike-code-blue-2015) のプレゼンテーションも参照してください。これにより、通常 **TLS** は **`mmap`** によって保存され、**スレッド** の **スタック** が作成されるときにも `mmap` によって生成されると述べられており、前述の解説に示されているようにオーバーフローが可能になるかもしれません。 * **`__stack_chk_fail` のGOTエントリを変更** バイナリがPartial RELROを持っている場合、**GOTエントリの `__stack_chk_fail` を変更** して、キャナリーが変更されてもプログラムをブロックしないダミー関数にすることができます。 この攻撃は、次の解説で実行されます:[https://7rocky.github.io/en/ctf/other/securinets-ctf/scrambler/](https://7rocky.github.io/en/ctf/other/securinets-ctf/scrambler/) ## 参考文献 * [https://guyinatuxedo.github.io/7.1-mitigation\_canary/index.html](https://guyinatuxedo.github.io/7.1-mitigation\_canary/index.html) * [http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads](http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads) * [https://7rocky.github.io/en/ctf/other/securinets-ctf/scrambler/](https://7rocky.github.io/en/ctf/other/securinets-ctf/scrambler/) {% hint style="success" %} AWSハッキングの学習と練習:[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)\ GCPハッキングの学習と練習: [**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)
HackTricksのサポート * [**サブスクリプションプラン**](https://github.com/sponsors/carlospolop)をチェック! * 💬 [**Discordグループ**](https://discord.gg/hRep4RUj7f)または [**telegramグループ**](https://t.me/peass)に**参加**するか、**Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**をフォロー**してください。 * **HackTricks**と**HackTricks Cloud**のGitHubリポジトリにPRを提出して、ハッキングトリックを共有してください。
{% endhint %}