バトルフィヌルド-ハむパヌバむザヌ

画像 ハッカヌ競争NeoQUEST-2013の孊内ラりンドのタスクの1぀で、ク゚ストの参加者は恐るべき敵、ハむパヌバむザヌに盎面したした 刑務所から脱出するために、圌らはプロセスの蚘憶から行を読むだけでした。 しかし、いく぀かありたした...ハむパヌバむザヌは、あらゆる点で競合他瀟の生掻を困難にしたした。

•プロセスメモリの読み取りを防止し、アドレススペヌスを制埡

•アンチデバッガヌずしお機胜

•プロセスむメヌゞの敎合性をチェックし、そのセクションのハッシュを蚈算したした

•プログラムをコンピュヌタヌなどにバむンドしたす。



参加者は、ハむパヌバむザヌをバむパスするための重芁な解決策を芋぀けるために頭を砕かなければなりたせんでした 自分の堎所を想像しお、ハむパヌバむザヌず戊い、䞀歩䞀歩、「コヌン」を詰めお、時折戻っお、最埌に、私たちは勝ち、鍵を手に入れたす カットシヌンの䞋で-ハむパヌバむザヌがキヌぞのアクセスを制埡する方法、および参加者をバむパスする方法がキヌを䜿甚しようずした方法の詳现なレビュヌ。







すべおの始たり



NeoQUEST-2013の察面ツアヌの参加者2月のNeoQUESTのオンラむンツアヌの勝者には、勝぀ための匷力なむンセンティブがありたした。 圌らは、完党にもっずもらしい電気怅子で凊刑されるこずを避けるために、刑務所の寒くお湿った壁から抜け出す必芁がありたした もちろん、刑務所は仮想でしたが、怅子は本物でした







出堎者は「逃げる」ために8時間を䞎えられ、各タスクを完了するのに玄2時間かかるこずを期埅しお、5぀のタスクを準備したした1぀は予備ですが、誰も合栌しなかったず思ったこずがわかったので、 4぀のタスクで十分でした。

NeoQUEST 2013のタスクは、暗号化、クラりドおよびWebテクノロゞヌ、ボットネットなど、情報セキュリティの共通領域の䞡方のセキュリティず、プログラミングさえ必芁ずする非暙準のデバむスおよびテクノロゞヌハむパヌバむザヌ、スマヌトカヌドなどのセキュリティに関するものでした。 「むき出しの」鉄、特にArduino SDKコントロヌラヌ。 ク゚ストの勝者である、 NeoQUEST 2013の察面ツアヌの䞻な賞であったRSAカンファレンスからアムステルダムに戻ったばかりのAVictor は、それぞれのタスクに぀いお少し曞いおいたす 2䜍はv0s Vlad Roskov で、 Caterpillarから報酬で保護されたCat B15スマヌトフォンを受け取りたした。



画像



そしお今、ハむパヌバむザヌに぀いおです



v0のみがハむパヌバむザヌをバむパスできたした。 タスクは次のように定匏化されたしたKeyReader.exe実行可胜ファむルが存圚する2぀の同䞀のWindowsコンピュヌタヌが利甚可胜です。 入力時に、圌は参加者のIDを受け取り、 「キヌが正垞に読み取られたした。」ず衚瀺したす。 終了するには任意のキヌを抌しおください。 デフォルトでは、参加者は管理者暩限を持぀アカりントで䜜業したす。 キヌを受け取る必芁がありたす。







これら2぀以倖のマシンで起動するず、KeyReader.exeが゚ラヌを報告したす。







参加者の代わりに自分自身を想像し、真実に到達するようにしおください メッセヌゞから刀断するず、キヌはプロセスメモリにあり、そこから読み取る必芁がありたす。 簡単に聞こえたすが、やっおみおください。 Windowsタスクマネヌゞャヌを実行し、KeyReader.exeプロセスを芋぀けお、キヌストロヌクの埅機時にダンプし、ダンプをRussinovichの文字列にフィヌドしたす 。 ダンプの重量は3.3MBで、ナヌティリティは55,000行を怜出したす。 それらの䞭からキヌを怜玢する方法はあたり明らかではありたせんが、キヌずいう単語で怜玢するず、次の行が芋぀かりたす。







これは必芁なものではないようです。 正確に䜕が起こったのか、ダンプにこの行が含たれおいる理由はただ明らかではありたせんが、これは明らかにパスワヌドではありたせん。 KeyReader.exeがIDAを䜿甚しおどのように機胜するかを理解しおみたしょう。すでに䜕が起こっおいるかを十分に理解した䞊で、タスクを完了しおください。 プログラムは簡単に逆コンパむルでき、䞀般的にはその意味が明確になりたす。 基本的なロゞックは次のずおりです。







ペヌゞアラむンメモリが割り圓おられ、れロに蚭定された埌、参加者のIDが読み取られ、 AcquireKey関数が呌び出されたす。 AcquireKey関数は小さく、アセンブラヌ挿入であった次のコヌドが含たれおいたす。







コヌドには、vmcall呜什が含たれおいたす。この呜什は、レゞスタを介しお枡されるパラメヌタヌを䜿甚しおハむパヌバむザヌぞの呌び出しを実行したす。 EAXレゞスタには倀「NeoQ」が含たれ、EDXレゞスタには倀「strt」が含たれ、EBXレゞスタには以前に割り圓おられたメモリペヌゞぞのポむンタが含たれ、ECXレゞスタにはペヌゞサむズが含たれ、EDIレゞスタには参加者IDが含たれたす。 呌び出しの結果は、ESIレゞスタを通じお返されたす。 簡単にするために、ハむパヌバむザヌが存圚する堎合はvmcall呜什がハむパヌバむザヌに制埡を転送し、存圚しない堎合は#UDを呌び出すず想定できたす。



呜什の操䜜アルゎリズムの完党な説明は、Intelのドキュメント64-ia-32-architectures-software-developer-vol-2b-manualにありたす 。 これで、キヌがハむパヌバむザヌに保存され、特定のパラメヌタヌでvmcall呜什を䜿甚しおアクセスされたずきにプログラムメモリにコピヌされるこずが明らかになりたした。



プログラムのステップをデバッグしお、ハむパヌバむザヌにアクセスした埌のメモリ内の内容を確認しおみたしょう。 OllyDbg 2.01をデバッガヌずしお䜿甚したす。 デバッグ䞭にKeyReader.exeを実行し、vmcallの埌の次のステヌトメントにブレヌクポむントを蚭定したす。 参加者IDを入力しおEnterを抌し、確立されたブレヌクポむントに到達したす。 EBXレゞスタにはアドレス0x1F5000が含たれおいたすが、れロがありたす。 ESIも0です。







F9を抌しお、゚ラヌが発生したこずを確認したす。







3぀のデバッグメカニズムがありたす。

•コヌドツヌルキットint3呜什

•各呜什の埌に割り蟌みint1を䜿甚した段階的なデバッグ

•デバッグレゞスタD0〜D7。メモリアクセスをキャッチできたす。

この堎合、呜什にブレヌクポむントをむンストヌルするずきに、呜什の最初のバむトを0xccint 0x3で䞊曞きしたす。 プログラムがこの堎所に到達するず、int3が実行され、制埡がデバッガヌに枡され、擊り切れたバむトが埩元され、埩元された呜什が実行され、呜什の䞊に再びint3が曞き蟌たれたす。 したがっお、ブレヌクポむントは実行䞭のむメヌゞを倉曎し、ハむパヌバむザヌは明らかに、キヌをプログラムメモリにコピヌする前にその敎合性をチェックしたす。 ゚ラヌメッセヌゞもこれを瀺唆しおいたす。



この問題は、次の方法で簡単に解決できたす。 vmcallの前にいく぀かの呜什をブレヌクポむントにむンストヌルし、ブレヌクポむントに入った埌、それを削陀し、ステップごずにコヌドを実行したす。 Vmcallを実行するず、次の結果が埗られたす。







EBXレゞスタでは、アドレスは0x165000です。このアドレスには、既におなじみの文字列"keyNICE TRY、THIS IS NOT A KEY"がありたす。 ハむパヌバむザヌは、キヌが読み取られないようにしたす。



KeStackAttachProcess関数ずKeUnstackDetachProcess関数を䜿甚しおプロセスのメモリを読み取る小さなドラむバヌを䜜成できたすが、すぐにこれも機胜しないずしたしょう。 厄介なパスに進み、Windowsに関心のあるプロセスのメモリをディスクに匷制的にアンロヌドさせ、pagefile.sysを解析しお、キヌを持぀バッファヌに察応するペヌゞを芋぀けるこずができたす。 しかし、このペヌゞには同じ行が衚瀺されたす。



次の方法を詊しおみたしょう-dllをKeyReaderプロセスに挿入し、そこからキヌが眮かれおいるメモリを読み取りたす。 たず、プロセスを開始し、Olly Dbgを䜿甚しおプロセスにアタッチし、キヌを持぀バッファヌが配眮されおいるアドレスを確認したす。 バッファヌぞのポむンタヌは0x40eb3cにありたす。







この堎合、バッファのメモリは0x600000に割り圓おられ、デバッガずしお、アプリケヌションは匕き続き動䜜したす。 このアドレスのメモリを読み取り、a.txtファむルでディスクに保存するdllを䜜成したす。 コヌドは次のようになりたす。







むンゞェクタヌずしお、WindowsのC / C ++経由の䟋を䜿甚したした 。 dllを挿入し、次の行を含むa.txtファむルを取埗したす。







これが鍵です。



KeyReaderプロセスむメヌゞに入らないコヌドむンゞェクションの䞻題のバリ゚ヌションは解決策になりたす。 たずえば、デバッガヌの参加者の1人が、getch関数によっお呌び出されるkernel32.dllのReadConsoleInputA関数のコヌドを修正し、そこから既知のアドレスの行を読み取りたした。 ご芧のずおり、タスクは最も難しいものではありたせんが、最終的には1人だけがタスクを管理したした。 ほずんどの堎合、これは時間の䞍足によるものであり、タスク自䜓は、答えに぀ながる論理的な連鎖をほずんど意味しないようなものです。 参加者は、ある時点で䜜業バヌゞョンに぀たずくために、他の誰かのプロセスの蚘憶を読むために知っおいるすべおの方法を敎理しなければなりたせんでした。



䞀般に、このタスクを準備するこずは、おそらくそれを実行するこずよりもさらに興味深いでしょう:)。 ペヌゞぞのアクセスを制埡するには、仮想アドレスから物理アドレスぞのペヌゞに関連付けられおいるすべおの倉換テヌブルの倉曎を制埡する必芁がありたした。 さたざたなマッピングオプションず、アクセスを制埡する物理ペヌゞのアドレスを倉曎できるずいう事実を考えるず、これはそれほど簡単ではありたせん。



ハむパヌバむザヌは、あるケヌスではキヌぞのアクセスを蚱可し、別のケヌスではそうではありたせんか キヌでペヌゞにアクセスするずき、圌は3぀の条件をチェックしたした。

•読み取りはナヌザヌモヌドから行う必芁がありたす

•キヌにアクセスするプロセスむメヌゞのそのセクション.textのハッシュは厳密に定矩する必芁がありたす

•キヌは、vmcallがキヌを受信するために呌び出されたアドレス空間からのみ読み取るこずができたす。



最初の条件は、カヌネルからキヌを読み取るすべおの詊みを拒吊したした。 これらには、ReadProcessMemory関数ず独自のドラむバヌの䜜成が含たれたす。 2番目の条件では、むメヌゞコヌドの倉曎ずブレヌクポむントの蚭定が蚱可されたせんでした。 ずころで、テキストセクションのみがチェックされたため、異なる方法で呌び出されるコヌドを䜿甚しお独自のセクションを远加し、゚ントリポむントを倉曎できたす。 次に、コヌドからキヌを取埗する関数を呌び出しお、ディスクに保存したす。 3番目の条件では、KeyReaderプロセスのメモリがキヌを読み取るために蓄積された他のプロセスは蚱可されたせんでした。 このような状況を取埗するには、Windows7でそのような機胜を備えた既補のナヌティリティが芋぀からなかったため、このような状況を取埗するには、独自のドラむバヌずそれず通信するアプリケヌションを䜜成する必芁があるため、この条件はやや倧げさです。 Windows XPでは、物理メモリの読み取り時にWinHex RAM Editorは同様の方法で機胜したした。 条件の䞻な目暙は、既成のナヌティリティのみを䜿甚しお、1行のコヌドを蚘述するこずなくタスクを完了できないこずでした。



そしお結論ずしお...



ハむパヌバむザヌを䜿甚しおタスクを準備する際、参加者にタスクの異垞な性質に疑問を抱かせたいず思いたした。 結局のずころ、プロセスメモリから行を読み取る際の問題は䜕でしょうか そしお、1人の参加者だけがタスクを完了したずいう事実から刀断しお、成功したした Habrの読者にずっお興味深いこずを願っおいたす すぐに、最も「鉄」のタスクNeoQUEST-2013の詳现な分析を含む蚘事を期埅しおください



All Articles