Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

[CB16] House of Einherjar :GLIBC上の新たなヒープ活用テクニック by 松隈大樹

1,636 views

Published on

例えば関数ポインタのようにBuffer Overflowに対して影響を受けやすい何らかデータが動的確保された領域にあるならば、Heap-based Buffer OverflowはStack-based Buffer Overflowと同じくらい攻撃されやすいと考えられる。しかし、メモリレイアウトはアプリケーションごとに異なるため、リモートからの攻撃者にはそれが本当に攻撃可能かどうかが判らない。そのためHeap-based Buffer Overflowへの攻撃はそれほど実践的でないとも言えるが, 大変興味深いものなので焦点を当ててみよう。任意のコード実行のためにプログラムカウンタを得るというものは攻撃者の目的のひとつであり、攻撃者はそれを"write-what-where primitive"(任意の箇所への任意のデータを書き込み)により実現することがある。Unlink Attackという直接的な"write-what-where primitive"を実現する古典的な攻撃手法があったが、現在では緩和策が施されたことで使えなくなっている。そのため、Exploit書きはmalloc()の戻り値をほぼ任意のアドレスに固定させることで間接的な"write-what-where primitive"を実現する手法を考えた。間接的な"write-what-where primitive"を有するHeap ExploitationテクニックにはMalloc Maleficarum(Phantasmal Phantasmagoria氏による攻撃手法とその論文)などがある。そのうちのいくつかは既に修正されているが, 未だに有効なものもある。今回は最新のGLIBCでも有効であり, 間接的"write-what-where primitive"を有する新たな攻撃手法として"House of Einherjar"を提案したいと思う。

--- 松隈 大樹Hiroki Matsukuma

サイバーディフェンス研究所の新米分析官であり、CTFチームTokyoWesternsのメンバーでもある。学生時代は国立東京工業高等専門学校というところで電子工学を学び, 趣味が高じてCTFに打ち込んでいたりした。アプリケーションをpwnする瞬間やカッコイイ音楽を聴いてるときが一番キテおり、おいしいものをひとと食べることも好む。最近はmalloc()の実装や組み込みシステムに対する攻撃など、やはりpwnに関することに興味をもっている.

Published in: Technology
  • Login to see the comments

[CB16] House of Einherjar :GLIBC上の新たなヒープ活用テクニック by 松隈大樹

  1. 1. CODE BLUE 2016.10.20 @st4g3r
  2. 2. Hiroki MATSUKUMA (@st4g3r) 新米ペンテスター  サイバーディフェンス研究所所属 CTF Player  TokyoWesterns 興味のあること  Exploitation  GLIBC malloc (現時点では) $whoami
  3. 3. tl;dr Heap Exploitation(x64 Linux/Glibc malloc) "House of Einherjar" とは?  Glibc mallocにおける新しいheap exploitation手法で, malloc() の戻り値をおおよそ任意なアドレスに強制させるものである.  通常, ユーザはmalloc()の戻り値のアドレスに対して読み書きを行える.  フラグメント防止のためにあるchunk同士の結合処理を利用する.  Well-sizedなchunk上でのOff-by-one Overflowが直後のchunkの prev_sizeとPREV_INUSEのコントロールをもたらす. Proof of Concept  http://ux.nu/6Rv6h
  4. 4. 概要 Glibc malloc  Chunk  Bin  Consolidating Chunks House of Einherjar  Flaw / Flow  Demo  Evaluation  Countermeasures
  5. 5. "struct malloc_chunk"  メモリブロックはfree()される際にfree listへとつながれる.  このとき, メモリブロックは"struct malloc_chunk"として扱われる.  ChunkのサイズはSIZE_SZ*2にアライメントされる. (prev_size) size fd bk (not used) (prev_size) size data + pads SIZE_SZ =8byte User's space (a) in-used (b) free 図1 struct malloc_chunk Shared with previous chunk Glibc malloc Chunk
  6. 6. 型 名称 説明 INTERNAL_SIZE_T prev_size 自身の直前にあるchunkのサイズ (shared) INTERNAL_SIZE_T size 自身のサイズと現在の状態 struct malloc_chunk *fd (free list上で)前方につながっているchunkへのポインタ struct malloc_chunk *bk (free list上で)後方につながっているchunkへのポインタ 表1: struct malloc_chunk Glibc malloc Chunk
  7. 7. "struct malloc_chunk"  メモリブロックはfreeされる際にfree listへとつながれる.  このとき, メモリブロックは"struct malloc_chunk"として扱われる.  ChunkのサイズはSIZE_SZ*2にアライメントされる. (prev_size) size fd bk (not used) (prev_size) size data + pads SIZE_SZ =8byte PMA User's space (a) in-used (b) free 図1 struct malloc_chunk Low 3 bits mean chunk status Shared with previous chunk Glibc malloc Chunk
  8. 8. "struct malloc_chunk"  メモリブロックはfreeされる際にfree listへとつながれる.  このとき, メモリブロックは"struct malloc_chunk"として扱われる.  ChunkのサイズはSIZE_SZ*2にアライメントされる. (prev_size) size fd bk (not used) (prev_size) size data + pads SIZE_SZ =8byte PMA User's space (a) in-used (b) free 図1 struct malloc_chunk Low 3 bits mean chunk status  [P]REV_INUSE  IS_[M]MAPPED  NON_MAIN_[A]RENA Shared with previous chunk Glibc malloc Chunk
  9. 9. Free chunkはfree list(bin)につながれる  Small bins  MAX_FAST_SIZE < size < MIN_LARGE_SIZE  MAX_FAST_SIZE: 0xa0  MIN_LARGE_SIZE: 0x400  Unsorted bins  free()されたばかりのchunkが一時的に格納されるリスト.  サイズによる制限は無い. Glibc malloc Bin
  10. 10. (prev_size) size fd bk (not used) bins[n-1] bins[n] bins[n+1] FD BK 図2. small binのfree list bins c struct malloc_chunk PMA Glibc malloc Bin
  11. 11. Glibc malloc Consolidating Chunks メモリ確保と解放を繰り返しているとフラグメント化を起こし てしまう  そこで, free()されるchunkと隣接するfree chunkの結合を考える.  自身の直前のchunkと隣接している.  自身の直後のchunkと隣接している. PREV_INUSE bit  自身の直前に隣接するchunkが使用中か否かを判断するためのフラグ.  これが結合の際の判断基準となる.
  12. 12. Glibc malloc Consolidating Chunks Chunkの結合処理はどこにある?  Glibcを読む.  free(p)  __libc_free(p)  _int_free(av, p, have_lock) <- これ!
  13. 13. (a) 始点 図3 _int_free()
  14. 14. (b) 結合箇所 図3 _int_free()
  15. 15. (c) 終点 図3 _int_free()
  16. 16. Glibc malloc Consolidating Chunks (prev_size) size prev p (a) prev_inuseのチェック 図4 結合 size = p->size If not prev_inuse(p): prevsize = p->prev_size size += prevsize p += -(long)(prevsize) fd bk (not used) (prev_size) size 0 data + pads p
  17. 17. Glibc malloc Consolidating Chunks (prev_size) size (b) 再配置 図4 結合 size = p->size If not prev_inuse(p): prevsize = p->prev_size size += prevsize p += -(long)(prevsize) p fd bk (not used) (prev_size) size 0 data + pads prev p p
  18. 18. Glibc malloc Consolidating Chunks (prev_size) size 1 p (c) 結果 図4 結合 p (prev_size) size fd bk (not used) fd bk (not used) (prev_size) size 0 data + pads prev p p
  19. 19. House of Einherjar Flaw / Flow 今のところ, これらのことが既知である  "p->prev_size"は, 直前に隣接するchunkと共有されうる.  "p->size"のPREV_INUSE bitを基にchunkの結合の可否を決定する.  新しいpの位置は"p->prev_size"により決定する.  "p = chunk_at_offset(p, -((long)prevsize))"
  20. 20. House of Einherjar Flaw / Flow 今のところ, これらのことが既知である  "p->prev_size"は, 直前に隣接するchunkと共有されうる.  "p->size"のPREV_INUSE bitを基にchunkの結合の可否を決定する.  新しいpの位置は"p->prev_size"により決定する.  "p = chunk_at_offset(p, -((long)prevsize))" ここで, 以下の条件について考える  3つのchunkが存在する.  p0: well-sizedなサイズをもつchunk(p1->prev_sizeを内包する).  p1: small binサイズのchunk.  (p2: malloc_consolidate()を抑制するためのchunk.)  p0についてOff-by-oneでNUL byte('¥0')なOverflowが存在する.
  21. 21. House of Einherjar Flaw / Flow (prev_size) size data (prev_size) size data + pads 1 well-sized shared (a) Overflow前 図5 House of Einherjarの原理 p0 (used) p1 (used)
  22. 22. (prev_size) size data (prev_size) size data + pads 1 (b) Overflow 図5 House of Einherjarの原理 Overflown House of Einherjar Flaw / Flow
  23. 23. (prev_size) size data 0xdeadbeef size data + pads '¥0' (c) Overflow後 図5 House of Einherjarの原理 p0 (free) p1 (used) shared well-sized House of Einherjar Flaw / Flow
  24. 24. House of Einherjar Flaw / Flow (prev_size) size data 0xdeadbeef size data + pads '¥0' (c) Overflow後 図5 House of Einherjarの原理 p0 (free) p1 (used) shared well-sized size = p1->size If not prev_inuse(p1): prevsize = p1->prev_size size += prevsize p1 += -(long)(prevsize)
  25. 25. House of Einherjar Flaw / Flow (prev_size) size data 0xdeadbeef size data + pads '¥0' (c) Overflow後 図5 House of Einherjarの原理 p0 (free) p1 (used) shared well-sized size = p1->size If not prev_inuse(p1): prevsize = 0xdeadbeef size += prevsize p1 += -(long)(prevsize)
  26. 26. House of Einherjar Flaw / Flow House of Einherjarに必要なこと  うまくサイズの調整されたchunkがOff-by-oneでOverflowを起こす.  ターゲットとする領域の近くにfake chunkがある.  fd, bkメンバはfake chunk自身を指すようにすると簡単である.  ターゲットとする領域と"p1"のアドレスについての差分が計算可能である.  このとき, これら2つのアドレスのleakが必要となる.  free()時に"p1->size"が大きく変更されるのでその補正が可能である.  ※fake chunkは何回か編集可能であると仮定する.
  27. 27. デモ http://ux.nu/6Rv6h
  28. 28. House of Einherjar Evaluation メリット  メモリレイアウトにも依るがOff-by-oneなOverflowさえあればできる.  "House of Force"のような巨大なmalloc()を必要としない. デメリット  fake chunkを置ける領域の近くしかmalloc()で取得できない.  2つのアドレスのleakが必要となる. 評価: "悪くはない"
  29. 29. House of Einherjar Countermeasures "struct malloc_chunk"がよくないのでは?  そもそも"chunk->prev_size"が通常の書き込みにより上書きされること がよくない.  そもそもBoundary Tagアルゴリズムだから仕方がない. 対策方法は?  Address checking  結合後の新しいchunkのアドレスは正しいか?  StackとHeapのアドレスは全然違う.  Return addressは守れる.  Heap内でのHouse of Einherjarには対応しきれない.
  30. 30. Thank You For Your Attention! Any Questions?

×