bohan pac sec_2016_jp

113
Tyler Bohan - @1blankwall1 PacSec 2016

Upload: pacsecjp

Post on 16-Apr-2017

133 views

Category:

Internet


1 download

TRANSCRIPT

Page 1: Bohan pac sec_2016_jp

Tyler Bohan - @1blankwall1 PacSec 2016

Page 2: Bohan pac sec_2016_jp

ゾーンの中 : OS X のヒープ エクスプロイテーション

Page 3: Bohan pac sec_2016_jp

自己紹介

•  Tyler Bohan –  シニアリサーチエンジニア –  Cisco Talos所属

•  チーム員 –  Aleksandar Nikolich –  Ali Rizvi-Santiago –  Cory Duplantis –  Marcin Noga –  Piotr Bania –  Richard Johnson –  Yves Younan

•  Talos の研究開発 –  サードパーティーの脆弱性研究

•  過去12ヶ月で170の脆弱性を発見 –  Microsoft –  Apple –  Oracle –  Adobe –  Google –  IBM, HP, Intel –  7zip, libarchive, NTP

–  セキュリティツールの開発

•  Fuzzers, Crash Triage

–  緩和策の開発

•  FreeSentry

Page 4: Bohan pac sec_2016_jp
Page 5: Bohan pac sec_2016_jp
Page 6: Bohan pac sec_2016_jp

なぜこの分野の研究を?

•  画像に関するヒープオーバーフローが見つかり、エクスプロイトに至った

•  OS X の標準のmalloc実装についての最新ドキュメントがあまりない

•  オーバーフローが意図しない副作用を起こさないと保証する必要がある

Page 7: Bohan pac sec_2016_jp

なぜこの分野の研究を?

•  ヒープスプレーは信頼性がなく、エレガントでもない — 時代遅れ

•  ヒープアルゴリズムの深い知識は相対的なチャンク配置を考えるうえで重要である

•  すでに解放されたブロックがヘッダを破壊やエラーを起こしながら絶えず実行される

Page 8: Bohan pac sec_2016_jp

過去の研究 •  Insomnia •  https://www.insomniasec.com/downloads/

publications/Heaps_About_Heaps.ppt •  Immunity

•  http://www.slideshare.net/seguridadapple/attacking-the-webkit-heap-or-how-to-write-safari-exploits

•  Phantasmal Phantasmagoria •  Chris Valasek

•  https://media.blackhat.com/bh-us-12/Briefings/ValasekBH_US_12_Valasek_Windows_8_Heap_Internals_Slides.pdf

•  Etc.

Page 9: Bohan pac sec_2016_jp

過去の研究 (OS X)

•  OS X Heap Exploitation Techniques - 2005 •  Nemo

•  Mac OS Xploitation (and others) - 2009

•  Dino A. Dai Zovi •  Cocoa with Love - How Malloc Works on Mac - 2010

•  Matt Gallagher

Page 10: Bohan pac sec_2016_jp

OS X •  El Capitan (10.11.5) での研究が完了

•  ツール実装のマイナーチェンジは容易

•  現在のバージョン(10.11.6)はこれまでのところとてもよい 😋 (Sierra ベータ版)

•  Scalable Malloc – OS X Hackers Handbookに掲載 •  Magazine Malloc - El Capitanでの標準確保方法

Page 11: Bohan pac sec_2016_jp

ロードマップ

•  ヒープ構造 - 退屈 (重要) •  ヒープ戦略 – とても楽しい (ユニークな技術)

•  エクスプロイト戦略 - 楽しい (全てを一緒に)

Page 12: Bohan pac sec_2016_jp

ヒープ入門 (?)

Page 13: Bohan pac sec_2016_jp

ヒープの実装

•  Magazine allocator – これから解説 •  Scalable allocator – 古いOSX の確保方法 •  JEmalloc – Jason Evansによる実装 (bsd) •  DLmalloc – Doug Leaによる実装 (glibc) •  PTmalloc – Wolfram Glogerによる実装 (newer-glibc) •  TCmalloc – Webkitの一般的な確保方法 (google) •  Lookaside List – Windowsの実装(以前のもの) •  LF Heap – Windowsの実装(最新) •  Etc.

Page 14: Bohan pac sec_2016_jp

ヒープ実装 •  DL Malloc, TC Malloc, JE Malloc, etc…

•  最近解放されたキャッシュ、ソートチャンクを使用

•  一般的にはリンクリスト/メタデータ、アリーナなどの間でハイブリット

•  チャンクベースのアロケータはメタデータヘッダ付きのチャンクを前に付け、利用可能な異なるチャンクを分割またはナビゲートすることができる。

Page 15: Bohan pac sec_2016_jp

ヒープの実装方法

Heaps about Heaps - Insomnia

リンクリストのアロケータ:

Page 16: Bohan pac sec_2016_jp

ヒープ実装

•  Magazine Allocator, LFH, BSD malloc etc…

•  アリーナベースのアロケータは各ページに同サイズのグループ確保をする傾向がある

•  確保されたオブジェクトは効率的に解放される

Page 17: Bohan pac sec_2016_jp

ヒープの実装方法

0x100200030(2Q) 0x100200070(4Q) 0x100200100(6Q) 0x100200560(8Q)0x100200010(1Q)0x100200180(1Q)0x1002001A0(1Q)

0x100200180(4Q)

Page 18: Bohan pac sec_2016_jp

OS X の話に少し逸れて

Page 19: Bohan pac sec_2016_jp

OS X – CoreFoundat ion

•  下位レベルのAPIに引数を渡すために様々な上位レベルの型が含まれている

•  これらには CFDictionary, CFSet, CFStringなどのものが含まれている.

•  参照とガベージコレクションポインタ: CFRetain/

CFRelease

Page 20: Bohan pac sec_2016_jp

OS X – CoreFoundat ion

•  システムのmallocを使用して、このようなハッシュテーブルを確保

•  ヒープの状態変更のために、初期化コードが標準ヒープに割り当てられる — 詳しくは後で

•  CoreFoundationからヒープオブジェクトの上書きが可能 •  WebKit とSafari では様々な確保が使用される

Page 21: Bohan pac sec_2016_jp

OS X – Magazine Al locator

•  ヒープユーティリティを提供 •  Guard Malloc

•  ページヒープのようなもの •  OpenBSD アロケータ — オリジナル

Page 22: Bohan pac sec_2016_jp

OS X – Magazine Al locator

•  Malloc スタックロギング: •  デバッグフラグを必要とする - MallocStackLogging •  ヒープレイアウトを変更

•  LLDB の malloc_info

•  lldb.macosx.heap をインポートするスクリプト •  malloc_info -s 0x1080715e0

Page 23: Bohan pac sec_2016_jp

OS X – Magazine Al locator

•  Malloc スタックロギング: •  ターミナルからのmalloc_history

•  詳細の出力 •  プログラムヒストリー全てで、mallocとfreeのための全スタックフレーム

•  現在の割り当てられたスタックフレームだけでなく

Page 24: Bohan pac sec_2016_jp

OS X – Magazine Al locator

•  Malloc スタックロギング:

Page 25: Bohan pac sec_2016_jp

OS X ヒープ

Page 26: Bohan pac sec_2016_jp

OS X – Al locators

•  Malloc Zones •  アプリケーションによって使用される複数のヒープ実装を管理

•  各ゾーンには、識別のためのバージョンと名前が含まれている

•  Scalable Allocator (version=5) •  Magazine Allocator (version=8) •  mmap/munmap でマップ/アンマップをする

Page 27: Bohan pac sec_2016_jp

OS X – Magazine Al locator

•  使用されている: •  デフォルトCRT mallocを呼び出すもの •  libsystem_malloc.dylib, CoreFoundation, etc. •  プレビュー、ColorSync、Safari、Keynoteなど…これらのコンポーネントを通して到達可能

•  使用されていない:

•  Webkit (Objective-c, libxpc, renderersなどのマイナス低レベルのもの)

•  ImageIO コピーの内部に実装

Page 28: Bohan pac sec_2016_jp

OS X – Magazine Al locator

•  フリーリストは他アロケータ上でバケットリストと比較 •  ポインタ用のクッキー/チェックサムが含まれている

// Because the free list entries are previously freed objects, a misbehaved // program may write to a pointer after it has called free() on that pointer,// either by dereference or buffer overflow from an adjacent pointer. This write// would then corrupt the free list's previous and next pointers, leading to a// crash. In order to detect this case, we take advantage of the fact that // malloc'd pointers are known to be at least 16 byte aligned, and thus have// at least 4 trailing zero bits.//// When an entry is added to the free list, a checksum of the previous and next// pointers is calculated and written to the low four bits of the respective// pointers. Upon detection of an invalid checksum, an error is logged and NULL

Page 29: Bohan pac sec_2016_jp

OS X – Magazine Al locator

•  それぞれの リージョン/アリーナ はコアか“magazine” に決められる

•  コアあたり1つのMagazine. “depot” と呼ばれるfreeの領域にある特別なMagazine

•  割り当てサイズは3種類に分けられる (tiny, small, large)

Page 30: Bohan pac sec_2016_jp

OS X – Magazine Al locator

•  Tiny と Small アロケータは “Quantum” (Q)という単位で管理されている

•  各magazineは短期のメモリ確保のための単一割り当てキャッシュを持っている

すなわち

NSNumber* myNumber = [NSNumber alloc]

Page 31: Bohan pac sec_2016_jp

OS X – Magazine Al locator

•  Tiny アロケーション (16Q) – 最大サイズは 1008 •  Small アロケーション (512Q) – 最小サイズは 1009 •  Large アロケーション (サイズはゾーンで定義され、“hw.memsize“のsysctlに基づいて定義されている)

Page 32: Bohan pac sec_2016_jp

OS X – Magazine Al locator

•  全ての割り当てはリージョンとして知られるアリーナから来ている

•  フリーリストはQの数によってインデックスされたリンクトリスト

•  チャンクがフリーリストに移行して結合される

•  depot内のリージョンが空の場合、リージョンはOSに戻される

Page 33: Bohan pac sec_2016_jp

Magazine Al locator – T iny Al locat ions

•  チャンクはtinyリージョンによって配置される •  1Q (16 bytes) から 63Q (1008 bytes)までに配置 •  リージョンは常に0X100000バイト(0x100ページ)のサイズ

•  64520 のQサイズのブロック割り当てが含まれる •  Tinyメタデータは2つのビットマップに記載:

1つはどのブロックがチャンクの始まりか もう1つはチャンクがビジー/フリーであるか

Page 34: Bohan pac sec_2016_jp

Magazine Al locator – Smal l A l locat ions

•  チャンク はsmall リージョン (Q = 512b)から配置 •  1Q (1008 / 512b) から szone.large_threshold までの配置

•  リージョンは常に 0x800000 バイト (0x800 ページ) のサイズ

•  16320 のQサイズのブロックが含まれる •  メタデータはそれぞれのブロックを表すuint16_t のシンプルなリストで、Qの数は次を示す

•  それぞれのuint16_t の高ビットはフリー/ビジーを示す

Page 35: Bohan pac sec_2016_jp

Magazine Al locator – Large Al locat ions •  szone.large_threshold よりも大きい

* sysctl のhw.memsize beingで定義 > 230

•  循環連結リストとキャッシュによって管理される •  特定のフラグメンテーションがしきい値に達するまでキャッシュされる

•  フラグメンテーションがしきい値に達すると、OSに戻される

•  このプレゼンではこれ以上は追求しない - エクスプロイト目的としては実用的でないので

Page 36: Bohan pac sec_2016_jp

OS X – Magazine Al locator

•  スレッドマイグレーション

•  ユーザスペースからカーネルへ移るときにコア間のスレッドは移行する

•  カーネルは、異なるコア上でスレッドを呼び出すことができる!

Page 37: Bohan pac sec_2016_jp

OS X – Magazine Al locator

•  スレッドマイグレーション

•  コアは magazine を決める •  magazine はヒープレイアウトを決める

•  コアに移行するときは正確なヒープの操作が困難、または不可能になる

Page 38: Bohan pac sec_2016_jp

OS X – Magazine Al locator

•  スレッドマイグレーション

•  特許によって保留された情報について

Page 39: Bohan pac sec_2016_jp

OS X – Magazine Al locator

•  スレッドマイグレーション – どのように扱う?

•  スレッドを占有してコア切り替えを防ぐようにする •  すなわち タイトループなど…

Page 40: Bohan pac sec_2016_jp

OS X – Magazine Al locator

•  スレッドマイグレーション – どのように扱う? •  5つのイテレーションの 利用可能対ブロッキングの差

•  利用可能 = ~460,000 イテレーション

•  ブロッキング = ~860,000 イテレーション

Page 41: Bohan pac sec_2016_jp

Magazine Allocator の構造

Page 42: Bohan pac sec_2016_jp

Magazine Al locator

•  三つの異なる割り当てタイプを管理するために様々な構造によって結ばれている

•  任意の割り当てのために、リージョンに付随するmagazineをそれぞれのコアに関連づける試み

•  OSに戻すためにアリーナとリージョンが空になることを追跡

•  大規模にキャッシュされた領域を再利用するために、大規模な割り当てと断片化を追跡

Page 43: Bohan pac sec_2016_jp

Magazine Al locator

•  各magazine は非常に短時間の割り当てに使われる単一キャッシュを確保する

•  各 magazine はすぐにリージョン内のフリーチャンクを識別するためにQによってインデックスされたフリーリストが含まれている

•  フリーチャンクは前方、後方のまとめ(Coalescing)を支援するためにメタデータを含んでいる

•  リージョンはそれがどれくらい使用しているか、使用中であるかを表現するためのメタデータを含んでいる

Page 44: Bohan pac sec_2016_jp

Malloc ゾーン

Page 45: Bohan pac sec_2016_jp

Magazine Al locator – mal loc_zones

•  ゾーン: •  バージョンの種類

•  一つのコンテナーにおいて複数の異なるmallocをサポートする機能

•  主な機能は拡張性 •  多くの割り当て方式を扱うことができる •  Safariが可能とするようなプラットフォームを作る

Page 46: Bohan pac sec_2016_jp

Magazine Al locator – mal loc_zone_t

struct malloc_zone_t {… funcptr_t* malloc; funcptr_t* calloc;… const char* zone_name;… struct malloc_introspection_t* introspect; unsigned version;…}

struct malloc_introspection_t {… funcptr_t* check; funcptr_t* print; funcptr_t* log;… funcptr_t* statistics;…}

Page 47: Bohan pac sec_2016_jp

Magazine Al locator – mal loc_zone_t

•  一般系な構造は各mallocを識別するために使用される •  Zone_Name – 識別子を持つ文字列へのポインタ •  Version – uint32_t アロケータの種類を識別する •  異なるため、関数ポインタが含まれる

•  エントリーポイント: malloc, free, calloc, etc •  イントロスペクション: size, memalign,

pressure_relief, etc •  Szone_t はPhrackの記事でNemoが攻撃

Page 48: Bohan pac sec_2016_jp

Magazine Al locator – mal loc_zone_t

•  Phrack の余談

•  Szone_t 上書き - 新しいszoneの作成が必要で有り実用的でない

•  バグが包まれる - 64bit環境ではクラッシュする

•  ダブル・フリー - もう1度チェック

Page 49: Bohan pac sec_2016_jp

Magazine Al locator – szone_t

struct szone_t { malloc_zone_t basic_zone;… unsigned debug_flags; …tiny allocations... …small allocations... unsigned num_small_slots; …large allocations... unsigned is_largemem; unsigned large_threshold; uintptr_t cookie;...}

•  ポインタ・サイズと、難読化が意図されているポインタはxorをとる

Page 50: Bohan pac sec_2016_jp

Magazine Al locator – szone_t

•  エンコードされたポインタはポインタの上位4ビットの内の4ビットのチェックサムが含まれる

•  難読化されたPTRは、チェックサムptrを介して変換される:

csum := pointer ^ cookie •  ポインタを経由してチェックサムを抽出: rol(csum,4) &

0xF

Page 51: Bohan pac sec_2016_jp

Magazine Al locator – szone_t static INLINE uintptr_tfree_list_checksum_ptr(szone_t *szone, void *ptr) { uintptr_t p = (uintptr_t)ptr; return (p >> NYBBLE) | (free_list_gen_checksum(p ^ szone->cookie) << ANTI_NYBBLE); // compiles to rotate instruction}

0x100103310 0x233688 0x100330598^ = 0x100330598Checksum( ) = 1

,4) | Checksum(…) =0x100103310ror( 1000000010010331

Page 52: Bohan pac sec_2016_jp

struct szone_t {... size_t num_tiny_regions;... region_hash_generation_t* tiny_region_generation; region_hash_generation_t[2] trg;

int num_tiny_magazines;... magazine_t* tiny_magazines;... unsigned num_small_slots;… region_t[64] initial_tiny_regions;…}

64

Magazine Al locator – t iny szone_t

struct region_hash_generation_t { size_t num_regions; size_t num_regions_shift; region_t*[num_regions] hash_regions; region_hash_generation_t* nextgen;}

Page 53: Bohan pac sec_2016_jp

Magazine Al locator – smal l szone_t struct szone_t {... size_t num_small_regions;... region_hash_generation_t* small_region_generation; region_hash_generation_t[2] srg;

int num_small_magazines;... magazine_t* small_magazines;… unsigned large_threshold;… region_t[64] initial_small_regions;…}

struct region_hash_generation_t { size_t num_regions; size_t num_regions_shift; region_t*[num_regions] hash_regions; region_hash_generation_t* nextgen;}

Page 54: Bohan pac sec_2016_jp

Magazine Al locator – large szone_t struct szone_t {... unsigned num_large_objects_in_use; unsigned num_large_entries; large_entry_t* large_entries; size_t num_bytes_in_large_objects;... int large_entry_cache_oldest, large_entry_cache_newest; large_entry_t[16] large_entry_cache;... unsigned large_threshold;...}

Page 55: Bohan pac sec_2016_jp

Magazine_T

Page 56: Bohan pac sec_2016_jp

Magazine Al locator – magazine_t

•  1つのmagazineはコア毎に割り当てられる. “depot”のための+1. •  depotはプレースホルダーmagazineとして使用 •  スロット -1 にインデックス •  使われることはなく、解放されたリージョンのキャッシュに使われる

•  コアにローカルリージョンをバインドするために使用

•  depotのために解放された後で、リージョンはmagazine間を移動する

Page 57: Bohan pac sec_2016_jp

Magazine Al locator – magazine_t

•  チャンクキャッシュ、ビットマップフリーリスト、割り当てに使われるための最後のリージョン、全リージョンのリンクリストが含まれる

•  現在のリージョンから割り当てを管理するための使用統計情報を監視

Page 58: Bohan pac sec_2016_jp

struct magazine_t {... void* mag_last_free; region_t mag_last_free_rgn;... free_list_t*[256] mag_free_list; unsigned[8] mag_bitmap;... size_t mag_bytes_free_at_end, mag_bytes_free_at_start; region_t mag_last_region;... unsigned mag_num_objects; size_t mag_num_bytes_in_objects, num_bytes_in_magazine;... unsigned recirculation_entries; region_trailer_t* firstNode, *lastNode;...}

Magazine Al locator – magazine_t

1110000000011001110001100001111XXX

Linked list of all regions

Local magazine cache

Page 59: Bohan pac sec_2016_jp

Magazine Al locator – magazine_t

•  統計 •  Mag_bytes_free_at_Start

•  Mag_num_objects

•  利用可能な連続スロット数 - それぞれ フリーとビジーで

使用 利用可能

リージョンmag_bytes_free_at_endmag_bytes_free_at_start

Page 60: Bohan pac sec_2016_jp

Magazine Al locator – magazine_t

•  mag_last_free cache – 短期割り当て= •  Qサイズはポインタとともにエンコードされる •  Tiny Q=16, 下位4ビットは、Qサイズを表す •  Small Q=512, 下位 9ビットは 、Qサイズを表す •  残りのビットはチャンクとポインタが含まれる

0x100101436 Pointer: 0x100101430Quantum: 6Q = 96 bytes

0x100f09ee1f Pointer: 0x100f09ee00Quantum: 31Q = 15872 bytes

tiny

small

Page 61: Bohan pac sec_2016_jp

Magazine Al locator – magazine_t Mag_free_bitmap 追加されるフリーエントリーが表される

Mag_free_list

フリーチャンクの循環リストが示される

Page 62: Bohan pac sec_2016_jp

Magazine Al locator – magazine_t

•  Magazine フリーリスト •  全てのフリーチャンクの循環リストを示す •  次とフリーのポインターがチェックされる •  チェックサムはポインタ上位4ビットで符号化 •  ポインタは右に4ビットローテートされ、その後

4ビットチェックサムとOR演算 •  チャンクが結合中の場合はチェックサムはチェックされない

0x300000001002032b 0x1002032b0Next Pointer in Chunk Actual Pointer

Page 63: Bohan pac sec_2016_jp

Magazine Al locator – magazine_t

•  チャンクがキャッシュからフリーリストに遷移時(?) •  循環リンクリストはチャンクに書かれる •  チャンクが>1Qのとき(Q)のサイズはチャンクの末尾に書かれる。

•  前後でまとめる(Coalescing)時に使用

Page 64: Bohan pac sec_2016_jp

Magazine Al locator – t iny magazine_t

•  フリーリストは256スロットを所有し、64のみ使用 •  szone.num_small_slots によって定義

•  いくつかのデットスペースは最大1008まで

•  NUM_SMALL_SLOTS = 64

Page 65: Bohan pac sec_2016_jp

Magazine Al locator – smal l magazine_t

•  フリーリストは使用可能な256スロット全てを使用 •  大きなしきい値に基づいて •  一般的に 0x1fc00 / 512 == 254

Page 66: Bohan pac sec_2016_jp

Region_T

Page 67: Bohan pac sec_2016_jp

Magazine Al locator – region_t

•  2つの異なるタイプ “tiny” と “small” のアロケータ

•  チャンクはQ上で分割されたチャンク数で構成: Tiny = 16 bytes, Small = 512 bytes.

•  リージョン+メタデータ+リージョントレイラーのサイズがベースとして計算されたQサイズブロックの数が含まれる

Page 68: Bohan pac sec_2016_jp

Magazine Al locator – region_t

•  メタデータはチャンクサイズ、チャンクがビジーかフリーかを示す情報を持っている

•  Tiny メタデータはheader/in-useの各ビットからリージョンブロックマッピングしている

•  Small メタデータは各uint16_t からブロックを直接マッピングしている

Page 69: Bohan pac sec_2016_jp

Magazine Al locator – region_t typedef uint8_t[Q] Quantum_t;

struct region_t { Quantum_t[NUM_BLOCKS] blocks; region_trailer_t trailer; metadata_t metadata;}

struct tiny_metadata_t { tiny_header_inuse_pair_t[NUM_BLOCKS / sizeof(uint32_t)] blocks;}

struct small_metadata_t { uint16_t[NUM_BLOCKS] msize;}

struct tiny_header_inuse_pair_t { uint32_t header, inuse;}

* メタデータはregion_tのブロックと直接相関している

Page 70: Bohan pac sec_2016_jp

Magazine Al locator – t iny region_t

•  Tiny メタデータ – 2つのuint32_tと構造体の配列 1. ブロックはチャンクの始まりであるかどうかをビットで示す (Qでチャンクサイズを計算するために使用).

2. ビットはチャンク全体がbusy(1) か free(0)かを示す

Page 71: Bohan pac sec_2016_jp

Magazine Al locator – smal l region_t

•  Small メタデータ – エンコードされた uint16_t 配列 •  高ビットはbusy(0) か free(1)を示す •  残りのビットはチャンクのためのQの数を示す •  Qは、次のチャンクまでいくつの要素をスキップするかを示す

Page 72: Bohan pac sec_2016_jp

Magazine Al locator – large regions

•  Large リージョン •  シンプル、ただアドレスとそのサイズ •  ひどく断片化するまでアンマップされない •  キャッシュに格納

typedef struct large_entry_t { vm_address_t address; vm_size_t size; boolean_t did_madvise_reusable;}

Page 73: Bohan pac sec_2016_jp

Magazine Al locator – region_tra i ler_t

•  各リージョンはmagazineがどれに連携するか知っている •  magazine_tがトレイラーを指し、magazineが全てのリージョンへの繰り返しを許すようにナビゲートする

struct region_trailer_t { struct region_trailer* prev, *next; boolean_t recirc_suitable; int pinned_to_depot; unsigned bytes_used; mag_index_t mag_index;}

depot magazine?

Linked list of all magazines in a region

Magazine whom retains ownership

Page 74: Bohan pac sec_2016_jp

戦略

Page 75: Bohan pac sec_2016_jp

Strategies – for cache

•  Mac Heapと呼ぶツール •  LLDB python スクリプトで全ての情報にアクセスできる •  オープンソース 🤑

Page 76: Bohan pac sec_2016_jp

Strategies

•  ポジショニング •  戦略的なブロック配置、キャッシュ管理

•  オーバーライト •  ブロックをFree (解放)の前か後のチャンク、busy (使用中)のチャンクに配置

•  メタデータ •  Unlinking attacks

Page 77: Bohan pac sec_2016_jp

Strategies – for cache

•  キャッシュ •  キャッシュを空に

•  キャッシュオブジェクトとしてのMallocの正確なサイズ

•  キャッシュからフリーリストへ

•  256b(tiny)未満の他のフリーオブジェクト •  新しいオブジェクトをキャッシュへ、キャッシュオブジェクトからフリーリストへ移動

Page 78: Bohan pac sec_2016_jp

Strategies – for f ree l is t

•  フリーリスト •  リンクリスト •  Quantum(Q)サイズ毎にインデックス化されている •  Tiny - 64 slots — Small - 256 slots •  Smallの最小サイズである1009では、割り当て不可能なため1Qを使用することができない

•  Q = 512 - 512という1Qのtinyリージョンへの割り当ては"dead"になる

Page 79: Bohan pac sec_2016_jp

•  まとめる(Coalescing) – チャンクがフリーリストに移動された場合 •  ForwardQ/BackwardQ – >1Q のチャンクへ書かれたとき

•  ForwardQ か BackwardQ が上書きされたとき、特定のカウントはフリーチャンクを指す必要がある

•  フリーリストにチャンク全体を追加する(任意の使用ずみチャンク間での使用を含む)

St rategies – mag_free_l is t

Page 80: Bohan pac sec_2016_jp

11111111111011110011000111111111111111111111111111111111111111111111111111111111

Strategies – mag_free_l is t – Coalesce

Overwrite chunk with 2Q + 3Q bytes data.Set BackwardQ to 12 (3+2+7).

Freeing Busy chunk will coalesce with 3Q Chunk and use overwritten BackwardQ of 12 joining 2Q chunk with 7Q chunk.

Due to BackwardQ being 12. Freeing 5Q chunk will read BackwardQ and add 7Q+2Q+3Q (12Q) to free list

whilst chunk still being by program.

111111111101111001100000000111111111111111111111111111111111111111111111111

Page 81: Bohan pac sec_2016_jp

Strategies – mag_free_l is t

•  Forwards まとめ(Coalesce) – realloc() かキャッシュがフリーリストに移行するとき •  フリーチャンクのForwardQは、まとめにどれだけ遠いか、 reallocにどれだけ遠いかを決めているように見える...

•  完了時、フリーリストに追加される

Page 82: Bohan pac sec_2016_jp

111111111111111110000001110111111111111111111111111111111111

Strategies – mag_free_l is t – Coalesce

Overwrite Busy with 2Q data to get to Free. Write 4+4 (8Q) into Free’s ForwardQ.

If Busy Chunk gets free’d, 2Q+4Q+4Q (10Q) gets added to free list. 3Q still in use by program.

Similarly if Busy Chunk gets realloc’d, The different of 8Q and the new allocation size gets added to the free list where 3Q chunk is still in use.

111111111111111111100001110111111111111111111111111111111111

111111111111111111111111111111111111111111111111111111111111

Page 83: Bohan pac sec_2016_jp

Strategies – mag_free_l is t

•  解放されたチャンクの先頭にリンクリストを上書き •  アンリンクによるWrite 4- 全く使えないASLR - 正しいチェックサムは大体7%の確率になる

•  リンクリストのポインタがNULLの場合、チェックサムは0になる. 残念ながら、mag_bitmapのビットはクリアされる.

•  ビットマップにビットをセット、まとめたエントリーへのアクセスを回復には、他のチャンクからフリーリストへ移る必要がある.

Page 84: Bohan pac sec_2016_jp

Strategies – mag_free_l is t

•  フリーリストからの割り当て - 4Q

101001100001111111110000001010111111111111111111111111000011111111111111111111111111111111000000000111111

Region_t – 0x100200000

0x100200030(2Q) 0x100200070(4Q) 0x100200100(6Q) 0x100200560(8Q)0x100200010(1Q)0x100200180(1Q)0x1002001A0(1Q)

0x100200180(4Q)

Page 85: Bohan pac sec_2016_jp

Strategies – for f ree l is t

キャッシュを見て、きちっと一致?

yes? 割り当て

フリーリストインデックス, Q-1, 合致?

yes?

フリーリストから, スロットが見つかる?

yes?

リージョンからの割り当て

Page 86: Bohan pac sec_2016_jp

Strategies – for region

•  リージョンからの割り当て •  現在の使用されているバイト数を計算 •  リージョンベースアドレスへ追加 •  必要なスペースを確保 •  freeされたものはフリーリストに戻る

使用 利用可能

リージョンmag_bytes_free_at_endmag_bytes_free_at_start

Page 87: Bohan pac sec_2016_jp

デモ

•  シングルコアスクリプト

script import onemagbreakpoint set -N singlemag1 -s libsystem_malloc.dylib -a 0x262abreakpoint set -N singlemag2 -s libsystem_malloc.dylib -a 0x2a6abreakpoint set -N singlemag3 -s libsystem_malloc.dylib -a 0xb95dbreakpoint set -N singlemag4 -s libsystem_malloc.dylib -a 0xbd43breakpoint command add -F onemag.cont singlemag1breakpoint command add -F onemag.cont singlemag2breakpoint command add -F onemag.cont2 singlemag3breakpoint command add -F onemag.cont2 singlemag4

Page 88: Bohan pac sec_2016_jp

Strategies – for region

•  リージョンビットマップ •  ビットマップフィッティング

•  リージョンビットマップ内部の単一で少量のスロットを埋め、リージョンビットマップになる

•  利用リージョンの終わりに次のスロットを割り当て •  ともにスロットを割り当て

Page 89: Bohan pac sec_2016_jp

Strategies – for region Fragmented BitmapIn Use = 1 Free = 0

1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110100110000111111000000111111000000001111111111111111111111111111000000000000000000000011111111111111111111000000000000011111111111111111111111111111111111

>>>region.getoffset()0x100200000>>>region.bitmap()

>>> len(region.bitmap())901

Page 90: Bohan pac sec_2016_jp

Strategies – for region >>> print magazine.dump()[1] 0x100202eb0[2] 0x100202ed0[4] 0x100202f10[6] 0x100202fb0[8] 0x100203070[13] 0x100203550[22] 0x1002032b0

1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110100110000111111000000111111000000001111111111111111111111111111000000000000000000000011111111111111111111000000000000011111111111111111111111111111111111

>>>region.getoffset()0x100200000>>>region.bitmap()

Page 91: Bohan pac sec_2016_jp

Strategies – for region

>>>t['mag_free_list'].quantum()56

1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110100110000111111000000111111000000001111111111111111111111111111000000000000000000000011111111111111111111000000000000011111111111111111111111111111111111

Page 92: Bohan pac sec_2016_jp

Strategies – for region

56の単一で少量の割り当てがビットマップを平坦にする

Page 93: Bohan pac sec_2016_jp

Strategies – for region Fragmented BitmapIn Use = 1 Free = 0

1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111

region.bitmap()

>>> len(region.bitmap())901

Page 94: Bohan pac sec_2016_jp

Strategies – for region

次の割り当てがビットマップを必要な量にする(その後、リージョンも)

Page 95: Bohan pac sec_2016_jp

Strategies – for region Fragmented BitmapIn Use = 1 Free = 0

1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111

region.bitmap()

>>> len(region.bitmap())925

Page 96: Bohan pac sec_2016_jp

Strategies – Scoping bugs(?)

•  ダブルフリー

•  メタデータとキャッシュに対し明示的にチェックしているのでフリーできない

Page 97: Bohan pac sec_2016_jp

Strategies – Scoping bugs(?)

•  ヒープスプレー

•  境界の先頭にブロック (0x100000 - tiny) (0x800000 - small)

•  0xXXXFC080 から 0xXXXFFFFF - tiny 構造体

•  0xXX800000 から 0xXXFF8000 - small 構造体

Page 98: Bohan pac sec_2016_jp

デバッグの戦略

Page 99: Bohan pac sec_2016_jp

LLDB In i t

•  LLDBは機能性に欠ける •  ページプロテクションを見る •  メモリをダンプする •  式の取り扱い •  etc

Page 100: Bohan pac sec_2016_jp

LLDB In i t

•  詳細すぎるコマンド(限定された機能)

•  breakpoint set -a `(void()) main`

•  breakpoint command add -o “x/x $rax” 1

Page 101: Bohan pac sec_2016_jp

LLDB In i t

•  LLDBは機能性に欠ける •  難しかったり扱いにくいようないくつかのコマンド

•  LLDB内部のPythonの機能は非常に面倒

Page 102: Bohan pac sec_2016_jp

LLDB In i t

•  機能を追加する一般的な方法が提供 •  エイリアスとブレイクポイント管理

•  内蔵されている完全なパーサは、WinDBGのようなブレイクポイント管理やコマンドを提供

•  ie. poi(main+$rax+local_1)

Page 103: Bohan pac sec_2016_jp

エクスプロイトの戦略

Page 104: Bohan pac sec_2016_jp

Safar i •  5つの mallocゾーン

•  Default Malloc - version 8 (magazine alloc)

•  GFX Malloc - version 8 (magazine alloc) •  WebKit Malloc - version 4 (bmalloc)

•  Quartz Core Malloc - version 5(scalable alloc) •  Default Purgeable Malloc - version 8(magazine alloc)

Page 105: Bohan pac sec_2016_jp

Safar i

•  5つの malloc ゾーン

Page 106: Bohan pac sec_2016_jp

脆弱性の詳細

•  画像ベースのヒープオーバーフロー

•  Core Foundation -> ImageIO

•  Default malloc ゾーン

•  ImageIO は独自の mallocを持っている (ImageIOMalloc) – ほとんどに使われている :)

Page 107: Bohan pac sec_2016_jp

Explo i tat ion Strategy

•  ヒープベースのオーバーフロー •  基本的に必要なもの:

•  情報の搾取 •  オブジェクトの上書き

•  ここでゾーンの問題が浮上する…

Page 108: Bohan pac sec_2016_jp

エクスプロイトの戦略

•  大半の制御可能な配置はWebKitのmallocに管理されている

•  しかし、新規にデフォルトゾーンを呼び出す

•  上書きするかなり多くのオブジェクトを開く •  情報のリークはまだ必要

Page 109: Bohan pac sec_2016_jp

Explo i tat ion Strategy

•  JavascriptでCoreFoundationを操作するHeap改竄方法が見つかった

•  AudioContextオブジェクトは、高確率でデフォルトの

mallocゾーンに配置 •  複数のイメージは適切な配置のヒープ領域が必要とする、CoreFoundationsがデフォルトのヒープへ配置するために初期化とセットアップをする - CSSは適切なロードに使用

Page 110: Bohan pac sec_2016_jp

Explo i tat ion Strategy

•  さらなる解析によりデフォルトゾーンに配置された文字列を見つけた

•  Date.prototype.ToLocale •  オーバーフローによって上書きができて、Javascriptからのアクセスも可能となる

Page 111: Bohan pac sec_2016_jp

Explo i tat ion Strategy

•  Date.prototype.ToLocale … — 3つのアロケーション •  ロケールの後quantumを空にする •  メタデータの上書き -> 後方への結合(coalesce) •  チャンクの解放 -> リージョンビットマップのクリア •  次の割り当てはロケール文字列の途中に配置 •  ヌル終端文字を取り除く •  日付を読み出す

Page 112: Bohan pac sec_2016_jp

Explo i tat ion Strategy

•  情報搾取が成功 •  オブジェクトの上書き

•  コード実行 👻

Page 113: Bohan pac sec_2016_jp

Conclus ion

•  https://github.com/blankwall/MacHeap •  MacHeap tool •  libsystem_malloc.idb

•  https://github.com/blankwall/LLDBInit

•  @1blankwall1