Free、UAF)の脆弱性についてMicrosoftに報告しました。深刻度「緊急」に該当する脆弱性とされ、識別番号「CVE-2019-1208」が割り当てられたこの脆弱性に対し、Microsoftは2019年9月のセキュリティ更新プログラムを公開し、対処済みとなりました。Concept、PoC)を報告しました。CVE-2019-1208」とは上述したように、「CVE-2019-1208」はUAFの脆弱性です。このクラスの脆弱性は、データを破損させ、プロセスを停止させる恐れがあります。これらの動作が引き起こされたタイミングに応じて、攻撃者は任意の、また遠隔からのコードの実行が可能になります。脆弱性の利用に成功した場合、攻撃者は、現在のユーザが持つシステム権限と同等の権限を取得する可能性があります。現在のユーザが管理者権限を所有していた場合、攻撃者はシステムを乗っ取り、以下の動作の実行が可能となります。■脆弱性「CVE-2019-1208」による影響予測この脆弱性を利用した攻撃のシナリオとして、ソーシャルエンジニアリングの技巧を施したフィッシングメールを送信し、ユーザが、IEで、脆弱性攻撃(エクスプロイト)コードが埋め込まれた不正なWebサイトにアクセスするように仕向けます。脆弱性攻撃コードを含むファイルが添付されたスパムメールをユーザに送信する手口も考えられます。ActiveXコントロールが埋め込まれたアプリケーションファイルが挙げられます。攻撃者は、ユーザが提供したコンテンツや広告を受け入れる正規のWebサイトを侵害することによって、脆弱性攻撃コードを埋め込むことも可能です。11でも無効になりました。したがって、今回紹介するPoCはローカルモードで実証されたものです。Microsoftによれば、この設定はレジストリまたはグループポリシーを介して有効にすることが可能です。いずれにせよ、攻撃者はスパムメールやその他のソーシャルエンジニアリングと組み合わせることにより、この脆弱性を利用する攻撃を行う可能性があります。発端は、2018年5月から6月にかけてVBScriptエンジンのAPI関数を含むモジュール「vbscript.dll」の関数に加えられた変更を比較しようとしてBinDiffを使用したことでした。そこで「SafeArrayAddRef」関数、「SafeArrayReleaseData」関数、および「SafeArrayReleaseDescriptor」関数を利用した変更が確認されました。調査を進めるにあたり、過去に脆弱性「CVE-2018-8373」を見つけた経験から「VBScriptClass」関数を使用したところ、以下の手順でUAFの脆弱性をトリガーできることがわかりました。Get」関数のコールバックをトリガーします。このコールバックで、バリアント「arr」に新しい「SafeArray」を作成します。この新しい「SafeArray」は「SafeArrayAddRef」関数によって保護されていないため、通常のコードフローの仮定は、このコールバックによって破られます(図1を参照)。Get」から戻ると、VbsJoinのコードフローは、「SafeArrayReleaseData」関数と「SafeArrayReleaseDescriptor」関数を呼び出して、「SafeArrayData」関数と「SafeArrayDescriptor」関数を参照する回数を減らします。新しい「SafeArray」は、「SafeArrayAddRef」関数によって保護されていないため、「SafeArrayData」関数および「SafeArrayDescriptor」関数の参照回数は0です。したがって、新しい「SafeArray」の「SafeArrayData」関数および「SafeArrayDescriptor」関数は、「SafeArrayReleaseData」関数および「SafeArrayReleaseDescriptor」関数を使用して解放されます(図2を参照)。Array(0)のコード図2-3:コールバックのコード(赤枠内)「VbsJoin」関数の戻り値を「arr(0)」に保存すると、PoCは「vbscript!AccessArray」関数でクラッシュします(図3)。これは、「SafeArrayDescriptor」が解放されますが、バリアント「arr」は解放された「SafeArrayDescriptor」のポインタを保存するためです。図3:「vbscript!AccessArray」関数でPoCがクラッシュした様子を示すコード■PoCはUAFの脆弱性をどう利用したか今回のPoCではUAFがトリガーされる経緯を完全に再現するにあたって、基本的な文字列/バイナリ文字列(BSTR)をデータ構造として使用したため、限定的に成功したといえます。「SafeArray」関数は多次元配列ですが、「VbsJoin」関数は1次元配列しか処理できないため、コールバックにおいて「SafeArray」関数の次元を変更しました。残念ながらそれでは成功せず、「Joinで配列型が一致しない」というランタイムエラーが確認されました。Next」を使用して、このランタイムエラーを回避しました。以下の図4は、変更後のPoCです。Next」を使用して変更したPoC0x20バイトの解放されたメモリを取得した後、0x20バイトのBSTRを使用して、大きなサイズの「SafeArray」を偽造しました。Shui」を利用して、このBSTRは0x20バイトの安定して解放されたメモリを再利用します。以下の図5-1に示すように、最終的に、要素番号「0x7ffffffff」および要素サイズ1biteの偽の1次元SafeArrayを取得しました。図5-1:偽のSafeArray「0x00000000」から「0x7fffffff」までのメモリの読み取り/書き込みに使用する「SafeArray」を作成しました。Zuckerbraun氏による技術を適用し、ヒープスプレー攻撃を利用して固定読み取り/書き込みアドレス「(0x28281000)」を取得しました。これは、脆弱性を突くために利用する読み取り/書き込みアドレスの一部を確保するために利用します。Execution)を実行しましたが、偽の辞書を作成するためには別の方法を使用しました。今回は、図6に示すように、前述のBSTRを使用して、以下の手順を実行しました。Exists」関数を「kernel32!Winexec」関数に置き換えます。calc.exe)」をこのBSTRに書き込みます。&h1000).Exists」のダミーを利用して「Winexec」関数をトリガーします。■被害に遭わないためには単体では危険性は低いと見積もられた脆弱性であっても、攻撃者は他の方法と組み合わせたり、利用者を騙したりすることにより、有効化してくる場合があります。いずれにせよ、ユーザと法人組織は常に脆弱性に対するベストプラクティスを採用する必要があります。パッチを適用して更新する必要でない場合はコンポーネントを無効、もしくは使用制限を設けるこの調査の技術的詳細は、こちら(英語)を参照してください。