42
Microsoft Windows カカカカカカカカカカ Windows カカカカカカカ

[CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long

Embed Size (px)

Citation preview

Page 1: [CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long

Microsoft Windowsカーネルのデスノート

Windows カーネルの内部

Page 2: [CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long

$whoami

• @zer0mem• Tencent KeenLab の Windows

カーネル研究者• Pwn2Own 優勝者

( 2015/2016 )、 wnie にノミネート( 2015 )

• ファジングで注目するもの:state

• 武術太極拳拳士

Daniel

• @long123king• Tencent KeenLab の

Windows カーネル研究者• Pwn2Own 優勝者( 2016 )• ファジングで注目するも

の:データ「フォーマット」• Windbg の専門家

Peter

高橋由佳子
$whoami ← unixコマンドの模様。洒落だと思うので、そのままにしてあります。
高橋由佳子
fuzzing focus → ファジングで注目するもの
Page 3: [CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long

アジェンダ

sandbox

ntoskrnl

拡張

clfs

内部

高橋由佳子
extension → 拡張としてみました
Page 4: [CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long

Sandbox• 攻撃対象領域を制限

• バグに対する潜在的景観• それを悪用するために利用可能なメソッド

• ACL vs さまざまなカーネルオブジェクトへのアクセス• 非 ntos 、非 w32k ドライバー• さまざまな ntos オブジェクト

• w32k フィルタリング• sandbox 化されたアプリが必要とするものに依存

• w32k ロックダウン

高橋由佳子
limiting attack surface → 攻撃対象領域を制限する
高橋由佳子
★potantional landscape for bugs ← potential のスペルミスではないかと思います。
Page 5: [CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long

Sandbox のターゲット

mutex メモリ

スレッド

PE セクション

パイプ

Page 6: [CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long

... 他には?

• Nt* トランザクション *• Nt* エンリストメ

ント *• Nt* マネージャ *

高橋由佳子
Enlistment → 入隊とかいう意味だそうですが、Microsoftは「エンリストする」という表現にとどめているようです。迷ったのですがそのままカタカナ表記にしてみました。
Page 7: [CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long

何だろう?

• カーネル トランザクション マネージャ

• 目的• カーネルトランザクションマネージャ( KTM )は、トランザ

クションを使うアプリケーション開発を可能とする。トランザクションエンジン自体はカーネルの内部にあるが、トランザクションはシングルホスト内または分散ホスト間でカーネルまたはユーザーモードトランザクション向けに開発可能。

• KTM は、トランザクション NTFS ( TxF )やトランザクションレジストリ( TxR )を実装するために使われる。 TxF は、NTFS ファイルシステム内でトランザクション処理ファイルシステムの操作を可能とする。 TxF は、トランザクション処理レジストリの操作を可能とする。 KTM は、クライアントアプリケーションがトランザクションでのファイルシステムやレジストリ操作と連動することを可能とする。

Page 8: [CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long

tm.sys

• シンプルなオブジェクトステート• わずかな syscall が利用可能• それほど多くないコードが含まれている• しかし面白い方法で相互接続される

• 結果 : • 1 回の null ポインターの逆参照• 1 個の悪用可能な脆弱性

Page 9: [CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long

tm の回避

• tm.sys 単純目的のドライバー• しかし、興味深い モジュールが バックエンドに含まれる• CLFS.sys

高橋由佳子
indirection → 回避としてみました。迂回がなんとなくしっくりこなかったので・・・
Page 10: [CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long

CLFS.sys• 目的

• 共通ログファイルシステム( CLFS ) API は、専用クライアントアプリケーションが利用できる高パフォーマンスの、汎用的なログファイル・サブシステムを提供し、複数のクライアントが共有することでログアクセスを最適化できる。

• ロギングまたはリカバリサポートを必要とするあらゆるユーザーモードのアプリケーションが、 CLFS を使用できる。

• 該当箇所• データやイベント管理、そしてサーバーや企業アプリケーションを開発

する際に CLFS を使用可能。• データ管理に対しては、以下と CLFS を使用可能:

• データベースシステム• ストアアンドフォワードシステムなどのメッセージング• オンライントランザクション処理( OLTP )システム• その他トランザクションシステムの類

Page 11: [CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long

CLFS.sys• トランザクションなど色々なものに、かなり統合

されている!• C++ コードベース• 十分な攻撃対象領域を提供

• … しかし、 AppContainer/ 信頼できないレベル、というわけではない…

• いや、そうなのか?

Page 12: [CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long

NtCreateTransactionManager• CLFS に依存• 自身のチェックポイント用に CLFS を使う

• それゆえに、以下を暗示する: • CLFS を開く• CLFS を * パース * する • CLFS と相互作用する

• では試してみよう!

Page 13: [CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long

CLFS - データファジング I.• わたしは、カーネルのデータファジングのファン

ではない• わたしは、カーネルでデータのパーシングをすることには全く

もって強く反対している☺

• 手っ取り早い調査をしてみよう。以下のものならばわたしも OK : • ファイルをランダムに変更する• 結果 = ゼロ• わたしにとってナイスなもの。というか、わたしはあまり興味

がない• 本来のアイディアに立ち戻る!

Page 14: [CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long

CLFS - ステートファジング

• アプローチ 1.• リバース・エンジニアリング: clfs.sys• ioctl に行く• ... あぁ、最初からやるのは面倒すぎる ...

• アプローチ 2.• MSDN ドキュメントを読み通す• その API 群がどのように動くかを理解する

• 自身または別の API を正常に呼び出すために必要なコールスタック

• Qilin (わたし達の内部ファズツール)にそのロジックを実装する

• Qilin のロジックにほんの少し干渉する

高橋由佳子
★callstack necessary to suceed to call one or another api→ suceed は succeed のスペルミスと思われます。
Page 15: [CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long

bugz++• 最初のファズツール試行の 15 分後、最初のクラッ

シュ• … なんてこった

• しかし DDoS のみ• それを除外• 別の bugz が出現

• ここで再度考える… 結局、データ・ファジングは本当にそんなに悪いアイディアなのか?

Page 16: [CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long

CLFS - データファジング II.• リバースエンジニアリング:どこで & どのよ

うにデータがパースされるのか

• エントリー・ポイント : ClfsCreateLogFile

•痛っ… マジック… ダミーのファズ防御• I. crc• II. 再配置が必要

Page 17: [CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long

CLFS - もっと真剣にファズしよう•既存コードの再実装は面倒すぎるが、そもそ

もそれは必要なのか?

Page 18: [CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long

CLFS - もっと真剣にファズしよう

• crc の実装と再配置は面倒くさすぎる

Page 19: [CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long

CLFS { ステート、ダミー、強化 }

データ強化されたファズ27% ++

データダミーファズ40%

ステートファズ33%

CLFS ファジング戦略 => 結果

高橋由佳子
Enhanced → 強化された
Page 20: [CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long

CLFS の内部… その傘下にあるもの…

高橋由佳子
under the hood → …その傘下にあるもの…
Page 21: [CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long

BLF ( ベースログファイル ) 形式

コントロールレコード

コントロールレコードシャドウ

ベースログレコード

ベースログレコードシャドウ

情報落ちレコード

情報落ちレコードシャドウ

[2 セクター ] レイアウト、拡張情報、情報落ちを含む

[2 セクター ] コントロールレコードのシャドウコピー

[0x3D セクター ] クライアント情報、コンテナ情報を含む。

[0x3D セクター ] ベースログレコードのシャドウコピー。

[1 セクター ] 情報落ちを含む。

[1 セクター ] 情報落ちレコードのシャドウコピー。

Page 22: [CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long

レコードヘッダー

修正上位バイト

セクター数 予備領域 1 チェックサム

フォーマットのバージョン 予備領域 2

予備領域 3

現在の LSN

次の LSN レコードのオフセット配列( 0x10 * DWORD )

固定オフセット

ストリームインデックス

マジックセクター数のコピー

Page 23: [CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long

コントロールレコード

レコードヘッダー( 0x70 バイト)

ダンプ数 マジック( 0xC1F5C1F5000005F1C )

予備領域 1 拡張フェーズ 拡張ブロックインデックス

拡張ブロックインデックスシャドー

拡張後のブロックセクター

予備領域 2 予備領域 3

予備領域 4

拡張前のファイルセクター

データファイルセクター 情報落ちの種類

情報落ちフィールド

実際のレコード数 予備領域 5

レコードパラメータの配列( 0x18 * 数)

Page 24: [CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long

ベースログレコード

レコードヘッダー( 0x70 バイト)

ダンプ数

予備領域1

ベースログID ( GUID )

クライアント記号のハッシュ配列( 0x0B * QWORD )

+配列の終わり

コンテナ記号のハッシュ配列( 0x0B * QWORD )

共有セキュリティディスクリプタ記号のハッシュ配列( 0x0B * QWORD )

予備領域2

クライアント数 予備領域

3予備領域4

予備領域5

コンテナ数

クライアントコンテキストのオフセット配列( 0x7C * DWORD )

コンテナコンテキストのオフセット配列( 0x400 * DWORD )

予備領域6

更新シーケンス番号

Page 25: [CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long

コンテナレコード

レコードヘッダー( 0x70 バイト)

仮想 LSN 補償処理が必要な次の LSN

直前の LSN レコードサイズ 次のレコードサイズ

フラグ レコードタイプ

データオフセット

Page 26: [CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long

シンボルヘッダー

タイプ( 0xC1FDF006 ) サイズ チェックサム ネームオフセット

予備領域 1 予備領域 2

予備領域 3ブロックネームオフセット

ブロック属性オフセット

Page 27: [CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long

クライアントコンテキスト

タイプ( 0xC1FDF007 ) サイズストリームインデックス 予備領域 1 フラッシュスレッド

予備領域( 0x28 バイト)

予備 LSN1 ベース LSN

最後にフラッシュされたLSN

最後の LSN

予備 LSN2 予備 LSN3

予備領域 3 ( 0x20 バイト)

Page 28: [CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long

コンテナコンテキスト

タイプ( 0xC1FDF008) サイズ コンテナファイルサイズ 予備領域 1

物理コンテナインデックス

論理コンテナインデックス 予備 LSN1

予備領域 2フラグストリーム数

Page 29: [CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long

CClfsBaseFilePersisted::ReadImage

実際のレコード数

レコードパラメータの配列

コントロールレコード

Page 30: [CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long

レコードパラメータ

バッファポインタ サイズ オフセット

Page 31: [CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long

CClfsBaseFile::GetBaseLogRecord

CClfsBaseFile::GetBaseLogRecord(CClfsBaseFile* this) xor eax, eax cmp ax, [rcx+28h] jz short locret_1C00335DB mov rcx, [rcx+30h] mov rcx, [rcx+30h] test rcx, rcx jz short locret_1C00335DB mov eax, [rcx+28h] add rax, rcx

locret_1C00335DB: retn

Page 32: [CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long

CClfsBaseFile::AcquireMetadataBlock

Page 33: [CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long

Use of AcquireMetadataBlock

Page 34: [CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long

CClfsBaseFilePersisted::OpenImage

クライアント記号ハッシュ配列

ベースログレコード

コンテナ記号ハッシュ配列

SD記号ハッシュ配列

Page 35: [CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long

シンボルハッシュ関数__int64 ClfsHashPJW(const struct _UNICODE_STRING *a1){ unsigned int v1 = 0, v4 = 0, v6; PWSTR wchar_buffer = a1->Buffer; const struct _UNICODE_STRING *v3 = a1; if ( a1->Length & 0xFFFE ){ do{ int v5 = 0x10 * v1 + RtlUpcaseUnicodeChar(*wchar_buffer); v6 = v5 & 0xF0000000; if ( v5 & 0xF0000000 ) v5 ^= v6 >> 0x18; v1 = v6 ^ v5; ++wchar_buffer; ++v4; } while ( v4 < (unsigned int)v3->Length >> 1 ); } return v1;}

Page 36: [CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long

強化 CFLS フォーマットファジング• ターゲットを熟知している場合、それを上手にファズ

できる。• 現在わかっていること :

• BLF ファイルフォーマット• コントロールレコード• ベースログレコード

• 記号ヘッダー• クライアントコンテキスト• コンテナコンテキスト

• コンテナレコード

• Clfs.sys は、これらのフォーマットをパースするための固有のロジックを持っているが、それは十分頑強なのだろうか?

Page 37: [CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long

強化 CFLS フォーマットファジング

Select

Deserialize

Mutate

Immune

Serialize

push デシリアライズ

シリアライズ

抗体

Yukako Takahashi
★Inmune → Immune のタイプミス?
Yukako Takahashi
ここのところは講演者に確認中です。
Yukako Takahashi
immuneでOKという確認を取りました。ひとまず免疫と訳してみました。
Yukako Takahashi
mutateなど、横文字にしないほうが良さそうなものについては、そのままにしてみました。
Page 38: [CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long

強化 CFLS フォーマットファジング

class CControlRecord : public CFormatBase<CControlRecord>{ …… virtual bool serialize(ostream & out) const override; virtual bool deserialize(istream & in) override; virtual bool mutate() override; ……};

class CBaseLogRecord : public CFormatBase<CBaseLogRecord>{ …… virtual bool serialize(ostream & out) const override; virtual bool deserialize(istream & in) override; virtual bool mutate() override; ……};……

Page 39: [CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long

強化 CFLS フォーマットファジング

bool CCLFSFormat::deserialize(istream & in){ …… m_controlRecord.deserialize(in); m_controlRecordShadow.deserialize(in); m_baseLogRecord.deserialize(in); m_baseLogRecordShadow.deserialize(in); m_truncateRecord.deserialize(in); m_truncateRecordShadow.deserialize(in); ……}

bool CCLFSFormat::mutate(istream & in){ …… }

bool CCLFSFormat::serialize(istream & in){ …… }

Page 40: [CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long

強化 CFLS フォーマットファジング

CCLFSDocument::CCLFSDocument(const string filename) :m_template_filename(filename) ,m_template_stream(filename, ios::in | ios::binary){ /* number: 0 */m_engine.registerFilter(make_unique<CCommonErrorBypass>()); /* number: 1 */m_engine.registerFilter(make_unique<CPOC_XXX_1>()); /* number: 2 */m_engine.registerFilter(make_unique<CPOC_XXX_2>()); /* number: 3 */m_engine.registerFilter(make_unique<CPOC_XXX_3>()); /* number: 4 */m_engine.registerFilter(make_unique<CPOC_XXX_4>()); /* number: 5 */m_engine.registerFilter(make_unique<CPOC_XXX_5>()); ……}

void CCLFSDocument::mutate(){ m_clfs_format.mutate(); m_engine.triggerFilter(3, m_orginal_clfs_format, m_clfs_format);}

Page 41: [CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long

強化 CFLS フォーマットファジング

bool CPOCFilterEngine::triggerFilter(size_t filterIndex, CCLFSFormat& originalFormat, CCLFSFormat& format){ bool b_triggered = false; for (size_t i = 0; i < m_filters.size(); i++) { if (i == filterIndex) { m_filters[i]->infect(originalFormat, format); b_triggered = true; } else m_filters[i]->immune(originalFormat, format); }

return b_triggered;}

Page 42: [CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long

Q & A

ご清聴ありがとうございました!