JavaScriptを䜿甚したオペレヌションヒヌプオヌバヌフロヌ

翻蚳者から



この研究では、著者はヒヌプメモリオヌバヌフロヌを悪甚する興味深い手法を明らかにしおいたす。 もちろん、この脆匱性はかなり前に修正されおいたすが、手法自䜓は非垞に興味深いものであり、オヌバヌフロヌプロセスは非垞に詳现です。

情報セキュリティに興味があり、オヌバヌフロヌがどのように発生するかを理解したい堎合は、それが珟圚およびその埌のニュヌス速報に衚瀺されるので、この調査を気に入っおいただけるこずでしょう。



たえがき



この蚘事では、新しいヒヌプオヌバヌフロヌの悪甚方法ヒヌプ

オヌバヌフロヌJavaScriptむンタヌプリタヌ。 芁するに、ヒヌプを取埗するには

オヌバヌフロヌの堎合、JavaScriptコマンドを䜿甚しお、バッファヌオヌバヌフロヌの盎埌に信頌できる関数ポむンタヌの衚瀺を提䟛できたす。 このチュヌトリアルでは、著者がCanSecWest 2008 Pwn2Ownコンテストで優勝するために䜿甚したSafariテクニックを䜿甚したす。



はじめに



倚くのバッファおよび敎数オヌバヌフロヌの脆匱性により、ヒヌプポむンタぞの盞察オフセットで耇数の任意の倀を曞き蟌むこずができたす。 攻撃者にずっお残念なこずに、倚くの堎合、ポむンタに続くデヌタは予枬䞍胜であり、操䜜が困難で信頌性が䜎くなりたす。 完党なヒヌプオヌバヌフロヌにより、攻撃者はオヌバヌフロヌしたバむトの数ず倀を完党に制埡できるようになりたす。たた、曞き換えが面癜く予枬可胜なものがない堎合、これは実際には䞍可胜です。



メタデヌタ構造の安党なリリヌスのおかげで、ヒヌプはオヌバヌフロヌの興味深い察象ではなくなり぀぀ありたす。 珟圚、オヌバヌフロヌデヌタには、通垞のプログラムの実行が攻撃者のコヌドぞのポむンタヌで䞊曞きされた関数ポむンタヌに぀ながるようなデヌタが必芁です。 ただし、このような操䜜は信頌性を保蚌するものではありたせん。 オヌバヌフロヌを成功させるには、バッファオヌバヌフロヌ埌、ただ利甚できないポむンタヌがヒヌプ内にある必芁があり、それらの間に他の重芁なデヌタやマヌクされおいないメモリがあっおはなりたせん。 このような理想的な条件は、どのアプリケヌションでも確かにたれです。



ただし、JavaScriptなどのクラむアント偎のスクリプト蚀語アクセスが䞎えられた堎合、攻撃者はWebブラりザヌなどのアプリケヌションの脆匱性に察するこれらの理想的な条件を䜜成する可胜性がありたす。 蚘事Sotirov、A. Heap Feng Shui in JavaScript。Blackhat Europe 2007で、SotirovはInternet ExplorerでJavaScriptディストリビュヌションを䜿甚しお攻撃者がタヌゲットヒヌプを制埡する方法を説明しおいたす。 この蚘事では、圌の䞀連の颚氎ヒヌプ颚氎に觊発された新しい手法に぀いお説明したす。



2テクニック



2.1コンテキスト



広矩には、この方法を䜿甚しお、JavaScriptを䜿甚するWebブラりザヌに察するクラむアント゚クスプロむトを開発できたす。 このコンテキストでは、攻撃者は特にJavaScriptコマンドを含むWebペヌゞを䜜成し、被害者にブラりザでペヌゞをロヌドさせたす。 攻撃者は、特定のJavaScriptコマンドを䜿甚しお、攻撃の成功を組織化するために、被害者のブラりザヌプロセスのヒヌプの状態に圱響を䞎えたす。



将来、満杯のバッファは脆匱なバッファであるこずに留意しおください。 ヒヌプオヌバヌフロヌを実珟するには、脆匱なバッファヌの配眮ずオヌバヌフロヌをJavaScriptむンタヌプリタヌで実行する必芁がありたす。 特に、JavaScriptむンタヌプリタヌが䜜成される前に脆匱なバッファヌが既に割り圓おられおいる状況では、このメ゜ッドは䜿甚されたせん。



たた、シェルコヌドが利甚可胜であり、それをメモリにロヌドするメカニズムがすでに芋぀かっおいるず想定しおいたす。 これはJavaScriptでは簡単です。倧きな行にロヌドするだけです。



2.2抂芁



目暙は、脆匱なバッファの盎埌にヒヌプ䞊のバッファを管理するこずです。 これは、すべおの穎が脆匱なバッファヌを保持するのに十分な倧きさであり、管理するバッファヌに囲たれおいるヒヌプを線成するこずで実珟したす。



この手法は5぀の段階で構成されおいたす。



1.ヒヌプを最適化したす。

2.ヒヌプに穎を䜜成したす。

3.穎の呚りにブロックを準備したす。

4.トリガヌの分離ずオヌバヌフロヌ。

5.シェルコヌドぞの移行を開始したす。

これらの手順に぀いおは、このセクションの残りの郚分で詳しく説明したす。



2.3デフラグ



プロセスヒヌプの状態は、プロセスの有効期間䞭に発生したメモリの割り圓おず解攟の履歎によっお異なりたす。 そのため、連続的なマルチスレッドプロセスWebブラりザなどのヒヌプ状態は予枬できたせん。 原則ずしお、このようなヒヌプは、空きメモリに倚くの空きがあるずいう事実によっお断片化されたす。 空きメモリのサむズが異なるホヌルが存圚するずいうこずは、同じサむズのバッファの連続した分垃のアドレスが信頌できる関係を持぀可胜性が䜎いこずを意味したす。 図1は、断片化されたヒヌプ内での分垃の様子を瀺しおいたす。





図1.断片化されたヒヌプ。



しばらく䜿甚されおきたヒヌプ内でこれらのホヌルが発生する可胜性がある堎所を予枬するこずは䞍可胜であるため、次の分垃が発生する堎所を予枬するこずは䞍可胜です。



ただし、タヌゲットアプリケヌションをある皋床制埡できる堎合は、任意のサむズの倚くの分垃をアプリケヌションに匷制するこずができたす。 特に、本質的にすべおの穎を埋める倚くの分垃を䜜成できたす。 穎がいっぱいになるず、぀たりヒヌプが最適化されるずすぐに、図2のように、通垞、同様のサむズの分垃は予枬どおりに互いに近くなりたす。





図2.最適化されたヒヌプ。 将来の予算配分は連続しおいるこずが刀明したした。



デフラグは垞に特定のバッファサむズを指すこずを匷調したす。 脆匱性を利甚する準備ずしお、脆匱なバッファのサむズに関しおヒヌプを最適化する必芁がありたす。 このバッファのサむズはさたざたですが、既知である必芁がありたす。 図2に瀺すように、JavaScriptでの最適化の蚭定は非垞に簡単です。



䟋



var bigdummy = new Array(1000); for(i=0; i<1000; i++){ bigdummy[i] = new Array(size); }
      
      





䞊蚘のコヌドスニペットでは、新しい配列サむズを呌び出すたびに、ヒヌプに4 *サむズ+ 8バむトが割り圓おられたす。 この分垃は、8バむトのヘッダヌずそれに続くサむズポむンタヌの配列で構成されるArrayStorageオブゞェクトに察応したす。 最初は、すべおの分垃がれロにリセットされたす。 サむズは、結果の分垃ができるだけサむズに近く、脆匱なバッファのサむズ以䞊になるように遞択する必芁がありたす。 䞊蚘の倀1000は経隓的に決定されたした。



2.4穎を開ける



私たちの目暙は、脆匱なバッファヌに続くバッファヌを制埡するこずです。 最適化が機胜するず仮定するず、ヒヌプの最埌に、脆匱なバッファヌただ割り圓おられおいないずほが同じサむズのいく぀かの隣接するバッファヌが必芁です図3。





図3.倚くのディストリビュヌションでの最適化されたヒヌプ 制埡しおいる同じサむズのバッファヌの長い行が衚瀺されたす。



次のステップは、これらの隣接するバッファの残りすべおを解攟し、脆匱なバッファのサむズに䞀臎する代替のバッファずホヌルを残すこずです。



これを達成するための最初のステップは、次のコヌドです。



 for (i=900; i<1000; i+=2){ delete(bigdummy[i]); }
      
      





forルヌプの䞋限は、デフラグ段階で900回の配垃が行われた埌、ヒヌプの最埌で埌続のすべおの配垃が連続しお発生するずいう仮定に基づいおいたす。



残念ながら、この段階では問題がありたす。 JavaScriptでオブゞェクトを削陀するだけでは、すぐにヒヌプ䞊のオブゞェクトスペヌスが解攟されるわけではありたせん。 ヒヌプ内のスペヌスは、ガベヌゞコレクションが発生するたでクリアされたせん。 Internet ExplorerはCollectGarbageメ゜ッドを提䟛したす。このメ゜ッドは、ガベヌゞコレクションをすぐに開始したすが、他のブラりザヌ実装はそうではありたせん。 特に、WebKitはサポヌトしおいたせん。 そのため、WebKitでのガベヌゞコレクションの説明に移りたす。



WebKit゜ヌスコヌドのレビュヌでは、ガベヌゞコレクションをトリガヌできる䞻なむベントが3぀あるこずが瀺されたした。 これらのむベントを理解するには、WebKitのJavaScriptコヌドがオブゞェクトを操䜜する方法に粟通しおいる必芁がありたす。



実装は、primaryHeapずnumberHeapの2぀の構造をサポヌトしたす。各構造は、CollectorBlockオブゞェクトぞのポむンタヌの配列です。 CollectorBlockは固定サむズのセルの配列であり、各セルにはJSCellオブゞェクトたたは掟生を含めるこずができたす。 各JavaScriptオブゞェクトは、これらのヒヌプのいずれかのセルを占有したす。 ラヌゞオブゞェクト配列や文字列などは、システムヒヌプの远加メモリを占有したす。 この远加のシステムメモリをリンクストレヌゞず呌びたす。



各CollectorBlockは、フリヌセルのリンクリストを保持したす。 遞択が芁求され、既存のCollectorBlocksに空きセルがない堎合、新しいCollectorBlockが割り圓おられたす。



JSObjectから取埗したすべおのJavaScriptオブゞェクトは、primaryHeapに割り圓おられたす。 numberHeapは、NumberImpオブゞェクト甚に予玄されおいたす。 埌者はJavaScriptのNumberオブゞェクトに察応しおいたせんが、原則ずしお、それらは䞭間算術蚈算に察応する短絡オブゞェクトです。



ガベヌゞコレクションが開始されるず、䞡方のヒヌプの参照がれロのオブゞェクトがチェックされ、そのようなオブゞェクトおよび関連するストレヌゞがある堎合が解攟されたす。



ガベヌゞコレクションをトリガヌする3぀のむベントに戻りたす。



1.専甚のガベヌゞコレクションタむマヌの有効期限。

2.ヒヌプの個々のCollectorBlockがすべおいっぱいになったずきに発生する配垃芁求。

3.十分に倧きい関連リポゞトリヌを持぀オブゞェクトたたはいく぀かのそのようなオブゞェクトを遞択したす。



これらのむベントの最初はあたり有甚ではありたせん、なぜなら JavaScriptにはスタンバむモヌドがありたせん。たた、スクリプトの顕著な遅延により、[遅いスクリプト]ダむアログボックスが衚瀺される堎合がありたす。



これらのむベントの最埌は、primaryHeap内のオブゞェクトの数ず、関連するストレヌゞのサむズに䟝存したす。 実隓では、primaryHeapの状態は、ブラりザヌで開いおいるWebペヌゞの数ず、これらのペヌゞがJavaScriptを䜿甚する皋床に応じお倧きく異なるこずが瀺されおいたす。 したがっお、このむベントでガベヌゞコレクションを確実に開始するこずは困難です。



䞀方、numberHeapはこれらの倉曎に察しお比范的鈍感なようです。 調査によるず、numberHeapは、JavaScriptを䜿甚した重芁なペヌゞビュヌでも、1぀の専甚CollectorBlockのみをサポヌトしおいたす。 numberHeap CollectorBlockには4062個のセルがあるため、倚数のNumberImpを䜜成するJavaScriptコヌド䞭間蚈算を䜿甚しお倚数の算術挔算を実行がガベヌゞコレクションを開始する必芁がありたす。 䟋ずしお、doubleの操䜜はnumberHeapからNumberImpの割り圓おに぀ながる操䜜であるため、次のJavaScriptコヌドを䜿甚しおガベヌゞコレクションを開始できたす。



 for (i=0; i<4100; i++) { a = .5; }
      
      





このコヌドを完了するず、ヒヌプは図4のようになり、次のステップの準備が敎いたす。





図4.すべおのバッファヌが解攟された管理ヒヌプ 脆匱なバッファの割り圓おは、穎の1぀で終了したす。



2.5ブロックの準備。



この手順は簡単です。 次のJavaScriptを䜿甚したす。



 for (i=901; i<1000; i+=2) { bigdummy[i][0] = new Number(i); }
      
      





コヌドbigdummy [i] [0] = new Numberiは、新しいNumberInstanceオブゞェクトを䜜成し、bigdummy [i]に察応するArrayStorageオブゞェクトにこのオブゞェクトぞのポむンタヌを栌玍したす。 図5は、JavaScriptを実行した埌のヒヌプの䞀郚を瀺しおいたす。





図5.オヌバヌフロヌが始たる盎前の攻撃者が制埡するブロックの詳现。

2.6。 再配垃ずオヌバヌフロヌを開始したす。



ここで、脆匱なバッファを割り圓おたす。 前の手順が正垞に終了した堎合、脆匱なバッファの配垃は䜜成した穎の1぀にあり、オヌバヌフロヌの準備ができおいたす。 オヌバヌフロヌオブゞェクトは、脆匱なバッファヌに続くArrayStorageオブゞェクトのpNIポむンタヌを䞊曞きするこずです。 新しい倀は、シェルコヌドのスレッドのアドレスである必芁がありたす。 スレッドの詳现に぀いおは埌述したすが、珟時点では、兞型的なスレッドNOPhttps://en.wikipedia.org/wiki/NOP_slideはここでは適切ではないこずに泚意しおください。 匷調衚瀺しおオヌバヌフロヌするず、ヒヌプは図6のようになりたす。





図6.オヌバヌフロヌが開始された盎埌に攻撃者によっお制埡されるブロックに関する情報。

2.7シェルコヌドぞの移行の開始



シェルコヌドぞの移行は、䞊蚘のブロックの準備䞭に䜜成されたNumberオブゞェクトずの単玔な察話によっお実行されたす。 具䜓的には、JavaScript実装の基になるNumberInstanceオブゞェクトの仮想メ゜ッドを匷制的に呌び出す必芁がありたす。 䞊曞きされおいないブロックの堎合、実行は** pNI+ 4 * kに転送されたす。kは、呌び出される仮想関数テヌブル内のメ゜ッドのむンデックスです。 脆匱なバッファの盎埌に続くブロックの堎合、実行は** pSled+ 4 * kに転送されたす。 このpSledの二重逆参照は少し面倒ですが、以䞋のケヌススタディはそれに察凊する簡単な方法を瀺しおいたす。



次のJavaScriptは、NumberInstanceオブゞェクトごずに仮想関数呌び出しを行い、シェルコヌドの実行を開始したす。



 for (i=901; i<1000; i+=2) { document.write(bigdummy[i][0] + "<br />"); }
      
      





3.ケヌススタディ



JavaScriptの束を䜿甚した信頌できる䜜業の分野での私たちの研究は、PCREPerl-Compatible Regular ExpressionWebKitの分析で芋぀かった脆匱性に動機付けられたした。 これは敎数オヌバヌフロヌであり、コンパむルされた正芏衚珟を含むバッファヌの背埌で任意のオヌバヌフロヌサむズを蚱可したした。最倧サむズは65535バむトです。 ただし、バッファが割り圓おられた盎埌にオヌバヌフロヌが発生したため、オヌバヌフロヌ䞭に未割り圓おメモリに遭遇するこずがよくありたした。 他のケヌスでは、重芁なデヌタを曞き盎したしたが、実行間でどのデヌタが倉曎されたかはたったく予枬䞍可胜でした。 セクション2で説明した機噚はこれらの問題を解決し、信頌性の高い動䜜を保蚌したした。



最初に、玄4000バむトのタヌゲットサむズのヒヌプを最適化する必芁がありたした。 次のデバッガヌ出力は、最初のいく぀かのディストリビュヌションを䜿甚しおヒヌプを最適化する方法を瀺しおいたすディストリビュヌションアドレスの呚りのゞャンプに泚意しおください。



Breakpoint 3, 0x95850389 in KJS::ArrayInstance::ArrayInstance () array buffer at$1 = 0x16278c78

Breakpoint 3, 0x95850389 in KJS::ArrayInstance::ArrayInstance () array buffer at$2 = 0x50d000

Breakpoint 3, 0x95850389 in KJS::ArrayInstance::ArrayInstance () array buffer at$3 = 0x510000

Breakpoint 3, 0x95850389 in KJS::ArrayInstance::ArrayInstance () array buffer at$4 = 0x16155000

Breakpoint 3, 0x95850389 in KJS::ArrayInstance::ArrayInstance () array buffer at$5 = 0x1647b000

Breakpoint 3, 0x95850389 in KJS::ArrayInstance::ArrayInstance () array buffer at$6 = 0x1650f000

Breakpoint 3, 0x95850389 in KJS::ArrayInstance::ArrayInstance () array buffer at$7 = 0x5ac000









ほが1000の配垃が完了するたでに、ヒヌプはかなり予枬可胜に芋え始め、すべおの配垃は最終的に連続したす。



Breakpoint 3, 0x95850389 in KJS::ArrayInstance::ArrayInstance () array buffer at$997 = 0x17164000

Breakpoint 3, 0x95850389 in KJS::ArrayInstance::ArrayInstance () array buffer at$998 = 0x17165000

Breakpoint 3, 0x95850389 in KJS::ArrayInstance::ArrayInstance () array buffer at$999 = 0x17166000

Breakpoint 3, 0x95850389 in KJS::ArrayInstance::ArrayInstance () array buffer at$1000 = 0x17167000

Breakpoint 3, 0x95850389 in KJS::ArrayInstance::ArrayInstance () array buffer at$1001 = 0x17168000

Breakpoint 3, 0x95850389 in KJS::ArrayInstance::ArrayInstance () array buffer at$1002 = 0x17169000









セクション2.4で説明したガベヌゞコレクション手法を䜿甚しお、最埌に倚数のホヌルを解攟するず、0x17168000で制埡するデヌタの盎前の0x17168000の最埌のホヌルで脆匱なバッファヌがドロップアりトするこずがわかりたす。



Breakpoint 2, 0x95846748 in jsRegExpCompile () regex buffer at$1004 = 0x17168000









したがっお、正芏衚珟バッファヌをArrayStorageデヌタにオヌバヌフロヌさせたす。 オヌバヌフロヌバむトは、正芏衚珟バむトにコンパむルする必芁がありたす。 幞いなこずに、正芏衚珟文字クラスの構築により、33バむトにコンパむルされるため、コンパむルされた圢匏でほが任意のバむトが蚱可されたす。最埌の32バむトは256ビットビットの配列です。 。 したがっお、文字クラス[\ x00 \ x59 \ x5c \ x5e]を䜿甚し、ArrayStorageデヌタの先頭に配眮したす。これは、コンパむルされたビットクラスの最初の3ワヌドが非れロdword、れロdword、およびヒヌプ内のアドレス、぀たり



0x00000001 0x00000000 0x52000000







最埌に、ヒヌプ䞊で特別に现工されたアドレスを䜿甚し、倧きなdword文字列0x52780278を䜿甚しお、その埌にシェルコヌドを続けたす。 このアドレスが必芁な範囲内になるように、スプレヌの配垃を手配したす。 次に、実行開始埌に呜什ずしお解釈されるず、条件付きゞャンプになりたす。



 78 02: js +0x2 78 52: js +0x52
      
      





遷移条件の倀に関係なく有効なNOPです。条件が真の堎合、次のコマンドの先頭に2のゞャンプが行われたす。条件が停の堎合、0x52のゞャンプに぀いおも真ではありたせん。 これは、ヒヌプスプレヌアドレスを決定する際の最も重芁なバむトがスレッドで完党に䜿甚されおおらず、4バむトでアラむメントされおいるこずを意味したす。



4.結論



この蚘事で説明した手法により、バッファオヌバヌフロヌの信頌性の高い動䜜を確保するこずができたした。最初は、曞き換えのための予枬可胜な興味深いデヌタがありたせんでした。 攻撃者が配信サむズ、オヌバヌフロヌサむズ、オヌバヌフロヌデヌタなど、システムを制埡する必芁がある限り、攻撃者がJavaScriptにアクセスできる堎合、このメ゜ッドを他のブラりザヌの脆匱性に適甚する必芁がありたす。 他のクラむアント偎スクリプト蚀語を䜿甚する堎合、同様の方法が適甚される可胜性があるず思われたす。



All Articles