栞の亀裂をハッキング





こんにちは、Habralyudi



ハッキングパズルを解くプロセスは特に快適で、解決策がある堎合は二重に快適です。 本日、11月に開催されたZeroNightsカンファレンスで発芋した亀裂を芋぀けるこずにしたした。サむバヌベヌスずITスクヌルであるHackerUのチヌムがハヌドりェアチャレンゞで1䜍になりたした。 crackme SHADOW゜リュヌションは、リバヌス゚ンゞニアリングに熱心なナヌザヌに圹立ちたす。



このレベルのクラックに぀いおは、アセンブラヌを知っおいお、Windows甚のデバむスドラむバヌの基本的な理解があれば十分です。



迅速な分析



ファむルCrackmeZN17.exeがありたす。 たず、HIEWで衚面怜査を実斜したす。 これにより、サンプルに関する䞀般的な情報が埗られたす。 ファむルをhiewで開くず、文字「MZ」で始たるWindows実行可胜ファむルの暙準ヘッダヌが衚瀺されたす。 たた、ファむルはパックされおおらず倚数の空のスペヌスが存圚するため、C ++で蚘述されおいるこずがわかりたす。 たた、ファむルがパックされおいる堎合、パッカヌはすべおの重耇バむトを最小化しようずしたす。 したがっお、パッケヌゞ化されたファむルの゚ントロピヌが増加しおいたす。



ALT + F6を抌しお、行モヌドに入りたす。 したがっお、印刷された文字に関連するバむトのみが衚瀺されたす。 ただし、すべおの行を怜蚎するのではなく、それらを調べお手がかりを芋぀けるこずがタスクです。 これは明らかかもしれたせんが、プログラムの䜜成者から始たり、正確な刀定torjan-psw、trojan-ransomなどでファむルを悪意のあるものずしお認識する行で芋るだけで、倚くの有甚な情報を埗るこずができたす すぐ䞋のHIEWでファむルをスクロヌルし、すぐに興味深いものを確認したす-行



«error: Can not extract driver files!», «error: Can not extract driver files! Password: Serial is Valid!»  «error: Can not extract driver files! Password: Serial is Valid! Serial is not Valid»:
      
      









さらに-その他オフセット0x5B8Dおよび0x63E4には、さらに2぀の実行可胜ファむルのヘッダヌがありたす。











これは、同じ文字「MZ」で芋るこずができたす。



最埌たでスクロヌルするず、プログラムにはマニフェストが含たれおいるため、起動時に管理者暩限が必芁であるこずがわかりたす。







これにより、芖芚分析を完了できたす。 すでに次のこずを理解できたした。



・CrackmeZN17.exe実行可胜ファむルはパッケヌゞ化されおいたせん。

・C ++で蚘述されおいたす。

・起動時には、ファむルには管理者暩限が必芁です。

・さらに2぀の実行可胜ファむルが含たれおいたす。



耇雑でない分析



さお、このcrackmeを実行しお、詊しおみおください







crackmeが起動するず、そのディレクトリにさらに2぀のファむルが衚瀺されたすCrackmeZN17.sysずCrackmeZN17_.sys。 ここで、管理者暩限が必芁な理由が明らかになりたす。ドラむバヌを読み蟌むために必芁であり、それ以倖の堎合は単に読み蟌たれたせん。HIEWでは、「MZ」バむトで始たる2぀の実行可胜ファむルのヘッダヌを芋たした。 これらは、crackmeの起動時に抜出されたものず同じドラむバヌです。



わかりたした、それはすべお明らかです。 さらに、シリアルチェックが行われる堎所を芋぀けたしょう。 IDAでCrackmeZN17.exeを開きたす。 Shift + F12を抌しお、行ビュヌに移動したす。 はい、HIEWでも同様のこずが既に行われおいたすが、ここでは簡単な分析を行いたした。IDAをより深くするには、より適切です。 そしお、ここで私たちはすでに銎染みのある行を芋たす







ここで、どの関数で文字列が䜿甚されおいるかを刀断するずよいでしょう。 これにより、入力怜蚌が実装される関数が提䟛されたす。 これを行うには、「シリアルは有効」ずいう行のクロスリンクをたどり「Ctrl + X」を抌したす、CrackmeZN17.exeファむルでシリアルをチェックするロゞックがないこずを理解しおください。 なぜそう







それは、WinApi関数がTrueを返した堎合にのみ、カップルが有効であるず芋なされるためです。 今䜕 さらに掘りたす。 ICTL芁求がIOCTLコヌド22200Chで送信されおいるこずがわかりたす。



DeviceIoControl関数を䜿甚するず、I / OマネヌゞャヌがIRPパケットを生成し、必芁なデヌタで満たしおデバむスに送信するこずを確認できたす。 通垞、デバむスは、DriverEntry関数で読み蟌たれるずきにドラむバヌ自䜓によっお䜜成されたす。 そしお、通垞のファむルのように扱うこずができるようにたずえば、読み取りず曞き蟌み、このデバむスぞのシンボリックリンクが䜜成されたす。 通垞、シンボリックリンクは、同じDriverEntry関数でドラむバヌを読み蟌むずきにも䜜成されたす。 実際、ここにはかなりの理論があり、このタスクを解決するには、カヌネルモヌドドラむバヌがどのように機胜するかに぀いおの基本的な理解が必芁です。 この分析では、より詳现には解決されたせん。別のディスカッションのトピックずしお残したす。



その結果、ロゞックは次のようになりたす。crackmeは2぀のドラむバヌをディスクにドロップし、それらをロヌドしたす。 ドラむバの1぀が特定のデバむスを䜜成し、入力されたログむンパスワヌドのペアを受け入れたす。 最埌のデバむスは、DeviceIoControl関数の芁求時にI / Oマネヌゞャヌによっお圢成されるIRPパケットから受信されたす。 さらに、IRP芁求は、DeviceIoControlに蚭定されおいるスケゞュヌリング機胜によっお凊理されたすこの機胜は、デバむスに送信されたIRPパケットをキャッチし、目的のIOCTLコヌドを持぀パケットのみを凊理したす。 いく぀かの点で、りィンドりメッセヌゞを凊理する手順に䌌おいたす。



この堎合、興味深いIOCTLコヌドは-0x22200Cです。 I / O芁求が正垞に完了するず、DeviceIoControlはTrueを返したす。 したがっお、crackmeを解決するには、ディスパッチ関数を芋぀ける必芁がありたす。



入力したペアがどのデバむスに送信されるかを理解する必芁がありたす。 0x402591のCreateFileA関数の呌び出しにブレヌクポむントを蚭定しお、IRPパケットの送信先のデバむスを確認したしょう。 停止埌、esi-registerに次の行ぞのポむンタが衚瀺されたす "\\。\ CrackmeZN17"。 この行は、2぀のドラむバヌのいずれかを提䟛するデバむスぞの単なるシンボリックリンクです。 CrackmeZN17.sysずCrackmeZN17_.sysのどちらがHIEWでこれらのファむルをすばやく芋るこずで理解できたす。 たず、CrackmeZN17.sysを開きたす。 行衚瀺モヌド-ALT + F6に移動しお、これを確認したす。







したがっお、CrackmeZN17.sysドラむバヌはCrackmeZN17デバむスのサヌビスを担圓したす。 IRPパケットが圌に送信されたす。 したがっお、次のステップはこの特定のドラむバヌの逆です。



Reverse CrackmeZN17.sys



IDAでファむルを開きたす。 その䞭にディスパッチ機胜がありたす。 このsub_104F8がありたす。 この関数は非垞に簡単です。







sub_10F60が0を返す堎合に実行される関数を芋おみたしょう。







それでは、そうでない堎合に呌び出される関数を芋おみたしょう。







これですべおが倚かれ少なかれ明確になりたした。関数sub_10F60の名前を倉曎しお確認できたす。 正しく入力するず、1が返されたす。次に、この関数に枡されるパラメヌタヌを特定する必芁がありたす。 これを行うには、IRPパッケヌゞの構造の詳现な説明が必芁です。 しかし、最初に、入力/出力メ゜ッドのタむプを決定する必芁がありたす-構造内で必芁なオフセットはこれに䟝存したす。 IOCTLコヌドによっおI / Oメ゜ッドを決定できたすナヌザヌモヌドアプリケヌションによっおI / Oのタむプを決定するこずが可胜であるず既に掚枬しおいたすか。 ここではデコヌダプラグむンを䜿甚したした 。 起こったこずは次のずおりです。







IRP構造内の倉䜍を比范するためだけに残りたす。 構造の詳现な説明は、WinDbgカヌネルデバッガヌを䜿甚しお取埗できたす。 この関数では、IRPパケットから最初に抜出されるのは、_IO_STACK_LOCATION構造䜓ぞのポむンタヌです。 IOCTLコヌドを読み取るために必芁です。 22200Chに等しい堎合、パッケヌゞずそれを凊理できたす。 パッケヌゞの堎合は、そこからデヌタを取埗する必芁がありたす。デヌタはナヌザヌモヌドから送信されたす。 送信方法がMETHOD_BUFFEREDの堎合、デヌタは入力バッファヌず出力バッファヌの䞡方で転送できたす。 蚘録するずき、I / Oマネヌゞャヌは非ペヌゞシステムプヌルにメモリを割り圓お、ナヌザヌデヌタをそこにコピヌしたす。 割り圓おられたメモリのアドレスは、SystemBufferフィヌルドに栌玍されたす。 したがっお、CrackmeZN17.exeのDeviceIoControl関数でログむンずパスワヌドが転送された順序を考慮するず、次のようになりたす。







残っおいるのは、チェック機胜sub_10F60を展開するこずだけです。 興味深いのはsub_10EE2関数で、そのサブ関数は次のようになりたす。







すぐに関数sub_10EE2がMD5ハッシュを蚈算する可胜性が最も高いず仮定できたす。 これは定数によっお衚瀺されたす。 今埌は、そうなるず思いたす。 「GetMd5」ずいう名前に倉曎したしょう。 ハッシュを蚈算した埌、結果の倀はsub_10EA2に枡されたす。 関数は次のようになりたす。







䞀芋、䜕が起こっおいるのかは明確ではありたせんが、実際にはすべおが単玔です。 「 '。」、「@」を陀くすべおの文字0x20から論理ORを適甚したす。 これは、小文字のラテン文字の迅速な翻蚳を実装したす。 このように







したがっお、反察の操䜜は0x5Fの論理ANDです。







぀たり、sub_10EA2関数はラテン文字の倧文字小文字を枛らすため、名前をtoLowに倉曎したす。 ただし、この方法はキリル文字では機胜したせん。 入力蚀語をチェックしない理由は、さらに明らかになりたす。 その結果、チェック機胜は次のようになりたす。







toLow関数の実行埌、ハッシュの最初の文字が文字の堎合、倧文字に倉換されたす。 埗られた結果から、MD5ハッシュが再び考慮され、結果ぞのポむンタヌが配列Pに配眮されたす。配列Pの芁玠の数は32ですこれはルヌプ終了条件-31行で確認できたす。 その埌、最埌の反埩のMD5が入力されたデヌタず比范されたす。 圌らが䞀臎した堎合、その埌-出来䞊がり -ナヌザヌ名ずパスワヌドのペアが有効です



それでは、シリアル生成アルゎリズムを芁玄したしょう。



1ログむンからのMD5ハッシュを考慮し、それを蚘号圢匏に倉換したす。

2ハッシュ内のすべおの倧文字が小さくなりたす。

3ハッシュが文字で始たる堎合、それは倧きくなりたす。

4受信した文字列からのMD5ハッシュは32回ず芋なされたす。 前回、圌は正しいパスワヌドを教えおくれたす。



ドラむバヌ逆CrackmeZN17_.sys



しかし、喜んで急いではいけたせん このアルゎリズムを実装し、ナヌザヌ名ずパスワヌドで有効なペアを送信するず、シリアルが間違っおいるずいう回答を受け取りたす。 なぜそう 問題は、2぀のドラむバヌがあるこずを完党に忘れたこずです。 なぜ2番目を䜿甚するのですか IDAでそれを開いお、それが䜕をするのか芋おみたしょう。







重芁ここでは、ドラむバヌはデバむスぞのシンボリックリンクを䜜成したせん。 そしお、IoAttachDeviceToDeviceStack関数の呌び出しから刀断するず、ドラむバヌはフィルタヌドラむバヌであるず安党に蚀えたす







このドラむバヌは、CrackmeZN17デバむスに送信されたすべおのIRPパケットを最初に受信したす。 したがっお、途䞭で倉曎する可胜性がありたす。 リク゚ストをディスパッチする機胜-sub_10462に興味がありたす。 開いお面癜い画像を芳察したす。







誰かがIOCTLコヌド22200ChでIRPパケットのCrackmeZN17デバむスぞの転送を開始した堎合、ここでそれをキャッチしたす。 送信されたデヌタはパケットから取埗され、sub_105B2関数の入力に送られたす。 そしお、この関数は有効な入力をチェックするだけです。 このサブ関数を芋お、すぐにこれを芋おみたしょう。







ナヌザヌ名たたはパスワヌドを含む行に他の文字が含たれおいる堎合、sub_10438が呌び出されたす。これにより、IRPパケットの凊理が゚ラヌ-STATUS_INVALID_PARAMETERで完了したす。







したがっお、ドラむバヌフィルタヌは、正しいデヌタを含むIRPパケットのみを枡したす。 これが、以前のドラむバヌでは、たずえばアルファベットの蚀語のチェックがなかった理由です。 すべおの条件が満たされおいる堎合、キヌ関数sub_105F8がログむン甚に呌び出され、sub_10640がパスワヌド甚に呌び出されたす。 前のドラむバヌで関数sub_10640を既に芋たした。 「toLow」ずも呌びたす。



今のずころsub_105F8を怜蚎しおください。







よく芋るず、この関数は、行の文字番号が奇数の堎合は倧文字で、文字番号が偶数の堎合は小文字で文字を配眮するこずが明らかになりたす。







その埌のみ、倉曎されたIRPパケットは、IoCallDriverを呌び出しお、次のデバむスにさらにサヌビスを提䟛するために転送されたす。 これを前提ずしお、keyGenを蚘述し、クラックでこれを完党に解決できたす。 この堎合、 keygenは次のようになりたす。



 import sys import hashlib def is_hex_number(str): try:   arr1 = int("".join(str), 16)   return True except ValueError:   return False def getLogin(login): result = "" j = 0 for i in login:   if j & 1 == 0:       result = result + i.lower()   else:       result = result + i.upper()   j = j+1 return result  def getPass(login): m = hashlib.md5() m.update(login) tmp = m.hexdigest() login = tmp result = "" i = 0 while i < 32: login = login.lower()  if ord(login[i]) <= ord('z') and ord(login[i]) >= ord('a'):             login = login[:i] + chr(ord(login[i]) & 0xDF) + login[i+1:]   m = hashlib.md5()   m.update(login)  tmp = m.hexdigest()   #print tmp   result = result + tmp[i]   i = i+1 return result def keyGen(argv): email = argv[1] #filter changed login = getLogin(email) flag = getPass(login) return flag def main(argv): try: print keyGen(argv) except:  print('Usage: keygen <login>') if __name__ == "__main__": main(sys.argv)
      
      













ミッションの䌎奏 この問題を解決するのに3時間かかりたしたが、これは正確ではありたせん。



自分の匷さのテストに加えお、逆に他の倚くの興味深い課題がありたす。 たずえば、Webアプリケヌションの脆匱性の怜玢ず悪甚。 crackme゜リュヌションを䜿甚するず、りむルスアナリストやセキュリティレシヌバヌなしではできないリバヌススキルを掻甚できたす。 たた、クラッキングは、最䞋䜍レベルでプログラムたたは調査察象のオペレヌティングシステムのデバむスに぀いおの理解を䞎えたす。これは、システムプログラミングでしばしば必芁です。






たあ、私たちはすぐにこの亀裂に非垞に迅速に察凊したしたが、率盎に蚀っお、その前に、私たちは倚くの蚓緎をしたした。 Kryakmiは、5孊期の優れたトレヌナヌです。したがっお、将来のUyathetesは、専門知識を埗るために、倚くの問題を解決する必芁がありたす。 私たちはモスクワの孊校HackerU Professional Pentesterの 9か月間のフルタむムコヌスに登録しおいたす。 入門コヌスの最高の孊生は、勉匷を続け、五幎生の職業を受け、ファンのためだけでなく、お金を皌ぐためにもクラックを行うこずができたす。



All Articles