85 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Libc Protections
{{#include ../../banners/hacktricks-training.md}}
## チャンクアライメントの強制
**Malloc**は**8バイト32ビットまたは16バイト64ビットのグループ**でメモリを割り当てます。これは、32ビットシステムではチャンクの終わりが**0x8**に整列し、64ビットシステムでは**0x0**に整列する必要があることを意味します。このセキュリティ機能は、ポインタをビンから使用する前に、各チャンクがこれらの特定の位置で**正しく整列しているか**をチェックします。
### セキュリティの利点
64ビットシステムにおけるチャンクアライメントの強制は、**偽のチャンクの配置を16アドレスごとに1つに制限することによって、Mallocのセキュリティを大幅に向上させます**。これにより、特にユーザーが入力値を制限された状況での攻撃が複雑になり、成功させるのが難しくなります。
- **\_\_malloc_hookに対するファストビン攻撃**
Mallocの新しいアライメントルールは、`__malloc_hook`に関する古典的な攻撃も阻止します。以前は、攻撃者はチャンクサイズを操作して**この関数ポインタを上書きし、**コード実行**を得ることができました。現在、厳格なアライメント要件により、そのような操作はもはや実行可能ではなく、一般的な悪用経路が閉じられ、全体的なセキュリティが向上します。
## ファストビンとtcacheにおけるポインタのマングリング
**ポインタのマングリング**は、メモリ管理操作において**ファストビンおよびtcache Fdポインタ**を保護するために使用されるセキュリティ強化です。この技術は、特に漏洩したメモリ情報を必要としない、または既知の位置に対してメモリ位置を直接操作するタイプのメモリ悪用戦術を防ぐのに役立ちます(相対的な**上書き**)。
この技術の核心は、難読化の公式です:
**`New_Ptr = (L >> 12) XOR P`**
- **L**はポインタの**ストレージ位置**です。
- **P**は実際の**ファストビン/tcache Fdポインタ**です。
ストレージ位置Lを12ビット右にシフトしてからXOR操作を行う理由は重要です。この操作は、メモリアドレスの最下位12ビットの決定論的な性質に内在する脆弱性に対処します。これらのビットは、システムアーキテクチャの制約により通常予測可能です。ビットをシフトすることで、予測可能な部分が方程式から外れ、新しいマングルされたポインタのランダム性が向上し、これらのビットの予測可能性に依存する悪用から保護されます。
このマングルされたポインタは、プログラムが使用するアドレスをランダム化する**アドレス空間配置のランダム化ASLR**によって提供される既存のランダム性を活用します。
ポインタを元のアドレスに戻す**デマングリング**は、同じXOR操作を使用して行います。ここでは、マングルされたポインタが公式のPとして扱われ、変更されていないストレージ位置LとXORされると、元のポインタが明らかになります。このマングリングとデマングリングの対称性により、システムは大きなオーバーヘッドなしにポインタを効率的にエンコードおよびデコードでき、メモリポインタを操作する攻撃に対するセキュリティが大幅に向上します。
### セキュリティの利点
ポインタのマングリングは、ヒープ管理における**部分的および完全なポインタの上書きを防ぐ**ことを目的としており、セキュリティの大幅な向上です。この機能は、悪用技術にいくつかの方法で影響を与えます:
1. **バイト相対的上書きの防止**: 以前は、攻撃者はポインタの一部を変更して**ヒープチャンクを異なる位置にリダイレクトすることができました**が、ポインタのマングリングにより、そのような相対的上書きは**ヒープの漏洩なしではブルートフォースを必要とし**、成功の可能性が大幅に減少します。
2. **tcacheビン/ファストビン攻撃の難易度の増加**: 関数ポインタ(`__malloc_hook`などを上書きする一般的な攻撃は、ファストビンまたはtcacheエントリを操作することによって妨げられます。たとえば、攻撃はLibCアドレスを漏洩させ、チャンクをtcacheビンに解放し、Fdポインタを上書きして`__malloc_hook`にリダイレクトし、任意のコード実行を行うことが含まれるかもしれません。ポインタのマングリングにより、これらのポインタは正しくマングルされる必要があり、**正確な操作にはヒープの漏洩が必要**であり、悪用の障壁が高まります。
3. **非ヒープ位置でのヒープの漏洩の必要性**: スタック、.bssセクション、またはPLT/GOTのような非ヒープ領域に偽のチャンクを作成することは、ポインタのマングリングの必要性から**ヒープの漏洩を必要とします**。これは、LibCアドレスを操作するための要件と同様に、これらの領域を悪用する複雑さを拡張します。
4. **ヒープアドレスの漏洩がより困難になる**: ポインタのマングリングは、ファストビンおよびtcacheビンにおけるFdポインタの有用性を制限し、ヒープアドレスの漏洩源としての役割を果たします。ただし、未ソート、小、大のビンのポインタはマングルされていないため、アドレスの漏洩に使用可能です。この変化により、攻撃者は悪用可能な情報を探すためにこれらのビンを探索する必要がありますが、一部の技術では、制約があるものの、漏洩前にポインタをデマングルすることが可能です。
### **ヒープの漏洩を伴うポインタのデマングリング**
> [!CAUTION]
> プロセスのより良い説明については、[**こちらの元の投稿を確認してください**](https://maxwelldulin.com/BlogPost?post=5445977088)。
### アルゴリズムの概要
ポインタのマングリングとデマングリングに使用される公式は次のとおりです:
**`New_Ptr = (L >> 12) XOR P`**
ここで、**L**はストレージ位置、**P**はFdポインタです。**L**が12ビット右にシフトされると、**P**の最上位ビットが露出します。これは、**XOR**の性質により、ビットが自分自身とXORされると0を出力するためです。
**アルゴリズムの主要なステップ:**
1. **最上位ビットの初期漏洩**: シフトされた**L**を**P**とXORすることにより、**P**の上位12ビットを効果的に取得します。シフトされた部分の**L**はゼロになるため、**P**の対応するビットは変更されません。
2. **ポインタビットの回復**: XORは可逆的であるため、結果とオペランドの1つを知っていれば、他のオペランドを計算できます。この特性を利用して、マングルされたポインタの部分と既知のビットセットを順次XORすることで、**P**のビット全体を推測します。
3. **反復デマングリング**: このプロセスは繰り返され、各回で前のステップから得られた**P**の新たに発見されたビットを使用して、マングルされたポインタの次のセグメントをデコードします。すべてのビットが回復されるまで続けます。
4. **決定論的ビットの処理**: **L**の最終的な12ビットはシフトによって失われますが、これらは決定論的であり、プロセス後に再構築できます。
このアルゴリズムの実装はここにあります: [https://github.com/mdulin2/mangle](https://github.com/mdulin2/mangle)
## ポインターガード
ポインターガードは、glibcで使用される悪用緩和技術で、特に`atexit()`のようなライブラリ呼び出しによって登録された関数ポインタを保護します。この保護は、ポインタをスクリューム難読化することによって行われ、64ビットの秘密とXORを行い、ビット単位の回転を適用します。このメカニズムは、攻撃者が関数ポインタを上書きすることによって制御フローをハイジャックするのを防ぐことを目的としています。
### **漏洩を伴うポインターガードのバイパス**
1. **ポインターガード操作の理解**: ポインタのスクリュームマングリングは、ポインタを64ビットの秘密とXORし、0x11ビットの左回転を行う`PTR_MANGLE`マクロを使用して行われます。元のポインタを回復するための逆操作は`PTR_DEMANGLE`によって処理されます。
2. **攻撃戦略**: 攻撃は、攻撃者がポインタの元のバージョンとマングルされたバージョンの両方を知る必要がある既知の平文アプローチに基づいています。
3. **既知の平文を悪用する**:
- **固定関数ポインタの特定**: glibcのソースコードや初期化された関数ポインタテーブル`__libc_pthread_functions`など)を調べることで、攻撃者は予測可能な関数ポインタを見つけることができます。
- **秘密の計算**: `__pthread_attr_destroy`のような既知の関数ポインタと、その関数ポインタテーブルからのマングルされたバージョンを使用して、マングルされたポインタを右回転させてから関数のアドレスとXORすることで秘密を計算できます。
4. **代替平文**: 攻撃者は、0や-1のような既知の値でポインタをマングルして、これらがメモリ内で識別可能なパターンを生成するかどうかを確認することもできます。これにより、メモリダンプ内でこれらのパターンが見つかった場合に秘密が明らかになる可能性があります。
5. **実用的な応用**: 秘密を計算した後、攻撃者は制御された方法でポインタを操作し、libcベースアドレスの知識と任意のメモリ位置を読み取る能力を持って、マルチスレッドアプリケーションにおけるポインターガード保護を実質的にバイパスできます。
## 参考文献
- [https://maxwelldulin.com/BlogPost?post=5445977088](https://maxwelldulin.com/BlogPost?post=5445977088)
- [https://blog.infosectcbr.com.au/2020/04/bypassing-pointer-guard-in-linuxs-glibc.html?m=1](https://blog.infosectcbr.com.au/2020/04/bypassing-pointer-guard-in-linuxs-glibc.html?m=1)
{{#include ../../banners/hacktricks-training.md}}