ギドラで簡単な「割れ目」を砎る-パヌト1

おそらく倚くの人が、これがどんな獣なのかを盎接知っおいるでしょう- ギドラ  "Hydra"ず、それがプログラムを実際に食べるものは、このツヌルは最近公開されたばかりですが、今幎3月に。 Hydraやその機胜などの説明で読者を悩たせるこずはありたせん。 トピックに参加しおいる人は、すでにこのすべおを研究しおいるず確信しおいたす。トピックにただ参加しおいない人は、い぀でもむンタヌネットで詳现な情報を簡単に芋぀けるこずができるため、い぀でも実行できたす。 ちなみに、Hydraプラグむンの開発の偎面の1぀は既にHabré優れた蚘事で取り䞊げられおいたす。䞻なリンクのみを提䟛したす。





そのため、Hydraは、 モゞュヌル構造を備えた無料のクロスプラットフォヌムのむンタラクティブな逆アセンブラヌおよび逆コンパむラヌであり、ほがすべおのメむンCPUアヌキテクチャをサポヌトし、逆アセンブルされたコヌド、メモリヌ、埩元された逆コンパむルされたコヌド、デバッグシンボルなどを操䜜するための柔軟なグラフィカルむンタヌフェむスを備えおいたす 。



このHydraで䜕かを壊そう



ステップ1.亀裂を芋぀けお調べる



「犠牲者」ずしお、単玔なクラックミヌプログラムを芋぀けたす。 䞋のスクリヌンショットのように、私はcrackmes.oneに行き、怜玢で難易床= 2-3「単玔」および「䞭」、プログラムの゜ヌス蚀語=「C / C ++」およびプラットフォヌム=「マルチプラットフォヌム」を瀺したした。







怜玢は2぀の結果を返したした䞋の緑色。 最初のクラックは16ビットであるこずが刀明し、Win10 64ビットでは開始したせんでしたが、2番目 level_2 by seveb が発生したした。 このリンクからダりンロヌドできたす。



クラックをダりンロヌドしお解凍したす。 サむトに瀺されおいるように、アヌカむブのパスワヌドはcrackmes.deです。 アヌカむブには、LinuxずWindowsに察応する2぀のディレクトリがありたす。 私のマシンでは、Windowsディレクトリに移動し、その䞭で唯䞀の「実行可胜ファむル」であるlevel_2.exeに䌚いたす。 実行しお、圌女が望むものを芋おみたしょう。







残念なようです プログラムを起動するず、䜕も衚瀺されたせん。 パラメヌタずしお任意の文字列を枡しお、再床実行しようずしたす突然、キヌを埅っおいたすか-そしお再び䜕も...しかし、絶望しないでください。 たた、タスクずしお起動パラメヌタヌを芋぀ける必芁があるず仮定したしょう 「スむスナむフ」であるHydraを芋぀けたしょう。



ステップ2. Hydraでのプロゞェクトの䜜成ず予備分析



すでにHydraがむンストヌルされおいるずしたす。 ただではない堎合、すべおが簡単です。



Ghidraをむンストヌルする
1 JDKバヌゞョン11以䞊をむンストヌルしたす 12を持っおいたす



2Hydraをダりンロヌドしたずえば、 こちらから 、むンストヌルしたす執筆時点で、Hydraの最新バヌゞョンは9.0.2で、9.0.1がありたす



Hydraを起動し、開いたプロゞェクトマネヌゞャヌですぐに新しいプロゞェクトを䜜成したす。 crackme3ずいう名前を付けたした ぀たり、crackmeおよびcrackme2プロゞェクトはすでに䜜成されおいたす。 実際、プロゞェクトはファむルディレクトリであり、任意のファむルを远加しお孊習するこずができたすexe、dllなど。 level_2.exeをすぐに远加したす [ファむル] | [むンポヌト]たたはIキヌのみ







Hydraは、むンポヌトする前に、Win32 OSおよびx86プラットフォヌム甚の32ビットPEポヌタブル実行可胜ファむルずしお、実隓的なクワックを特定したこずがわかりたす。 むンポヌト埌、さらに情報を埅っおいたす







ここでは、前述のビット深床に加えお、 ゚ンディアンネスの順序に興味があるかもしれたせん。これは、Intel 86thプラットフォヌムで想定されおいたLittle 䜎バむトから高バむトたでです。



予備的な分析で、これで完了です。



ステップ3.自動分析を実行する



Hydraでプログラムの完党自動分析を開始する時間。 これは、察応するファむルlevel_2.exeをダブルクリックしお行いたす。 モゞュヌル構造のHydraは、すべおの基本機胜にプラグむンシステムを提䟛したす。プラグむンシステムは、远加/無効化、たたは独立しお開発できたす。 分析に぀いおも同様です-各プラグむンは、分析のタむプを担圓したす。 そのため、最初に目的の分析のタむプを遞択できるりィンドりが衚瀺されたす。



分析蚭定りィンドり






ここでは、デフォルト蚭定のたたにしお分析を実行するのが理にかなっおいたす。 分析自䜓は非垞に高速です玄7秒かかりたしたが、フォヌラムのナヌザヌは、倧芏暡プロゞェクトではHydraの速床がIDA Proに負けおいるず蚎えおいたす。 これは本圓かもしれたせんが、小さなファむルの堎合、この違いは重芁ではありたせん。



これで分析は完了です。 その結果は、コヌドブラりザりィンドりに衚瀺されたす。







このりィンドりはHydraで䜜業するための䞻芁なりィンドりです。したがっお、より慎重に怜蚎する必芁がありたす。



コヌドブラりザヌむンタヌフェむスの抂芁
デフォルトのむンタヌフェヌス蚭定は、りィンドりを3぀の郚分に分割したす。



䞭倮郚にはメむンりィンドりがありたす。これは、IDA、OlyDbgなどの「兄匟」にほが類䌌した逆アセンブラのリストです。 デフォルトでは、このリストの列は巊から右ぞメモリアドレス、コマンドのオペコヌド、ASMコマンド、ASMコマンドのパラメヌタヌ、盞互参照該圓する堎合です。 圓然、このりィンドりのツヌルバヌにあるレンガの壁の圢のボタンをクリックしお、衚瀺を倉曎できたす。 正盎に蚀うず、逆アセンブラ出力の同様の柔軟な蚭定を芋たこずはありたせん。これは非垞に䟿利です。



3パネルの巊偎郚分 



  1. プログラムのセクションマりスをクリックしおセクションを移動したす
  2. 文字ツリヌむンポヌト、゚クスポヌト、関数、ヘッダヌなど
  3. 䜿甚される倉数のタむプツリヌ


私たちにずっお最も䟿利なりィンドりはシンボルツリヌです。これにより、たずえば名前で関数をすばやく芋぀けお、察応するアドレスに移動できたす。



右偎には、逆コンパむルされたコヌドのリストがありたすこの䟋ではC。



デフォルトのりィンドりに加えお、[ りィンドり ]メニュヌでは、他の倚数のりィンドりずディスプレむを䜿甚しお、ブラりザ内の任意の堎所を遞択しお配眮できたす。 䟿宜䞊、BytesりィンドりずFunction Graphのあるりィンドりを䞭倮に远加し、右偎に文字列倉数Stringsず関数のテヌブルFunctionsを远加したした。 これらのりィンドりは、個別のタブで䜿甚できるようになりたした。 たた、任意のりィンドりを取り倖しお「フロヌティング」にし、自由に配眮しおサむズを倉曎するこずができたす-これも非垞に思慮深い解決策です。



ステップ4.プログラムアルゎリズムの孊習-main関数



さお、クラックプログラムの盎接分析に進みたしょう。 ほずんどの堎合、プログラムの゚ントリポむントを怜玢するこずから始めたす。 起動時に呌び出されるメむン関数。 クラックがC / C ++で蚘述されおいるこずを知っおいるず、main関数の名前はmainたたはそのようなものになるず掚枬されたす:) ツリヌのシンボル巊パネルのフィルタヌに「main」ず入力し、「 関数」セクションの関数_mainを確認したす。 マりスをクリックしおそこに移動したす。



main関数ずあいたいな関数の名前の倉曎の抂芁



逆アセンブラのリストでは、察応するコヌドセクションがすぐに衚瀺され、右偎にこの関数の逆コンパむルされたCコヌドが衚瀺されたす。 Hydraのもう1぀の䟿利な機胜は、遞択の同期です。マりスがASMコマンドの範囲を遞択するず、逆コンパむラヌの察応するコヌドセクションが匷調衚瀺され、逆も同様です。 さらに、メモリ衚瀺りィンドりが開いおいる堎合、割り圓おはメモリず同期されたす。 圌らが蚀うように、すべおの独創的なこずは簡単です



すぐに、たずえば、IDAでの䜜業ずは察照的にHydraでの䜜業の重芁な特城に泚目したす。 Hydraでの䜜業の䞻な目的は、逆コンパむルされたコヌドの分析です 。 このため、Hydraの䜜成者芚えおいる-私たちはNSAからのスパむに぀いお話しおいる:)は、逆コンパむルの品質ずコヌドを䜿甚するこずの利䟿性に倚倧な泚意を払いたした。 特に、コヌドをダブルクリックするだけで、関数、倉数、メモリのセクションの定矩に進むこずができたす。 たた、デフォルトの名前には意味がなく、混乱を招く可胜性があるため、倉数ず関数はすぐに名前を倉曎できたす。これは非垞に䟿利です。 埌で芋るように、このメカニズムをよく䜿甚したす。



したがっお、ここにメむン関数がありたす。これは、次のようにHydraが「分析」したす。



メむンのリスト
int __cdecl _main(int _Argc,char **_Argv,char **_Env) { bool bVar1; int iVar2; char *_Dest; size_t sVar3; FILE *_File; char **ppcVar4; int local_18; ___main(); if (_Argc == 3) { bVar1 = false; _Dest = (char *)_text(0x100,1); local_18 = 0; while (local_18 < 3) { if (bVar1) { _text(_Dest,0,0x100); _text(_Dest,_Argv[local_18],0x100); break; } sVar3 = _text(_Argv[local_18]); if (((sVar3 == 2) && (((int)*_Argv[local_18] & 0x7fffffffU) == 0x2d)) && (((int)_Argv[local_18][1] & 0x7fffffffU) == 0x66)) { bVar1 = true; } local_18 = local_18 + 1; } if ((bVar1) && (*_Dest != 0)) { _File = _text(_Dest,"rb"); if (_File == (FILE *)0x0) { _text("Failed to open file"); return 1; } ppcVar4 = _construct_key(_File); if (ppcVar4 == (char **)0x0) { _text("Nope."); _free_key((void **)0x0); } else { _text("%s%s%s%s\n",*ppcVar4 + 0x10d,*ppcVar4 + 0x219,*ppcVar4 + 0x325,*ppcVar4 + 0x431); _free_key(ppcVar4); } _text(_File); } _text(_Dest); iVar2 = 0; } else { iVar2 = 1; } return iVar2; }
      
      







倉数の定矩、暙準のCタむプ、条件、ルヌプ、関数呌び出しなど、すべおが正垞に思えたす。 しかし、コヌドを詳しく芋るず、䜕らかの理由で䞀郚の関数の名前が定矩されおおらず、疑䌌関数_text 逆コンパむラりィンドり-.textに眮き換えられおいるこずがわかり たす 。 これらの関数が䜕であるかを定矩するこずから始めたしょう。



最初の呌び出しの本文をダブルクリック



  _Dest = (char *)_text(0x100,1);
      
      





これは、デヌタ甚のメモリを割り圓おるために䜿甚される暙準calloc関数の単なるラッパヌ関数であるこずがわかりたす。 したがっお、この関数の名前をcalloc2に倉曎しおみたしょう。 機胜ヘッダヌにカヌ゜ルを蚭定し、コンテキストメニュヌを呌び出しお、[ 名前の倉曎 ] 機胜 ホットキヌ-L を遞択し、開いたフィヌルドに新しい名前を入力したす。







関数の名前がす​​ぐに倉曎されたこずがわかりたす。 メむン本文ツヌルバヌの[ 戻る ]ボタンたたはAlt + <- に戻りたす。ここでは、神秘的な_textcalloc2の代わりに、すでに立っおいるこずがわかりたす。 いいね



他のすべおのラッパヌ関数に぀いおも同じこずを行いたす。定矩を1぀ず぀確認し、それらの機胜を確認し、名前を倉曎しC関数の暙準名にむンデックス2を远加、メむン関数に戻りたす。



メむン関数コヌドを理解したす



さお、奇劙な機胜を芋぀けたした。 メむン関数のコヌドの調査を開始したす。 倉数宣蚀をスキップするず、文字列で指定された条件が満たされた堎合にのみ、関数が倉数iVar2の倀を返すこずがわかりたす。これはれロ関数の成功の兆候です。



 if (_Argc == 3) { ... }
      
      





_Argcは、 mainに枡されるコマンドラむンパラメヌタヌ匕数の数です。 ぀たり、プログラムは2぀の匕数を「食べ」たす最初の匕数は、垞に実行可胜ファむルぞのパスです。



では、先に進みたしょう。 ここでは、256文字のC文字列 char配列を䜜成したす。



 char *_Dest; _Dest = (char *)calloc2(0x100,1); //  new char[256]  C++
      
      





次に、3回の繰り返しのルヌプがありたす。 その䞭で、最初にbVar1フラグが蚭定されおいるかどうかを確認し、 蚭定されおいる堎合は、次のコマンドラむン匕数文字列を_Destにコピヌしたす。



 while (i < 3) { /*    .  */ if (bVar1) { /*   */ memset2(_Dest,0,0x100); /*    _Dest    */ strncpy2(_Dest,_Argv[i],0x100); break; } ... }
      
      





このフラグは、次の匕数を解析するずきに蚭定されたす。



 n_strlen = strlen2(_Argv[i]); if (((n_strlen == 2) && (((int)*_Argv[i] & 0x7fffffffU) == 0x2d)) && (((int)_Argv[i][1] & 0x7fffffffU) == 0x66)) { bVar1 = true; }
      
      





最初の行は、この匕数の長さを蚈算したす。 さらに、条件は、匕数の長さが2、最埌から2番目の文字== "-"、最埌の文字== "f"でなければならないこずをチェックしたす。 デコンパむラが、バむトマスクを䜿甚しお文字列から文字を抜出する方法を「翻蚳」しおいるこずに泚目しおください。

数倀の10進倀ず察応するASCII文字は、察応する16進リテラルの䞊にカヌ゜ルを眮くず衚瀺できたす。 ASCIIマッピングは垞に機胜するずは限りたせん。そのため、むンタヌネット䞊のASCIIテヌブルを確認するこずをお勧めしたす。 たた、コンテキストメニュヌ-> 倉換を䜿甚しお スカラヌを任意の番号システムから他のシステムに盎接倉換するこずもできたす。この堎合、この番号は遞択した番号システムのすべおの堎所逆アセンブラヌおよび逆コンパむラヌに衚瀺されたす。 しかし、個人的には、仕事の調和のためにコヌドにヘックスを残すこずを奜みたす。 メモリアドレス、オフセットなど ヘクスはどこにでも蚭定されたす。

ルヌプの埌にこのコヌドがありたす



 if ((bVar1) && (*_Dest != 0)) { /*    1) "-f"  2)  -         */ _File = fopen2(_Dest,"rb"); if (_File == (FILE *)0x0) { /*  1    */ perror2("Failed to open file"); return 1; } ... }
      
      





ここですぐにコメントを远加したした。 匕数 "-f path_to_file"の有効性を確認し、察応するファむルを開きたす2番目の匕数が枡され、_Destにコピヌしたした。 ファむルは、 fopen関数の「rb」パラメヌタヌで瀺されるように、バむナリ圢匏で読み取られたす。 読み取りが倱敗した堎合たずえば、ファむルが䜿甚できない堎合、゚ラヌメッセヌゞがstderrorストリヌムに出力され、プログラムはコヌド1で終了したす。



次は最も興味深いです



  /* !!!     !!! */ ppcVar3 = _construct_key(_File); if (ppcVar3 == (char **)0x0) { /*    ,  "Nope" */ puts2("Nope."); _free_key((void **)0x0); } else { /*    -      */ printf2("%s%s%s%s\n",*ppcVar3 + 0x10d,*ppcVar3 + 0x219,*ppcVar3 + 0x325,*ppcVar3 + 0x431); _free_key(ppcVar3); } fclose2(_File);
      
      





開いおいるファむル蚘述子 _File は_construct_key関数に枡され、明らかに、求められおいるキヌの怜蚌を実行したす。 この関数は、 ppcVar3倉数に栌玍されおいる2次元のバむト配列 char ** を返したす。 配列が空の堎合、簡朔な「Nope」がコン゜ヌルに衚瀺されたす぀たり、「Nope」、メモリは解攟されたす。 それ以倖の堎合配列が空でない堎合、明らかに正しいキヌが衚瀺され、メモリも解攟されたす。 関数の最埌で、ファむル蚘述子が閉じられ、メモリが解攟され、倀iVar2が返されたす。



だから、今、私たちは次のものが必芁であるこずに気付きたした



1正しいキヌでバむナリファむルを䜜成したす。

2匕数「-f」の埌にクラックのパスを枡す



蚘事の第2郚では 、関数_construct_keyを分析したす。これは、刀明したように、ファむル内のキヌをチェックする圹割を果たしたす。



All Articles