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-byte (32-bit) または 16-byte (64-bit) のグループ で割り当てます。これは、32-bit システムではチャンクの末尾が 0x8 に整列し、64-bit システムでは 0x0 に整列することを意味します。セキュリティ機能は、bin からポインタを使用する前に各チャンクがこれらの特定位置で正しく整列しているかをチェックします。
セキュリティ上の利点
64-bit システムでのチャンク整列の強制は、偽チャンクの配置を16個に1つのアドレスに限定することで Malloc のセキュリティを大幅に向上させます。これにより、特に入力値の制御が限定される状況での悪用が複雑化し、攻撃の実行がより困難になります。
- Fastbin Attack on
__malloc_hook
Malloc の新しい整列規則は、__malloc_hook に関する古典的な攻撃も阻止します。以前は、攻撃者がチャンクサイズを操作してこの関数ポインタを上書きし、code execution を得ることが可能でした。現在は厳格な整列要件により、そのような操作はもはや実行可能ではなくなり、一般的な悪用ルートが閉じられて全体的なセキュリティが向上しています。
注: glibc 2.34 以降、レガシーフック(
__malloc_hook,__free_hook, など)はエクスポートされた ABI から削除されています。現代のエクスプロイトは代わりに他の書き込み可能な関数ポインタ(例: tcache per-thread struct、vtable-style callbacks)を狙うか、setcontext、_IO_list_allプリミティブ等に依存するようになっています。
Pointer Mangling on fastbins and tcache
Pointer Mangling はメモリ管理操作における fastbin and tcache Fd pointers を保護するためのセキュリティ強化です。この技術は、特に leaked memory 情報を必要としない、または既知位置に対する相対的な操作でメモリ位置を直接操作するような種類のメモリエクスプロイト手法を防ぐのに役立ちます(相対的な overwrites)。
この技術の核心は難読化の公式です:
New_Ptr = (L >> 12) XOR P
- L はポインタの Storage Location(格納場所)です。
- P は実際の fastbin/tcache Fd Pointer です。
格納場所(L)を右に12ビットシフトしてから XOR を行う理由は重要です。この処理は、メモリアドレスの下位12ビットがシステムアーキテクチャ上で通常予測可能であるという決定論的性質に起因する脆弱性に対処します。ビットをシフトすることで、予測可能な部分が式から外れ、新しい難読化されたポインタのランダム性が向上し、これらのビットの予測可能性に依存するエクスプロイトから保護されます。
この難読化されたポインタは、プログラムが使用するアドレスをランダム化して攻撃者によるプロセスのメモリ配置の予測を困難にする ASLR によって提供される既存のランダム性を利用しています。
ポインタを元のアドレスに戻す(Demangling)には同じ XOR 演算を使用します。ここでは、難読化されたポインタを式中の P として扱い、変更されていない格納場所(L)と XOR することで元のポインタが復元されます。この難読化と復号の対称性により、システムはオーバーヘッドを大きく増やすことなくポインタのエンコードとデコードを効率的に行え、ポインタ操作を悪用しようとする攻撃に対して大幅なセキュリティ向上を実現します。
セキュリティ上の利点
Pointer mangling はヒープ管理における部分的および完全なポインタ上書きを防ぐことを目的としており、セキュリティを大幅に強化します。この機能は複数の方法でエクスプロイト手法に影響を与えます:
- 部分的(バイト単位)相対上書きの防止: 以前は攻撃者がポインタの一部だけを変更して、正確なアドレスを知らなくてもヒープチャンクを別の場所にリダイレクトすることが可能でした(これは leakless House of Roman exploit に見られる技法です)。Pointer mangling により、そのような相対的上書きは heap leak なしではブルートフォースが必要になり、成功確率が大幅に下がります。
- Tcache Bin/Fastbin 攻撃の難化: fastbin や tcache エントリを操作して関数ポインタ(例:
__malloc_hook)を上書きする一般的な攻撃が妨げられます。例えば、LibC アドレスを leak し、チャンクを tcache bin に free してから Fd ポインタを上書きして__malloc_hookにリダイレクトし code execution を得るような攻撃は、Pointer mangling の下ではこれらのポインタを正しく mangled する必要があり、正確な操作のために heap leak が必要になります。これにより悪用の敷居が上がります。 - 非ヒープ領域での偽チャンク作成にも heap leak が必要に: スタック、.bss セクション、または PLT/GOT のような非ヒープ領域に偽チャンクを作る場合も、ポインタ mangling のために heap leak が必要となるため、これらの領域を悪用する難易度が LibC アドレス操作と同様に高くなります。
- ヒープアドレスの漏洩がより困難に: Pointer mangling は fastbin および tcache ビン内の Fd ポインタをヒープアドレス漏洩のソースとして利用する有用性を制限します。ただし、unsorted、small、large bins にあるポインタは mangled されず、アドレス漏洩に引き続き利用可能です。この変化により、攻撃者は exploitable な情報を得るためにこれらのビンを探る必要があり、状況によっては漏洩前にポインタを demangle する技術が使える場合もありますが、制約が伴います。
Safe-Linking Bypass (page-aligned leak scenario)
safe-linking を有効にしている場合(glibc ≥ 2.32)でも、mangled pointer を 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.
アルゴリズムの主要ステップ:
- 最上位ビットの初期 leak: シフトした L を P と XOR することで、シフトされた部分の L がゼロになるため、実質的に P の上位12ビットを得ることができます。
- ポインタビットの回復: XOR は可逆なので、結果と一方のオペランドが分かればもう一方を計算できます。この性質を利用して、既知のビットセットをマングルされたポインタの部分と逐次 XOR することで P の全ビットを推定します。
- 反復的デマングリング: このプロセスを繰り返し、前のステップで新たに見つかった P のビットを使ってマングルされたポインタの次のセグメントを復号し、全ビットが回復されるまで続けます。
- 決定的なビットの扱い: シフトによって L の最下位12ビットは失われますが、それらは決定的であるため、後処理で再構築できます。
You can find an implementation of this algorithm here: https://github.com/mdulin2/mangle
Pointer Guard
Pointer guard は glibc で使われるエクスプロイト緩和技術で、特に atexit() のようなライブラリ呼び出しで登録される格納済みの関数ポインタを保護します。この保護は、スレッドデータ (fs:0x30) に格納されたシークレットとポインタを XOR し、ビット単位の回転を適用してポインタをスクランブルすることを含みます。この仕組みは、関数ポインタを上書きしてコントロールフローを乗っ取ることを防ぐことを目的としています。
leak を使った Pointer Guard のバイパス
- Pointer Guard の動作理解: ポインタのスクランブル(マングリング)は
PTR_MANGLEマクロで行われ、ポインタを 64 ビットのシークレットと XOR した後に 0x11 ビットの左回転を行います。元のポインタを回復する逆操作はPTR_DEMANGLEが担当します。 - 攻撃戦略: この攻撃は既知平文(known-plaintext)アプローチに基づいており、攻撃者はマングルに使われたシークレットを推定するために、ポインタの元の状態とマングルされた状態の両方を知っている必要があります。
- 既知の平文を利用した攻撃:
- 固定された関数ポインタの特定: glibc のソースや初期化済みの関数ポインタテーブル(
__libc_pthread_functionsなど)を調べることで、予測可能な関数ポインタを見つけられます。 - シークレットの計算:
__pthread_attr_destroyのような既知の関数ポインタと関数ポインタテーブル上のそのマングル版を使い、マングルされたポインタを逆回転(右回転)してから関数のアドレスと XOR することでシークレットを算出できます。
- 代替平文: 攻撃者は 0 や -1 のような既知値でポインタをマングルして、メモリ上で識別可能なパターンが生じるかを試せます。これらのパターンがメモリダンプで見つかれば、シークレットが明らかになる可能性があります。
- 実用的応用: シークレットを算出した後、攻撃者はポインタを制御して操作でき、libc ベースアドレスを知っていて任意のメモリ位置を読み取れる環境では、マルチスレッドアプリケーションにおける Pointer Guard を事実上バイパスできます。
GLIBC Tunables & Recent Loader Bugs
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を提出してハッキングトリックを共有してください。


