Off by one overflow

Reading time: 9 minutes

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をサポートする

基本情報

1Bのオーバーフローにアクセスすることで、攻撃者は次のチャンクのsizeフィールドを変更できます。これにより、実際に解放されるチャンクを改ざんでき、別の正当なチャンクを含むチャンクを生成する可能性があります。このエクスプロイトはダブルフリーやオーバーラップチャンクに似ています。

オフバイワンの脆弱性には2種類あります:

  • 任意のバイト:このタイプは、そのバイトを任意の値で上書きすることを可能にします
  • ヌルバイト(オフバイヌル):このタイプは、そのバイトを0x00でのみ上書きすることを可能にします
  • この脆弱性の一般的な例は、strlenstrcpyの動作が不一致である以下のコードに見られ、次のチャンクの先頭に0x00バイトを設定できることです。
  • これはエインヘリヤルの家を使ってエクスプロイトできます。
  • Tcacheを使用している場合、これはダブルフリーの状況に利用できます。
オフバイヌル
c
// From https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/off_by_one/
int main(void)
{
char buffer[40]="";
void *chunk1;
chunk1 = malloc(24);
puts("Get Input");
gets(buffer);
if(strlen(buffer)==24)
{
strcpy(chunk1,buffer);
}
return 0;
}

他のチェックの中で、現在、チャンクが解放されるたびに、前のサイズがメタデータのチャンクに設定されたサイズと比較されるため、この攻撃はバージョン2.28からかなり複雑になっています。

コード例:

目標

  • チャンクが別のチャンクの中に含まれるようにし、その2番目のチャンクへの書き込みアクセスが含まれているチャンクを上書きできるようにする

要件

  • サイズメタデータ情報を変更するためのオフバイワンオーバーフロー

一般的なオフバイワン攻撃

  • チャンク ABC(サイズ0x20と仮定)を3つ割り当て、トップチャンクとの統合を防ぐためにもう1つを割り当てます。
  • Cを解放します(0x20 Tcacheフリーリストに挿入されます)。
  • チャンク Aを使用してBにオーバーフローします。オフバイワンを悪用して、Bsizeフィールドを0x21から0x41に変更します。
  • これで、Bが解放されたチャンクCを含むようになります。
  • Bを解放し、0x40チャンクを割り当てます(再びここに配置されます)。
  • まだ解放されているCfdポインタを変更できます(Tcacheポイズニング)。

オフバイヌル攻撃

  • メモリの3つのチャンク(a、b、c)が順番に予約されます。次に、中間のチャンクが解放されます。最初のチャンクにはオフバイワンオーバーフローの脆弱性があり、攻撃者は0x00を使用して悪用します(前のバイトが0x10だった場合、中間のチャンクは実際よりも0x10小さいことを示します)。
  • 次に、中間の解放されたチャンク(b)に2つの小さなチャンクが割り当てられますが、b + b->sizeは、指されているアドレスが必要なサイズよりも小さいため、チャンクcを更新しません。
  • 次に、b1とcが解放されます。c - c->prev_sizeはまだb(現在はb1)を指しているため、両方が1つのチャンクに統合されます。しかし、b2はまだb1とcの間にあります。
  • 最後に、新しいmallocが実行され、このメモリ領域を再利用します。実際にはb2を含むことになり、新しいmallocの所有者がb2の内容を制御できるようになります。

この画像は攻撃を完璧に説明しています:

https://heap-exploitation.dhavalkapil.com/attacks/shrinking_free_chunks

その他の例と参考文献

  • https://heap-exploitation.dhavalkapil.com/attacks/shrinking_free_chunks
  • Bon-nie-appetit. HTB Cyber Apocalypse CTF 2022
  • strlenが次のチャンクのsizeフィールドを考慮するため、オフバイワン。
  • Tcacheが使用されているため、一般的なオフバイワン攻撃がTcacheポイズニングを使用して任意の書き込みプリミティブを取得するのに機能します。
  • Asis CTF 2016 b00ks
  • オフバイワンを悪用してヒープからアドレスを漏洩させることが可能です。これは、文字列の終わりのバイト0x00が次のフィールドによって上書きされるためです。
  • 任意の書き込みは、オフバイワンの書き込みを悪用してポインタを別の場所に指すようにし、そこに偽の構造体と偽のポインタを構築します。次に、この構造体のポインタをたどって任意の書き込みを取得できます。
  • libcアドレスが漏洩するのは、ヒープがmmapを使用して拡張されると、mmapによって割り当てられたメモリがlibcから固定オフセットを持つためです。
  • 最後に、任意の書き込みが悪用され、__free_hookのアドレスにone gadgetが書き込まれます。
  • plaidctf 2015 plaiddb
  • ユーザー入力行を読み取るgetline関数にNULLオフバイワンの脆弱性があります。この関数は、コンテンツの「キー」を読み取るために使用され、コンテンツ自体ではありません。
  • 書き込みには最初に5つのチャンクが作成されます:
  • chunk1 (0x200)
  • chunk2 (0x50)
  • chunk5 (0x68)
  • chunk3 (0x1f8)
  • chunk4 (0xf0)
  • チャンク防御 (0x400) はトップチャンクとの統合を避けるためのものです。
  • 次に、チャンク1、5、3が解放されるので:

[ 0x200 Chunk 1 (free) ] [ 0x50 Chunk 2 ] [ 0x68 Chunk 5 (free) ] [ 0x1f8 Chunk 3 (free) ] [ 0xf0 Chunk 4 ] [ 0x400 Chunk defense ]

- 次に、チャンク3 (0x1f8)を悪用して、nullオフバイワンがprev_sizeを`0x4e0`に書き込みます。
- 最初に割り当てられたチャンク1、2、5、3のサイズとそれらのチャンクのヘッダーの合計が`0x4e0`に等しいことに注意してください:`hex(0x1f8 + 0x10 + 0x68 + 0x10 + 0x50 + 0x10 + 0x200) = 0x4e0`
- 次に、チャンク4が解放され、すべてのチャンクを消費するチャンクが生成されます:
- ```python
[ 0x4e0 Chunk 1-2-5-3 (free) ] [ 0xf0 Chunk 4 (corrupted) ] [ 0x400 Chunk defense ]

[ 0x200 Chunk 1 (free) ] [ 0x50 Chunk 2 ] [ 0x68 Chunk 5 (free) ] [ 0x1f8 Chunk 3 (free) ] [ 0xf0 Chunk 4 ] [ 0x400 Chunk defense ]