Windows イメージ ライブラリの自動テストにより、CVSS スコア 7.8 のゼロクリック コード実行を含む 37 のセキュリティ問題が明らかになりました。すべての脆弱性は、Mandiant による開示に続いて Microsoft によって修正されました。
Windows での 画像解析の脆弱性に関する説明を続けると、Windows でサポートされている 2 つのファイル タイプ、RAW と High Efficiency Image File Format (HEIF) に注目します。
Windows XP 以降の Windows バージョンには、これらのコーデックがデフォルトで含まれているため、RAW ファイルはWindows Camera Codec Packでサポートされています。コーデック ファイルは、system32 フォルダーにWindowsCodecsRaw.dllとして存在します。 RAW コーデックは Windows Imaging Component (WIC) 対応です。つまり、WIC を使用するプログラムは、コードを追加しなくても RAW 画像を読み込んでデコードできるはずです。これにより、Explorer でサムネイルとプレビューを表示できるようになり、Microsoft.Photos.exe でサポートされている RAW 画像を表示できるようになります。 WIC とコンポーネント オブジェクト モデル (COM) がファイル形式の検出と対応するコーデックの読み込みを処理するため、コーデックを WIC 対応にすることで、新しいファジング ハーネスの作成を回避できました。これは、ファジングをすぐに開始するのに非常に便利でしたが、COM の動作方法が原因で、重いパフォーマンスの負担 (10 倍から 30 倍の速度低下) が伴いました。
このコーデックは、Canon、Casio、Epson、Fujifilm、Kodak、Konica Minolta、Leica、Nikon、Olympus、Panasonic、Pentax、Samsung、Sony、およびその他のさまざまなカメラ モデルなど、複数のカメラ メーカーの RAW ファイルをサポートしています。表面的には、サポートされているカメラ モデルとメーカーの数を考えると、これは非常に魅力的な攻撃対象領域です。残念ながら、サポートされているファイル形式のほとんどは TIFF であるか、TIFF ファイル形式に基づいています。
RAW コーデックのファジングには、汎用の WIC ハーネスを使用し、 WindowsCodecsRaw.dllをコード カバレッジ モジュールとして使用します。コーパスはさまざまな公共の場所から収集され、コード カバレッジの一部を犠牲にしてサイズを最小限に抑えました。これは、RAW ファイルのファイル サイズが大きいため必要です。
ファジングでは、Canon CR2 形式の RAW ファイルのライブラリの解析で 2 つの整数オーバーフローの脆弱性と、HEIF ファイルの解析で 35 の脆弱性を発見しました。このブログ投稿では、最も注目すべき調査結果の詳細を紹介します。
CVE-2020-16968
CVE-2020-16968 は、特別に細工された Canon CR2 ファイルの解析中にヒープ オーバーフローを引き起こす整数オーバーフローです。
クラッシュの詳細を図 1 に示します。
|
図 1: RAW コーデックのクラッシュ
バグの根本原因は、図 2 のWindowsCodecsRaw!POBitmapImageRep::initでのオブジェクトの割り当てを調べることで見つけることができます。
|
図 2: 脆弱な機能
POBitmapImageRep::initは、カメラ センサーに関連付けられた複数の高さと幅を受け入れ、それらが受け入れる値の大まかな検証を行います。これらの値は画像ファイルから取得されるため、ユーザーが制御できます。この脆弱性は、最初の検証であっても、センサーの高さと幅の 32 ビットの乗算によって整数オーバーフローが発生し、ヒープ メモリの割り当てが必要以上に小さくなる可能性があるという事実から発生します。さらに、 POBitmapImageRep::initは、メモリの割り当てに使用される汎用関数であり、さまざまなメーカーの複数の RAW ファイル形式で使用されています。異なるファイル形式も同じ脆弱性を引き起こす可能性が非常に高いです。
整数オーバーフローの原因となるサンプル値を図 3 に示します。
|
図 3: 整数オーバーフローの計算
POBitmapImageRep::initによって割り当てられた結果のヒープ メモリは、イメージ ファイルからのデータを格納するために使用されます。これは、行ごとの 2 つのネストされたforループを使用して実行されます。 CCanonSRawLoadRaw::lossless_jpeg_load_rawの基礎となるコードは、 dcrawライブラリから C++ への関数の移植の結果です。
バリアント分析
この脆弱性の変種は、コードの他の部分でのHeapAllocの使用を相互参照することで簡単に見つけることができます。 CCanonSRawLoadRaw::GetBitmapImageには、ヒープ オーバーフローにつながる同様のパターンの整数オーバーフローが含まれていました。 Microsoft は、これを別の脆弱性 CVE-2020-0997 として修正することを決定しました。
パッチ
Microsoft は、図 4 に示すように、乗算を 64 ビットに昇格させ、結果が 4 GiB を超えた場合に救済することで、両方の整数オーバーフローにパッチを適用しました。
|
図 4: CVE-2020-16968 パッチ
HEIF
High Efficiency Image File Format (HEIF) は、ISO Base Media File Format (ISOBMFF) に基づく、画像および画像シーケンス用の新しいより動的なコンテナー形式です。 Windows 10 は、 HEIF 画像拡張Windows ストア アプリを通じて HEIF をサポートします。 HEIF Image Extension は WIC にも対応しているため、ファザーを変更することなく、古いハーネスを使用して HEIF デコーダーにアクセスできます。
HEIF はコンテナ形式であるため、複数の圧縮形式をサポートしています。
- HEIF (AVCI) の高度なビデオ コーディング (AVC)
- HEIF (HEIC) の高効率ビデオ コーディング (HEVC)
- HEIF (AVIF) の AOMedia ビデオ 1 (AV1)
Windows ストアの HEIF イメージ拡張機能は、AVC をサポートする基本的な HEIF コンテナーをサポートしています。 HEVCまたはAV1をデコードするには、追加の拡張機能をインストールする必要があります。 AV1 拡張機能のサポートはオープン ソースのlibavifに基づいていますが、HEVC は Microsoft 独自のコード ベースのようで、拡張機能をインストールするには 0.99 ドルの支払いが必要です (複雑な HEVC ライセンス条件のためと思われます)。すべての拡張機能は WIC に対応しており、HEIF は検出されたファイル形式に基づいて対応する拡張機能をロードするため、新しいハーネスは必要ありません。
HEIF をファジングするために、ファイル ヘッダーに基づいて 3 つの個別のコーパス セットを収集し、脆弱性が見つかる可能性に基づいてファジングすることにしました。そのサポートは、OSSFuzz や他の研究者によって定期的にファジングされている libavif コードに基づいているため、私は AVIF のファジングに費やす金額を最小限に抑えました。 AVC コーデックの普及と、比較的新しいコーデックである新しい HEVC 拡張機能にほとんどの時間を費やしたことを考えると、AVC 拡張機能に費やされた時間はわずかでした。
これらのコーデックをファジングすると、想像以上に実り多いものになりました。何百ものクラッシュをトリアージした後、合計 35 件の脆弱性が Microsoft Response Center (MSRC) に報告され、21 件の CVE が発生しました。クラッシュのほとんどは HEVC 拡張機能によるもので、AVIF 拡張機能によるものはごくわずかでした。 HEIF 拡張機能で見つけた解放後のヒープ使用 (UAF) の興味深いケースを説明しましょう。前述の UAF の脆弱性 (CVE-2020-17101) によるクラッシュの例を図 5 に示します。
|
図 5: HEIF クラッシュ
CVE-2020-17101 の use-after-free は、ISOBMFF ヘッダー解析の非常に早い段階で発生します。コード パスは、サムネイルの作成によって呼び出すことができます。これにより、基本的にこれはゼロクリックのリモート コード実行 (RCE) になります。この RCE を有効にするのに役立つのは、Windows エクスプローラーでサムネイルが既定でオンになっていることです。
ISOBMFF は、ボックスまたはアトムを使用して、代表的なファイルに格納されているデータをカプセル化します。各ボックスには、長さフィールド (4 バイト)、ボックス名 ( fourCCバイト シーケンス)、およびオプションのメタデータとデータが含まれます。データには、他のボックスと対応するメタデータを含めることができます。
基本的なボックスの解析はバイト “ftyp” (図 6 のオフセット 4) から始まり、サポートされているブランドを探します。ここで、「mif1」はブランド、「heic」は画像コレクションのブランドです。通常の解析シナリオでは、「mif1」の後に「meta」ボックスが続き、「meta」ボックスは「hdlr」、「iloc」、「iinf」、「pitm」などの他のボックスをカプセル化します。
概念実証 (PoC) ファイル (図 6) を解析すると、”meta” ボックスの後に “xxxx” 汎用ボックスが続きます (“hdlr” と “pict” ではなく)。 「pict」が欠落しているため、解析コードは次のボックス「pitm」と「iloc」を「型付きボックス」ではなく汎用ボックスと見なします。解析が「hdlr」ボックスに到達すると、「hdlr」ボックスと「pict」ボックスがタイプ付きボックスとして解析され、「meta」オブジェクトが更新されて見つかった「pict」ボックスがマークされます。ここで、解析は 2 番目の「pitm」ボックスに到達し、型指定されたボックスと見なされます。ポインターは「meta」オブジェクトで更新されます。次のボックス「zzzz」は汎用ボックスとして解析され、新しい「pitm」オブジェクトにアタッチされます。最初の解析はすべてCQTAtom::ScanChildren関数で行われます。
解析が最後に達し、 CHEIFImage::FinalParseAtom関数を呼び出すと、「iloc」、「iinf」、および「pitm」ボックスが見つかったかどうかがチェックされます。これらのボックスのいずれかが欠落している場合、オブジェクトのデストラクタが呼び出されてクリーンアップされ (オブジェクトは参照カウントされます)、関数CQTAtom::ScanChildrenを呼び出して解析が再開されます。デストラクタは、「pitm」に接続されている「zzzz」ボックスを解放しますが、「zzzz」オブジェクトへの格納されたポインタは「pitm」オブジェクトからヌルになりません。
解析が再開されると、「メタ」オブジェクトにはすでに「pict」があり、「xxxx」は汎用ボックスとして解析されますが、「pitm」と「iloc」(図 6 のオフセット 0x49 と 0x57) は入力ボックスとして解析されます。 .すでに「pitm」があるため、(完全な解析ではなく) その参照カウントがインクリメントされ、「iloc」が解析されます。この解析は失敗し、コードはエラーで救済されます。
解析が失敗したため、オブジェクトは再び破棄されます。デストラクタはリンク リストをループし、すべてのオブジェクトのデストラクタを呼び出します。 「pitm」オブジェクトには、解放された「zzzz」オブジェクトへのポインタ参照がまだあるため、コードは、解放されたオブジェクトの仮想関数テーブルにアクセスし、デストラクタを仮想関数として呼び出すことによって、「zzzz」オブジェクトをもう一度解放しようとします。ファジングされたプロセスのページ ヒープを有効にしているため、これによりクラッシュが発生します。
パッチ
Microsoft は、メモリを解放した後に保存されたポインター参照を無効にすることにより、この脆弱性にパッチを適用しました。
結論
このブログ シリーズのパート 3 では、Windows の組み込みイメージ パーサーの複数の脆弱性を紹介し、Windows でサポートされている新しいイメージ フォーマットを紹介します。報告されたすべての脆弱性のリストは、次の付録に記載されており、 Mandiant Vulnerability Disclosuresで参照されています。
付録
CVE ID |
提出日 |
確定日 |
脆弱性の種類 |
CVE-2020-0997 |
2020 年 7 月 1 日 |
2020 年 9 月 8 日 |
整数オーバーフロー |
CVE-2020-16968 |
2020 年 7 月 1 日 |
2020 年 10 月 13 日 |
整数オーバーフロー |
CVE-2020-17022 |
2020 年 7 月 3 日 |
2020 年 10 月 13 日 |
ヒープ/スタック オーバーフロー |
CVE-2021-24110 |
2020 年 7 月 7 日 |
2021 年 3 月 9 日 |
ヒープオーバーフロー |
CVE-2021-1643 |
2020 年 7 月 8 日 |
2021 年 1 月 12 日 |
ヒープオーバーフロー |
CVE-2020-17101 |
2020年7月10日 |
2020 年 11 月 10 日 |
無料後に使用 |
CVE-2020-17107 |
2020年7月13日 |
2020 年 11 月 10 日 |
ヒープオーバーフロー |
CVE-2020-17106 |
2020年7月13日 |
2020 年 11 月 10 日 |
ヒープオーバーフロー |
CVE-2020-17108 |
2020年7月21日 |
2020 年 11 月 10 日 |
ヒープオーバーフロー |
CVE-2020-17109 |
2020 年 7 月 30 日 |
2020 年 11 月 10 日 |
ヒープオーバーフロー |
CVE-2020-17105 |
2020年8月13日 |
2020 年 11 月 10 日 |
ヒープオーバーフロー |
CVE-2020-17110 |
2020年8月31日 |
2020 年 11 月 10 日 |
ヒープオーバーフロー |
CVE-2021-27048 |
2020 年 10 月 14 日 |
2021 年 3 月 9 日 |
ヒープオーバーフロー |
CVE-2021-27047 |
2020 年 10 月 14 日 |
2021 年 3 月 9 日 |
ヒープオーバーフロー |
CVE-2021-27049 |
2020 年 10 月 14 日 |
2021 年 3 月 9 日 |
ヒープオーバーフロー |
CVE-2021-27051 |
2020 年 10 月 14 日 |
2021 年 3 月 9 日 |
ヒープオーバーフロー |
CVE-2021-26902 |
2020 年 10 月 23 日 |
2021 年 3 月 9 日 |
ヒープオーバーフロー |
CVE-2021-27061 |
2020 年 10 月 23 日 |
2021 年 3 月 9 日 |
ヒープオーバーフロー |
CVE-2021-24089 |
2020 年 10 月 23 日 |
2021 年 3 月 9 日 |
ヒープ/スタック オーバーフロー |
CVE-2021-33775 |
2021 年 3 月 24 日 |
2021 年 7 月 13 日 |
ヒープオーバーフロー |
CVE-2021-33777 |
2021 年 3 月 24 日 |
2021 年 7 月 13 日 |
初期化されていないメモリ |
CVE-2021-33778 |
2021 年 3 月 24 日 |
2021 年 7 月 13 日 |
ヒープオーバーフロー |
CVE-2021-38661 |
2021 年 4 月 27 日 |
2021 年 9 月 14 日 |
ヒープオーバーフロー |
参照: https://www.mandiant.com/resources/blog/fuzzing-image-parsing-three
Comments