Windows をより安全にする
      SafeSEH on MinGW
今ではほぼ役に立たない




              Tsukasa #01 (@a4lg)
自己紹介…は省略
自己紹介…は省略
自己紹介…は省略
自己紹介…は省略




    MinGW!!
What is MinGW?
• Windows 用のプログラムを
  GNU で作るためのツールチェーン + α
 – ほとんどの機能は本家 binutils/gcc で対応済
• 最近は 64-bit 向けフォークの
  mingw-w64 が面白い!
 – Windows 固有の機能にほとんど対応
 – カーネルモードドライバも (一応) 作れる!
 – 自分もパッチを 2 個ほど投げました。
What is this?
<?xml version="1.0" encoding="UTF-8"?>
<xfdf xmlns="http://ns.adobe.com/xfdf/">
<overflow [omitted] hÐpàhhDbd [censored]
Ô1ö1ÿGVh.exehcalc1æWj [censored] [omitted] ézÿÿÿëùÌÌ
[censored] /></xfdf>
What is this?
<?xml version="1.0" encoding="UTF-8"?>
<xfdf xmlns="http://ns.adobe.com/xfdf/">
<overflow [omitted] hÐpàhhDbd [censored]
Ô1ö1ÿGVh.exehcalc1æWj [censored] [omitted] ézÿÿÿëùÌÌ
[censored] /></xfdf>

• 情報セキュリティに関する問題の回答例
  – 脆弱性のアドバイザリ (CVE-2004-0194) と
    Acrobat Reader のバイナリから exploit を書け
  – ファイルを開くと電卓を起動する。

                    入社試験前問題
Exploitation Process (1)

               OVERFLOW!
                            戻り
  脆弱なバッファ
                           アドレス
Exploitation Process (1)

               OVERFLOW!
              ポインタ          戻り
  脆弱なバッファ
               変数          アドレス



• 戻りアドレスとの間にポインタ変数がある!
  – この部分をうまく回避しないと、戻りアドレスを
    上書きしても制御を奪えない。
    • オーバーフローの後もこの部分が複数回
      参照されるので、攻略が少し難しい。
SEH overwrite
• この攻撃には、Windows の例外処理機構を
  悪用した exploit が使用されている。
• 構造化例外処理 (Structured Exception Handling)
  – x86 版ではスタックに、例外ハンドラのアドレスや
    次の例外ハンドラを示す情報をスタックに積む。
SEH overwrite
• この攻撃には、Windows の例外処理機構を
  悪用した exploit が使用されている。
• 構造化例外処理 (Structured Exception Handling)
  – x86 版ではスタックに、例外ハンドラのアドレスや
    次の例外ハンドラを示す情報をスタックに積む。
  – この部分をうまく置き換えると、シェルコードが
    いとも簡単に実行されてしまう。
    • スタックやヒープのアドレスを
      細かく調べる必要がなくなる。
Exploitation Process (2)

               OVERFLOW!
              ポインタ          戻り     SEH
  脆弱なバッファ
               変数          アドレス   構造体



• スタック上の SEH 構造体を上書きする
  – その後、むしろ積極的に例外を発生させる!
  – Google: pop-pop-ret
  – すると、SEH 構造体の一部がコードとして実行される。
• 脆弱性なのは変わらないが、SEH 上書きのせいで
  攻略の難易度が飛躍的に下がってしまう…
What is this?
<?xml version="1.0" encoding="UTF-8"?>
<xfdf xmlns="http://ns.adobe.com/xfdf/">
<overflow [omitted] hÐpàhhDbd [censored]
Ô1ö1ÿGVh.exehcalc1æWj [censored] [omitted] ézÿÿÿëùÌÌ
[censored] /></xfdf>

• 情報セキュリティに関する問題の回答例
  – 脆弱性のアドバイザリ (CVE-2004-0194) と
    Acrobat Reader のバイナリから exploit を書け
  – ファイルを開くと電卓を起動する。

                    入社試験前問題
What is this?
<?xml version="1.0" encoding="UTF-8"?>
<xfdf xmlns="http://ns.adobe.com/xfdf/">
<overflow [omitted] hÐpàhhDbd [censored]
Ô1ö1ÿGVh.exehcalc1æWj [censored] [omitted] ézÿÿÿëùÌÌ
[censored] /></xfdf>

• 情報セキュリティに関する問題の回答例
  – 脆弱性のアドバイザリ (CVE-2004-0194) と
    Acrobat Reader のバイナリから exploit を書け
  – ファイルを開くと電卓を起動する。

                    入社試験前問題
SafeSEH!
• SEH の例外ハンドラは、予め決まっている。
• なら、それを予め登録しておく = SafeSEH
 – Windows XP SP2 で対応した保護機能
   (いわゆるソフトウェア DEP)
 – PE ファイル内に有効な例外ハンドラを格納する
 – それ以外のアドレスを例外ハンドラとして
   指定された場合には、単に強制終了させる。
   • 少なくとも、任意コード実行よりはマシ。
SafeSEH on MinGW (1)
• アセンブラ (GNU as)
  – SafeSEH 関連の擬似命令を定義
     • 一部 SEH 関連の擬似命令はすでに定義済
  – オブジェクトファイルに SafeSEH 情報をエミット
• リンカ (GNU ld)
  – オブジェクトファイルの SafeSEH 情報をリンク
• コンパイラ (GCC)
  – SafeSEH 対応を示すマクロを定義。
     • mingw-w64 の CRT では、SEH 情報を
       インラインアセンブラで (条件付き) 記述している。
SafeSEH on MinGW (2)
• SafeSEH 情報
  – COFF (.obj …) と PE (.exe …) で構造が違う!
• COFF
  – @feat.00 シンボル
       • SafeSEH 対応を示す特殊シンボル (bit 0 = 1)
  – .sxdata セクション
       • 例外ハンドラのシンボル番号リスト
• PE
  – IMAGE_LOAD_CONFIG_DIRECTORY 構造体
       • 例外ハンドラのアドレスリスト
SafeSEH on GNU as (1)
• 擬似命令: .safeseh_handler <symbol>
  – COFF の仕様上、ハンドラはシンボルで
    参照できる必要がある。
  – このハンドル時に .sxdata に
    シンボルのインデックスを追加する。
• アセンブル終了前
  – @feat.00 シンボルを追加する
• しかしこれはうまくいかない!
SafeSEH on GNU as (2)
• Problem 1 : シンボル番号がズレる!?
  – COFF 仕様によれば、シンボルテーブルは
    一定の規則でソートされる必要がある。
  – 擬似命令解釈時にはこの番号がわからない。
• Solution 1 : シンボルを後で .sxdata に吐く
  – 擬似命令解釈時にはシンボル情報だけ
    リストに入れておき、最後にまとめて
    .sxdata セクションに吐き出す。
• 状況がさらに悪化した…
SafeSEH on GNU as (3)
• Problem 2 : セクションもシンボルも弄れない
 – オブジェクトファイル処理最終段階では、
   セクションの内容が固定されており、データの
   追加が不可能。
 – シンボルはここでも並び替えられていない…
• 試行錯誤の末、なんとかできた!
SafeSEH on GNU as (4)
• オブジェクトファイル処理時に、
  COFF シンボルを強制的に並び替える。
 – coff_renumber_symbols 関数は本来本当に最後に
   使われるが、ここではその前に呼び出す!
• .sxdata にダミーデータを追加しておき、
  後で強制的に書き換える。
 – 擬似命令解釈時にダミーのデータを .sxdata に吐く
 – 最終段階で、このデータを実際のものに置換する
   • これは再配置処理などでもやるので、
     多分大丈夫だと思う。
SafeSEH on GNU as (5)
• .sxdata セクションの属性は特殊
 – IMAGE_SCN_LNK_INFO
• BFD 部分に手を入れて、.sxdata セクションの
  特殊扱いを追加する。
 – .text や .bss などの特殊扱いと同様。
 – ここへの変更は objdump などにも影響する。
SafeSEH on GNU ld
• .sxdata セクションを削除する
  – PE ではもはや必要ないため
  – リンカスクリプトの一部 (/DISCARD/) に追記
• オプション: --safeseh
  – リンク時に SafeSEH を有効にするオプション
  – SafeSEH 無効のバイナリ処理時にエラー生成
• COFF の SafeSEH 情報をリンクする


                              未完成orz
…時間切れorz
• 2 週間後を目処にパッチ公開予定。
 – mingw-w64 / GNU の本家に採用されればいいなぁ。
• 実は SafeSEH はあまり役に立たない orz
 – プロセス内に SafeSEH 無効バイナリがあれば
   SafeSEH の有効性が大幅に低下する。
 – ハードウェア DEP が有効な場合、この種の
   テクニックが使いにくくなる。
 – そもそも、ヒープでコードが実行できるなら、
   もっと単純な SEH overwrite + heap splay で
   攻略可能!
じゃあなんでやったの?
• むしゃくしゃしてやった(ry
じゃあなんでやったの?
• むしゃくしゃしてやった(ry
• SEH 関連で実装されていない機能が
  ほとんど存在しない!
 – x64, ARM, MIPS… の安全な SEH に対応。
   • UNIX 系でいう DWARF2 EH に近い
 – 実装されていないのは次のものだけ!
   • Itanium 版の安全な SEH
   • x86 専用の SafeSEH
 – なんか実装されていないのは中途半端に思えた。
Thank you!
• OTL

Windows をより安全にする SafeSEH on MinGW

  • 1.
    Windows をより安全にする SafeSEH on MinGW 今ではほぼ役に立たない Tsukasa #01 (@a4lg)
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
    What is MinGW? •Windows 用のプログラムを GNU で作るためのツールチェーン + α – ほとんどの機能は本家 binutils/gcc で対応済 • 最近は 64-bit 向けフォークの mingw-w64 が面白い! – Windows 固有の機能にほとんど対応 – カーネルモードドライバも (一応) 作れる! – 自分もパッチを 2 個ほど投げました。
  • 7.
    What is this? <?xmlversion="1.0" encoding="UTF-8"?> <xfdf xmlns="http://ns.adobe.com/xfdf/"> <overflow [omitted] hÐpàhhDbd [censored] Ô1ö1ÿGVh.exehcalc1æWj [censored] [omitted] ézÿÿÿëùÌÌ [censored] /></xfdf>
  • 8.
    What is this? <?xmlversion="1.0" encoding="UTF-8"?> <xfdf xmlns="http://ns.adobe.com/xfdf/"> <overflow [omitted] hÐpàhhDbd [censored] Ô1ö1ÿGVh.exehcalc1æWj [censored] [omitted] ézÿÿÿëùÌÌ [censored] /></xfdf> • 情報セキュリティに関する問題の回答例 – 脆弱性のアドバイザリ (CVE-2004-0194) と Acrobat Reader のバイナリから exploit を書け – ファイルを開くと電卓を起動する。 入社試験前問題
  • 9.
    Exploitation Process (1) OVERFLOW! 戻り 脆弱なバッファ アドレス
  • 10.
    Exploitation Process (1) OVERFLOW! ポインタ 戻り 脆弱なバッファ 変数 アドレス • 戻りアドレスとの間にポインタ変数がある! – この部分をうまく回避しないと、戻りアドレスを 上書きしても制御を奪えない。 • オーバーフローの後もこの部分が複数回 参照されるので、攻略が少し難しい。
  • 11.
    SEH overwrite • この攻撃には、Windowsの例外処理機構を 悪用した exploit が使用されている。 • 構造化例外処理 (Structured Exception Handling) – x86 版ではスタックに、例外ハンドラのアドレスや 次の例外ハンドラを示す情報をスタックに積む。
  • 12.
    SEH overwrite • この攻撃には、Windowsの例外処理機構を 悪用した exploit が使用されている。 • 構造化例外処理 (Structured Exception Handling) – x86 版ではスタックに、例外ハンドラのアドレスや 次の例外ハンドラを示す情報をスタックに積む。 – この部分をうまく置き換えると、シェルコードが いとも簡単に実行されてしまう。 • スタックやヒープのアドレスを 細かく調べる必要がなくなる。
  • 13.
    Exploitation Process (2) OVERFLOW! ポインタ 戻り SEH 脆弱なバッファ 変数 アドレス 構造体 • スタック上の SEH 構造体を上書きする – その後、むしろ積極的に例外を発生させる! – Google: pop-pop-ret – すると、SEH 構造体の一部がコードとして実行される。 • 脆弱性なのは変わらないが、SEH 上書きのせいで 攻略の難易度が飛躍的に下がってしまう…
  • 14.
    What is this? <?xmlversion="1.0" encoding="UTF-8"?> <xfdf xmlns="http://ns.adobe.com/xfdf/"> <overflow [omitted] hÐpàhhDbd [censored] Ô1ö1ÿGVh.exehcalc1æWj [censored] [omitted] ézÿÿÿëùÌÌ [censored] /></xfdf> • 情報セキュリティに関する問題の回答例 – 脆弱性のアドバイザリ (CVE-2004-0194) と Acrobat Reader のバイナリから exploit を書け – ファイルを開くと電卓を起動する。 入社試験前問題
  • 15.
    What is this? <?xmlversion="1.0" encoding="UTF-8"?> <xfdf xmlns="http://ns.adobe.com/xfdf/"> <overflow [omitted] hÐpàhhDbd [censored] Ô1ö1ÿGVh.exehcalc1æWj [censored] [omitted] ézÿÿÿëùÌÌ [censored] /></xfdf> • 情報セキュリティに関する問題の回答例 – 脆弱性のアドバイザリ (CVE-2004-0194) と Acrobat Reader のバイナリから exploit を書け – ファイルを開くと電卓を起動する。 入社試験前問題
  • 16.
    SafeSEH! • SEH の例外ハンドラは、予め決まっている。 •なら、それを予め登録しておく = SafeSEH – Windows XP SP2 で対応した保護機能 (いわゆるソフトウェア DEP) – PE ファイル内に有効な例外ハンドラを格納する – それ以外のアドレスを例外ハンドラとして 指定された場合には、単に強制終了させる。 • 少なくとも、任意コード実行よりはマシ。
  • 17.
    SafeSEH on MinGW(1) • アセンブラ (GNU as) – SafeSEH 関連の擬似命令を定義 • 一部 SEH 関連の擬似命令はすでに定義済 – オブジェクトファイルに SafeSEH 情報をエミット • リンカ (GNU ld) – オブジェクトファイルの SafeSEH 情報をリンク • コンパイラ (GCC) – SafeSEH 対応を示すマクロを定義。 • mingw-w64 の CRT では、SEH 情報を インラインアセンブラで (条件付き) 記述している。
  • 18.
    SafeSEH on MinGW(2) • SafeSEH 情報 – COFF (.obj …) と PE (.exe …) で構造が違う! • COFF – @feat.00 シンボル • SafeSEH 対応を示す特殊シンボル (bit 0 = 1) – .sxdata セクション • 例外ハンドラのシンボル番号リスト • PE – IMAGE_LOAD_CONFIG_DIRECTORY 構造体 • 例外ハンドラのアドレスリスト
  • 19.
    SafeSEH on GNUas (1) • 擬似命令: .safeseh_handler <symbol> – COFF の仕様上、ハンドラはシンボルで 参照できる必要がある。 – このハンドル時に .sxdata に シンボルのインデックスを追加する。 • アセンブル終了前 – @feat.00 シンボルを追加する • しかしこれはうまくいかない!
  • 20.
    SafeSEH on GNUas (2) • Problem 1 : シンボル番号がズレる!? – COFF 仕様によれば、シンボルテーブルは 一定の規則でソートされる必要がある。 – 擬似命令解釈時にはこの番号がわからない。 • Solution 1 : シンボルを後で .sxdata に吐く – 擬似命令解釈時にはシンボル情報だけ リストに入れておき、最後にまとめて .sxdata セクションに吐き出す。 • 状況がさらに悪化した…
  • 21.
    SafeSEH on GNUas (3) • Problem 2 : セクションもシンボルも弄れない – オブジェクトファイル処理最終段階では、 セクションの内容が固定されており、データの 追加が不可能。 – シンボルはここでも並び替えられていない… • 試行錯誤の末、なんとかできた!
  • 22.
    SafeSEH on GNUas (4) • オブジェクトファイル処理時に、 COFF シンボルを強制的に並び替える。 – coff_renumber_symbols 関数は本来本当に最後に 使われるが、ここではその前に呼び出す! • .sxdata にダミーデータを追加しておき、 後で強制的に書き換える。 – 擬似命令解釈時にダミーのデータを .sxdata に吐く – 最終段階で、このデータを実際のものに置換する • これは再配置処理などでもやるので、 多分大丈夫だと思う。
  • 23.
    SafeSEH on GNUas (5) • .sxdata セクションの属性は特殊 – IMAGE_SCN_LNK_INFO • BFD 部分に手を入れて、.sxdata セクションの 特殊扱いを追加する。 – .text や .bss などの特殊扱いと同様。 – ここへの変更は objdump などにも影響する。
  • 24.
    SafeSEH on GNUld • .sxdata セクションを削除する – PE ではもはや必要ないため – リンカスクリプトの一部 (/DISCARD/) に追記 • オプション: --safeseh – リンク時に SafeSEH を有効にするオプション – SafeSEH 無効のバイナリ処理時にエラー生成 • COFF の SafeSEH 情報をリンクする 未完成orz
  • 25.
    …時間切れorz • 2 週間後を目処にパッチ公開予定。 – mingw-w64 / GNU の本家に採用されればいいなぁ。 • 実は SafeSEH はあまり役に立たない orz – プロセス内に SafeSEH 無効バイナリがあれば SafeSEH の有効性が大幅に低下する。 – ハードウェア DEP が有効な場合、この種の テクニックが使いにくくなる。 – そもそも、ヒープでコードが実行できるなら、 もっと単純な SEH overwrite + heap splay で 攻略可能!
  • 26.
  • 27.
    じゃあなんでやったの? • むしゃくしゃしてやった(ry • SEH関連で実装されていない機能が ほとんど存在しない! – x64, ARM, MIPS… の安全な SEH に対応。 • UNIX 系でいう DWARF2 EH に近い – 実装されていないのは次のものだけ! • Itanium 版の安全な SEH • x86 専用の SafeSEH – なんか実装されていないのは中途半端に思えた。
  • 28.