[BUUCTF]リバース-[GWCTF2019] re3

[GWCTF 2019] re3

別館

ステップ

  1. 64ビットプログラム、シェルなし、idaで直接開く、まず最初にプログラム内の文字列を取得する
    ここに画像の説明を挿入します
  2. フラグに関連する関数を見つけるための正しいジャンプによると、以下にABCが表示されます...... * /、プログラムにbase64暗号化があると推測します
    ここに画像の説明を挿入します
  3. ここにはf5はありません。jzポットがidaの通常の動作に影響を与えたと推定されます。上記のメイン関数
    main()を見てみましょう
    ここに画像の説明を挿入します
    入力文字列の長さは32ビットです。mprotect関数を使用して0xF000を変更します。 dword_400000の長さアドレスから読み取り可能、書き込み可能、​​実行可能、sub_402219()のデータはXORされています。
  4. sub_402219()関数は、データとしてXORに参加するだけでなく、関数として参照されているため、この関数を開くことができません。XOR
    を推測すると、この関数が実際の関数になります。したがって、最初にsub_402219()でデータを復元
    し、疑似コード部分でsub_402219直接クリックして、そのデータセグメントにジャンプします。アセンブリコードでデータを
    ここに画像の説明を挿入します
    見つけDキーを押してデータ型に変換してから
    ここに画像の説明を挿入します
    、idcスクリプトを使用する必要があります。データを復元するには、最初にidcスクリプトを使用し、
    最初にshif + f2を記録してスクリプトエディタを呼び出してから、idcスクリプトを編集できます。構文はcに少し似ています。具体的な構文については、この記事参照してください。この記事で
    ここに画像の説明を挿入します
    は、書き込み方法について簡単に説明します。最初に、修復するデータの開始位置であるローカル変数addrを定義します。これは、トラバースに使用され、後続のforループはmain関数をコピーし、最後はPatchByte(addr+i,Byte(addr+i)^0x99)この文章。
    PatchByteの構文を最初に見てください。この文は、addrから始まり、iを使用してアドレスをトラバースし、対応するアドレスの値をbyte_402219 [addr + i] = byte_402219 [addr + i] ^ 0x99に設定
    ここに画像の説明を挿入します
    します。実行をクリックして復元します。データ
    ここに画像の説明を挿入します
    を復元し、復元後にデータを選択します。cを押し、forceを選択して強制的に実行し、データをコードに変換します。
    ここに画像の説明を挿入します
    次に、pを押して、コードの先頭の0x402219に関数を作成します。
    ここに画像の説明を挿入します
    ここで戻ってメイン関数
    ここに画像の説明を挿入します
    sub_402219( )。この機能を開くことができます。19行目のジャンプアウトはBaiduです。説明のためにてください

関数境界認識エラー、または
何らかの理由により、コンパイラーは連続領域に格納されていない一部のコードを分離しますが、他の場所では、これらのブロックはチャンクと呼ばれるidaによって認識されることがあり、一部は認識できません。この時点で、手動で設定する必要があります。
境界認識エラーの場合は、alt + pで正しい終了を見つけます。
後者の場合は、append_func_tailを使用してこの関数にターゲット領域を追加します。さらに、最初にターゲット領域の定義を解除する必要があります。

私はこの質問のwpのためにBaiduに行きました、そしてそれがそれに影響を与えなかったのを見つけたので、私はそれを投げ続けませんでした。

  1. main()を引き続き確認し、sub_40207B()
    sub_40207B()を呼び出します。そのパラメーターunk_603170()はidaで直接表示できません。次に移動して、
    sub_40207B()がsub_401CF9関数を呼び出すかどうかを確認します。長すぎます。関数の
    ここに画像の説明を挿入します
    機能コードによるとこれはmd5暗号化n1bookのp273アルゴリズムの機能コードであることがわかります。
    ここに画像の説明を挿入します
    ここに画像の説明を挿入します
    この関数は主にbase64テーブルでmd5暗号化を2回実行します。

  2. 次に、sub_402219()
    ここに画像の説明を挿入します
    sub_400A71()があります。
    ここに画像の説明を挿入します最初に、全体で4回ループします。データを処理するときに、byte_4023A0が使用されます。
    ここに画像の説明を挿入します
    上記のn1bookの図によると、これはAES暗号化されたsであることがわかります。この関数の機能はunk_603170(base64表进行了两次md5加密后的结果)、キー
    sub_40196E()が同じ機能コードを持っているため着信です。これはAES暗号化のステップである必要があります。したがって、その機能はunk_603170(上一层传入的base64表进行了两次md5加密后的结果)、データに対してAES暗号化を実行するためのキーとしてキーを使用することです。
    9〜11行の処理後に入力して取得しますbyte_6030a0でデータを取得し、byte_6030a0でデータを抽出します
    ここに画像の説明を挿入します
    byte_6030a0 = BC0AADC0147C5ECCE0B140BC9C51D52B46B2B9434DE5324BAD7FB4B39CDB4B5B

  3. この時点で、プログラムのロジックが明確になります。
    最初に、base64テーブルがmd5で2回暗号化された結果がunk_603170
    unk_603170に渡され、入力したデータがAES暗号化されてbyte_6030a0unk_603170が取得されます
    。調整またはオンラインmd5が可能です。暗号化プラットフォーム。入手するか、独自のmd5暗号化スクリプトを作成して実行します。

  4. unk_603170の値を調整します(主に、ツールのWebサイトを2回使用した後に正しいキーを取得できず、md5暗号化を2回使用し、自分で作成したpythonがエンコード変換の間にスタックしている
    ためこれはelfファイルであるため、使用する必要があります仮想モバイル調整、IDAを使用したELFファイルの調整方法(仮想マシンを使用)については、この記事を詳しくお読みください
    物理マシンと仮想マシンが相互にpingを実行できることが前提です。pingが失敗した場合は、リセットしてください。仮想マシンネットワークカード。
    長い間調整した後、私はついにそれを理解しました。これunk_603170=CB8D493521B47A4CC1AE7E62229266CE
    ここに画像の説明を挿入します
    は、この質問をデバッグする際の落とし穴の記録です。
    ここに画像の説明を挿入します
    まず、プログラムが入力文字列である限り、このexit(0)をバイパスできることがわかります。長さは32ですが、実際の操作では機能しません。バイパスする方法は、ifを実行して次のブレークポイントを判断し、次のブレークポイントを
    ここに画像の説明を挿入します
    設定してからunk_603170への割り当てを実行し、f9を最初のブレークポイントまで実行することです。、次にctrl + f7をクリックして、2番目のブレークまで実行します。クリックしてから、シングルステップf8からunk_603170に移動して割り当てを完了し、unk_603170に移動します。

  5. 最後に、unk_603170を使用してbyte_6030a0を復号化します。オンラインツールは復号化に失敗し、他のマスターpython2のexpを投稿し、python3でコード化された変換がスタックします。

from Crypto.Cipher import AES
import codecs

aes = AES.new(decode_hex('CB8D493521B47A4CC1AE7E62229266CE')[0], AES.MODE_ECB)
print(aes.decrypt(decode_hex('BC0AADC0147C5ECCE0B140BC9C51D52B46B2B9434DE5324BAD7FB4B39CDB4B5B')[0])) 

フラグ{924a9ab2163d390410d0a1f670}

経験のソース:https//www.cnblogs.com/Mayfly-nymph/p/12829168.html

おすすめ

転載: blog.csdn.net/mcmuyanga/article/details/114360856