re學習筆記(65)BUUCTF - re - [GKCTF2020]Chellys identity

新手一枚,如有錯誤(不足)請指正,謝謝!!

題目鏈接:[GKCTF2020]Chelly’s identity

最近忙着看書,刷題斷了好久了,,,

IDA載入,shift+F12搜索字符串
在這裏插入圖片描述
雙擊跟到函數去,來到關鍵函數
在這裏插入圖片描述
我這裏的IDA修改了一下基址,因爲我配合OD動態調試做的,爲了讓函數地址與OD地址一致。
與我函數名不一樣的,需要改IDA基址
先查看OD基址
在這裏插入圖片描述
然後修改IDA的
在這裏插入圖片描述
修改成OD基址0xCB0000,然後點擊【OK】
在這裏插入圖片描述
從OD中找到主函數的地址部分(搜索IDA顯示的地址或者搜索字符串
在這裏插入圖片描述
cin是C++的輸入
在這裏插入圖片描述
在這裏插入圖片描述
然後F8單步一下,程序恢復運行,隨便輸入點字符串
在這裏插入圖片描述
可以看到內存窗口已經有了輸入
在這裏插入圖片描述
下一個內存訪問斷點,看看什麼時候訪問輸入,然後F9運行等斷點斷下
在這裏插入圖片描述
程序被斷下,選中的部分就是循環
在這裏插入圖片描述
回IDA找地址,發現是這裏的循環
在這裏插入圖片描述
此時的代碼,把eax,也就是輸入字符串的,第一個byte位,也就是第一個字符的地址給了ecx。
在這裏插入圖片描述
之後ecx又給了棧上的一個內存,也就是前面IDA for循環圖的v16
之後把這個值v16壓入棧(push edx)然後進入了1502函數
在這裏插入圖片描述
執行完一個循環,發現1771函數是獲取輸入的長度(多次調試變換輸入發現

而11D6函數是獲取複製後字符串的長度
在這裏插入圖片描述
複製的字符串存在哪呢,去看IDA
在這裏插入圖片描述
由於函數點進去再出來它的變量名就變了,,註釋部分沒有改,v32就是原來的v16
複製後的字符串應該存到了v34,去看v34的定義在ebp+0x48處,去OD找這個地址(不知道爲啥計算出來是D98,是上一個,,但也差不了多少啦)
可以看到他把輸入的字符的ASCII碼按int類型存儲到新的一塊內存地址,也就是上圖IDA中的v34
在這裏插入圖片描述
然後這個for循環就分析完畢了
CC1771函數獲取輸入的長度賦值給v13
然後CC1D6獲取該複製的內存地址的長度,比較這兩個長度,當相等的時候也就複製完畢了
然後CC1528獲取每一個字符的地址,給v32
CC15D2函數將v32複製給v34指向的內存地址
在這裏插入圖片描述
然後就是下面的CC11BD函數,他將v34傳了進去
在這裏插入圖片描述
雙擊進去,可以猜到是判斷長度是否等於16(猜不到可以用OD多調試幾遍,查看一下sub_CC11D6的返回值(emmm,寫到這才發現這個函數上面也出現過,做題的時候真沒發現)
在這裏插入圖片描述
知道CC11BD函數判斷長度後,看一下sub_CC1721函數
在這裏插入圖片描述
IDA雙擊進去,用OD調試一下,獲取一下CC1456的返回值也就是v8的值是新複製內存的地址,而CC1375的返回值V7是新複製內存結尾的地址。
然後while循環用首地址V8進行運算,每次給首地址V8+1,直到他等於尾地址V7 。程序知道數組循環完了就退出了。
在這裏插入圖片描述
具體的運算就是*v8異或了v6,而v6是由for循環累加得到的。
for循環的條件就是*i小於*v8,也就是讓*i小於輸入字符的ASCII碼值

*i的值先返回OD查看CC1325的返回值
通過記錄得到2,3,5,7,11,…猜測是質數
然後回到IDA,查看CC1325函數沒發現東西,看參數v9來自函數CC16E0
進入CC16E0函數
在這裏插入圖片描述
小於a2也就是小於128,然後進CC1672函數發現了質數的代碼
在這裏插入圖片描述
在這裏插入圖片描述
所以加密函數內的邏輯就差不多爲,
將比輸入字符ASCII碼小的質數加起來,然後與輸入字符進行異或,得到一個int類型數組
在這裏插入圖片描述
然後去看判斷是否成功的函數
在這裏插入圖片描述
這些函數都可以通過OD調試得到返回值,根據返回值可以判斷是啥,,,
然後CC1325經過調試,每次的返回值就是v9數組

可以得到判斷函數就是判斷,加密後的數組是否等於v9數組

寫腳本得到flag
在這裏插入圖片描述
在這裏插入圖片描述

#include <iostream>

using namespace std;

int zhishu(int num)
{
    for (int i = 2; i < num; i++)
    {
        if (!(num % i))
            return 0;
    }
    return 1;
}
int jm(int num)
{
    int sum = 0;
    for (int i = 2; i < num; i++)
        if (zhishu(i))
            sum += i;
    return sum ^ num;
}

int main()
{
    const int data[16] = { 438,1176,1089,377,377,1600,924,377,1610,924,637,639,376,566,836,830 };
    string flag = "";
    for (int i = 0; i < 16; i++)
    {
        for (int j = 0; j < 128; j++)
            if (jm(j) == data[i])
                flag += (char)j;
    }
    cout << "flag{" << flag << "}" << endl;
}

得到最終flag爲flag{Che11y_1s_EG0IST}
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章