「隔離されたヒープ」により、「解放後使用」の脆弱性を利用した攻撃を軽減

Microsoft が 2014年6月10日(米国時間)に公開した定例セキュリティ情報で、Internet Explorer(IE)に存在する「Use After Free(解放後使用)」の脆弱性を利用した攻撃を軽減させる画期的な改善が確認されました。トレンドマイクロが「isolated heap(隔離されたヒープ)」と名づけたこの改善策は、「解放後使用」の脆弱性利用の影響を受けやすい多くのオブジェクトに、隔離されたメモリ領域を用意するように設計されています。

IE 11 を例に説明します。更新プログラムの適用前は、関数「CHeadElement::CreateElement」により、ヒープからメモリ空間が割り当てられます。図1 はそのコードです。

図1:関数「CHeadElement::CreateElement」
図1:関数「CHeadElement::CreateElement」

図1 が示すように、メモリ空間は、ヒープ「g_hProcessHeap」から割り当てられています。これは、IE の初期設定のヒープです。つまり、すべての IEオブジェクトは、同じヒープを共有しています。更新プログラム適用後は、この個所でのコードは、以下のように変更されます。

図2:更新プログラム適用後の関数「CHeadElement::CreateElement」
図2:更新プログラム適用後の関数「CHeadElement::CreateElement」

図3:更新プログラム適用後の関数「CHeadElement::CreateElement」
図3:更新プログラム適用後の関数「CHeadElement::CreateElement」

図2 および図3 が示すように、IE はヒープ「g_hIsolatedHeap」からメモリ空間を割り当ていることがわかります。つまり、「隔離されたヒープ」を使用したこれらのクラスオブジェクトは、IE の他のオブジェクトと同じヒープを共有しないことになります。

■「隔離されたヒープ」は、「解放後使用」の脆弱性利用の攻撃をどう軽減できるか
「解放後使用」の脆弱性を利用した攻撃が最初に行う動作は、制御したオブジェクトを利用して、「解放後使用」のオブジェクトが持つメモリ空間を占拠することです。最近確認された「CVE-2014-0322」や「CVE-2014-1776」などの IE のゼロデイ脆弱性は、この技術を利用しています。

メモリ空間を占拠する方法は以下のとおりです。

  1. String もしくは Array を用いて、攻撃者が制御できるバッファを作成します。例:“var d=b.substring(0,(0×340-2)/2);”
  2. IEエレメントオブジェクトを作成します。例:“g_arr[a]=document.createElement(‘div’)”
  3. 脆弱性を利用し、対象とするオブジェクトを解放します。
  4. 1 で作成した String を用いて、2 で作成したオブジェクトの属性を繰り返し設定します。例:

    for(a=0;a<arrLen;++a)
    {
    g_arr[a].className=d.substring(0,d.length);

    }

手順4では、IE はヒープ「g_hProcessHeap」にメモリ空間を割り当てます。この例の手順4 では、以下のコールスタックが確認できます。

図4:関数「RtlAllocateHeap()」を呼び出す関数「CAttrArray::Set()」
図4:関数「RtlAllocateHeap()」を呼び出す関数「CAttrArray::Set()」

図4 では、関数「CAttrArray::Set()」が関数「RtlAllocateHeap()」を呼び出しているのが確認できます。このコールスタックは、以下のコードで実行されます。

図5:「RtlAllocateHeap」およびヒープ「g_hProcessHeap」を利用。バッファに String の情報がコピーされる
図5:「RtlAllocateHeap」およびヒープ「g_hProcessHeap」を利用。バッファに String の情報がコピーされる

今回の更新プログラムが公開される前は、「RtlAllocateHeap」が正しいサイズの場合、攻撃者が制御するバッファが、解放されたオブジェクトのメモリ空間を占拠する可能性が高くなりました。しかし、更新プログラムの公開後は、解放されたオブジェクトがヒープ「g_hIsolatedHeap」に割り当てられるため、解放されたオブジェクトのメモリ空間が、攻撃者が制御するバッファに占拠される可能性がなくなりました。これは、「解放後使用」の脆弱性を利用した攻撃を軽減できる良い解決策と言えます。

今回の更新プログラムのコードでは、ヒープ「g_hIsolatedHeap」は、HTML および SVG DOM エレメント(Cから始まるエレメント) に利用され、CTreeNode、CMarkup、CAttribute のようなエレメントを保護します。これらのオブジェクトは、「解放後使用」の脆弱性を抱える可能性がとても高く、「隔離されたヒープ」を通じて保護されることが重要です。

■「隔離されたヒープ」は、「解放後使用」の脆弱性利用の攻撃を緩和する完全な解決策となるか
完璧な解決策は存在しません。Microsoft が実施した今回の改善策により、脆弱性利用が難しくなったものの、この脆弱性が完全に除去されたわけではありません。実際、今回の改善策を回避する方法が理論的には 2つあります。

  1. 攻撃者が、String の代わりに、以下の 3つの条件に当てはまるオブジェクトを見つけた場合:
    1. 「隔離されたヒープ」に割り当てられている
    2. 「解放後使用」のオブジェクトとして正しいサイズである
    3. オブジェクトのコンテンツを簡単に制御できる

    ただし、攻撃者が上記の攻撃を実行できる妥当な方法を見つけられるかは不明です。

  2. オブジェクトの多くが、「隔離されたヒープ」ではなく、プロセスヒープをいまだに使用しています。こうしたオブジェクトが、「解放後使用」の脆弱性を抱えていた場合、今回の「隔離されたヒープ」の解決策は有効ではありません。しかし、Microsoft は、今後このような問題が起きた場合には、「隔離されたヒープ」を使用するオブジェクトを簡単に追加することができるとしています。

Microsoft が、IE のセキュリティ向上を継続して行い、脆弱性利用の攻撃を軽減させているのは好ましいことです。「隔離されたヒープ」は完全な解決策ではありませんが、今回の対策は、今後に向けてこうした種類の攻撃を緩和しようとする画期的な改善策だったと思われます。

参考記事:

 翻訳:品川 暁子(Core Technology Marketing, TrendLabs)