Libc 保護
Tip
AWSハッキングを学び、実践する:
HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。
チャンク整列の強制
Malloc はメモリを 8バイト(32-bit)または16バイト(64-bit)の単位で割り当てます。つまり32ビット環境ではチャンクの終端は 0x8 に、64ビット環境では 0x0 に整列するべきです。このセキュリティ機能は、bin からポインタを使う前に各チャンクがこれらの特定位置で 正しく整列しているか をチェックします。
セキュリティ上の利点
64-bit システムでのチャンク整列の強制は、偽チャンクを置ける場所を 16アドレスにつき1箇所だけ に制限することで Malloc のセキュリティを大幅に向上させます。これは特に入力値の制御が限られている状況での悪用を困難にし、攻撃をより複雑で成功しにくいものにします。
- Fastbin Attack on
__malloc_hook
Malloc の新しい整列ルールは、__malloc_hook を狙った古典的な攻撃も阻止します。以前は攻撃者がチャンクサイズを操作してこの関数ポインタを 上書き し、コード実行 を得ることができました。現在では厳密な整列要件によりそのような操作は実行不可能になり、一般的な悪用経路が閉じられて全体のセキュリティが向上します。
注意: glibc 2.34 以降、レガシーフック(
__malloc_hook,__free_hookなど)はエクスポートされた ABI から削除されています。モダンなエクスプロイトは他の書き込み可能な関数ポインタ(例: tcache per-thread struct、vtable-style callbacks)を狙うか、setcontext、_IO_list_allといったプリミティブに依存するようになっています。
fastbins と tcache における Pointer Mangling
Pointer Mangling はメモリ管理での fastbin および tcache の Fd ポインタ を保護するためのセキュリティ強化です。この技術は、特にメモリのleakを必要としない、あるいは既知の位置に対する相対操作(相対的な overwrites)でメモリ位置を直接操作するタイプの攻撃を防ぐのに役立ちます。
この技術の核心は次の難読化式です:
New_Ptr = (L >> 12) XOR P
- L はポインタの 格納場所 です。
- P は実際の fastbin/tcache Fd ポインタ です。
XOR 演算の前に格納場所 (L) を右に 12 ビットシフトする理由は重要です。この操作は、システムアーキテクチャの制約により通常予測可能なメモリアドレスの下位12ビットという決定論的性質に起因する脆弱性に対処します。ビットをシフトすることで予測可能な部分を式の外に移動させ、新しい mangled ポインタのランダム性を高め、これらのビットの予測可能性に依存するエクスプロイトから保護します。
この mangled ポインタは既存のランダムネス、つまり Address Space Layout Randomization (ASLR) によって提供されるランダム性を活用します。ASLR はプログラムで使用されるアドレスをランダム化し、攻撃者がプロセスのメモリレイアウトを予測しにくくします。
mangled ポインタを元のアドレスに戻す(Demangling)には同じ XOR 演算を用います。ここでは mangled ポインタを式の P として扱い、変更されていない格納場所 (L) と XOR することで元のポインタが復元されます。マンリングとデマンリングの対称性により、システムは大きなオーバーヘッドなしにポインタのエンコード/デコードを効率的に行え、ポインタ操作に依存する攻撃に対して大幅な防御力を提供します。
セキュリティ上の利点
Pointer mangling はヒープ管理における部分的および完全なポインタ上書きを防ぐことを目的としており、セキュリティを大きく向上させます。この機能はいくつかの攻撃手法に影響を与えます:
- Prevention of Bye Byte Relative Overwrites: 以前は攻撃者がポインタの一部を変更して、正確なアドレスを知らなくともヒープチャンクを別の場所へリダイレクトすることができました(leakless の House of Roman のような手法)。Pointer mangling により、そのような相対的な overwrites は heap leak がない状態ではブルートフォースが必要になり、成功率が大幅に下がります。
- Increased Difficulty of Tcache Bin/Fastbin Attacks: fastbin や tcache エントリを操作して関数ポインタ(例:
__malloc_hook)を上書きする一般的な攻撃が困難になります。例えば、LibC アドレスを leak してチャンクを tcache bin に free し、Fd ポインタを書き換えて__malloc_hookにリダイレクトするような攻撃は、Pointer mangling があるため正しく mangled されたポインタが必要となり、正確な操作には heap leak が必要となってエクスプロイトのハードルが上がります。 - Requirement for Heap Leaks in Non-Heap Locations: stack、.bss セクション、または PLT/GOT といった non-heap 領域に偽チャンクを作る際も、pointer mangling のために heap leak が必要 になります。これによりこれら領域を悪用する難易度が上がり、LibC アドレス操作と同様の複雑さが必要になります。
- Leaking Heap Addresses Becomes More Challenging: Pointer mangling は fastbin や tcache ビン内の Fd ポインタをヒープアドレスの leak ソースとして使う有用性を制限します。ただし、unsorted、small、large のビンにあるポインタは unmangled のままであるため、依然としてアドレス漏洩に利用可能です。この変化により攻撃者はこれらのビンを探索する方向に追いやられますが、一部の手法では制約はあるものの leak 前にポインタをデマンリングできる可能性も残されています。
Safe-Linking Bypass (page-aligned leak scenario)
Safe-Linking が有効でも(glibc ≥ 2.32)、mangled ポインタを leak でき、かつ破壊されたチャンクと被害者チャンクが同じ 4KB ページを共有している場合、元のポインタはページオフセットだけで復元できます:
// leaked_fd is the mangled Fd read from the chunk on the same page
uintptr_t l = (uintptr_t)&chunk->fd; // storage location
uintptr_t original = (leaked_fd ^ (l >> 12)); // demangle
This restores the Fd and permits classic tcache/fastbin poisoning. If the chunks sit on different pages, brute-forcing the 12-bit page offset (0x1000 possibilities) is often feasible when allocation patterns are deterministic or when crashes are acceptable (e.g., CTF-style exploits).
Heap Leak を用いたポインタのデマングリング
Caution
このプロセスのより詳細な説明については check the original post from here を参照してください。
アルゴリズム概要
The formula used for mangling and demangling pointers is:
New_Ptr = (L >> 12) XOR P
Where L is the storage location and P is the Fd pointer. When L is shifted right by 12 bits, it exposes the most significant bits of P, due to the nature of XOR, which outputs 0 when bits are XORed with themselves.
主な手順:
- 初期的な最上位ビットの取得: シフトした L と P を XOR することで、シフト部分がゼロになるため P の上位 12 ビットが事実上得られます。
- ポインタビットの復元: XOR は可逆的なので、結果と一方のオペランドが分かっていればもう一方を算出できます。この特性を使い、既知のビット列をマングルされたポインタの部分と順次 XOR して P の全ビットを推測します。
- 反復的デマングリング: 前のステップで得られた P の新しいビットを利用して次のセグメントを復号することを繰り返し、全ビットが回復されるまで続けます。
- 決定論的なビットの扱い: L の最下位 12 ビットはシフトによって失われますが、これらは決定論的であり、処理後に再構築できます。
このアルゴリズムの実装は次にあります: https://github.com/mdulin2/mangle
Pointer Guard
Pointer Guard は、特に atexit() のようなライブラリ呼び出しで登録される格納された関数ポインタを保護するために glibc で使用されるエクスプロイト緩和技術です。この保護は、ポインタをスレッドデータ (fs:0x30) に保存されたシークレットと XOR し、ビット単位の回転を適用してスクランブルすることを含みます。この仕組みは、攻撃者が関数ポインタを上書きして制御フローをハイジャックするのを防ぐことを目的としています。
Bypassing Pointer Guard with a leak
- Pointer Guard の動作理解: ポインタのスクランブル(マングリング)は
PTR_MANGLEマクロによって行われ、ポインタを 64 ビットのシークレットと XOR した後、0x11 ビットの左ローテートを行います。元のポインタを回復する逆操作はPTR_DEMANGLEによって処理されます。 - 攻撃戦略: この攻撃は既知平文アプローチに基づきます。攻撃者はマングルされる前のポインタ(平文)とマングル後のポインタの両方を知る必要があり、それによってマングリングに使われたシークレットを導き出します。
- 既知平文の悪用:
- 固定された関数ポインタの特定: glibc のソースコードや初期化済みの関数ポインタテーブル(例:
__libc_pthread_functions)を調べることで、予測可能な関数ポインタを見つけられます。 - シークレットの算出:
__pthread_attr_destroyのような既知の関数ポインタと、関数ポインタテーブルから得られるそのマングル済みバージョンを使い、マングル済みポインタを右回転(逆回転)し、その結果を関数のアドレスと XOR することでシークレットを計算できます。
- 代替平文: 攻撃者は 0 や -1 のような既知値でポインタをマングルしてみて、メモリ内で識別可能なパターンが現れるかを調べることで、メモリダンプ中にこれらのパターンが見つかればシークレットを明らかにできる可能性があります。
- 実用上の適用: シークレットを算出した後、攻撃者はポインタを制御された方法で操作でき、libc ベースアドレスを知って任意のメモリを読む能力があれば、マルチスレッドアプリケーションにおける Pointer Guard を実質的にバイパスできます。
GLIBC_TUNABLES と最近のローダーバグ
The dynamic loader parses GLIBC_TUNABLES before program startup. Mis-parsing bugs here directly affect libc before most mitigations kick in. The 2023 “Looney Tunables” bug (CVE-2023-4911) is an example: an overlong GLIBC_TUNABLES value overflows internal buffers in ld.so, enabling privilege escalation on many distros when combined with SUID binaries. Exploitation requires only crafting the environment and repeatedly invoking the target binary; pointer guard or safe-linking do not prevent it because corruption happens in the loader prior to heap setup.
References
Tip
AWSハッキングを学び、実践する:
HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。


