安恆X計劃平臺10月月賽逆向題BASE++題目思路
阿新 • • 發佈:2018-10-31
這道題比賽時就看到了名字 沒下載到
一直在找題目附件 發現52破解上yechen123師傅發了帖子
就下載下來分析了一波 現在來記錄一下
IDA載入靜態分析可知
關鍵程式碼就在main()
程式與我們拿到flag有關的步驟就是
0x01:判斷my_str_len(ps:就是我們輸入的字串的長度)是否小於32 正確的輸入最後算出來正好等於32 所以將會繼續向下執行
0x02:sub_91100()將我們得輸入my_str中的字母進行替換
0x03:通過sub_91360()與sub_91440()他倆配合的變種base64(ps:分析可知,只是替換了編碼表而已) 進行編碼
0x04:得到的串需要等於"TRLT5amLBoLT5Z6Fa5LqN6mkTomqR66Da4LqX5mgBwkkP5wmTZ6D===="
int __cdecl main(int argc, const char **argv, const char **envp) { int result; // eax int v4; // [esp+30h] [ebp-28h] int v5; // [esp+34h] [ebp-24h] printf(std::cout, "please input your flag:"); scanf(std::cin, my_str); if ( strlen(my_str) < 32 ) // 我們的輸入 my_str長度必須小於32 goto LABEL_14; sub_91100(my_str); // 這裡將my_str中的小寫字母進行替換 v5 = strcmp(my_str, "guvf_vf_n_snxr_synt_____________"); if ( v5 ) v5 = -(v5 < 0) | 1; if ( v5 ) { LABEL_14: sub_91360(); // 替換了base32編碼的密碼錶 sub_91440(strlen(my_str), my_str, a0); // 進行變種base32編碼 用32個字元表示256個ASC字元,也就是說5個ASC字元一組可以生成8個Base字元 v4 = strcmp(a0, "TRLT5amLBoLT5Z6Fa5LqN6mkTomqR66Da4LqX5mgBwkkP5wmTZ6D====");// 用變種base32加密後 與這個串進行比較 if ( v4 ) v4 = -(v4 < 0) | 1; if ( v4 ) printf(std::cout, "soooooooooorry\n"); else // 如果v4等於0 則輸出"Congratulations!!!" printf(std::cout, "Congratulations!!!\n"); system("pause"); result = 0; } else { printf(std::cout, "try harder!\n"); result = 0; } return result; }
IDA動態除錯時
F7進入sub_91360()可以看到 地址0009507C開始存放著這麼一個字串byte_9507C
這個就是要使用的密碼錶
NoPqRsTuVwXyZaBcDeFgHiJkLm765432
有了編碼表之後 可以很容易求得編碼之前的串
import string import base64 my_base64table = "NoPqRsTuVwXyZaBcDeFgHiJkLm765432" std_base64table ="ABCDEFGHIJKLMNOPQRSTUVWXYZ234567" s = "TRLT5amLBoLT5Z6Fa5LqN6mkTomqR66Da4LqX5mgBwkkP5wmTZ6D====" s = s.translate(string.maketrans(my_base64table,std_base64table)) print base64.b32decode(s) #10n78ppn3ro00o70r2opop5s3roqq937
但是這裡就可以發現 長度正好是32位
那就肯定經過了0x02這個步驟
signed int __thiscall sub_91100(const char *this)
{
const char *v1; // edi
unsigned int i; // esi
char v3; // cl
v1 = this;
i = 0;
if ( strlen(this) ) //this 就是我們的my_str
{
do
{
v3 = v1[i];
if ( (v3 - 0x61) <= 0x19u ) //如果有小寫字母就進行這種操作
v1[i] = (v3 - 0x54) % 26 + 0x61;
if ( (v3 - 0x41) <= 0x19u ) //如果有大寫字母就進行這種操作
v1[i] = (v3 - 0x34) % 26 + 0x41;
++i;
}
while ( i < strlen(v1) );
}
return 1;
}
因為base32解碼之後只有小寫字母
那我們只要把它們逆一下即可
這裡是yechen123師傅的指令碼
先生成密碼錶
然後對應下標即可(ps:又get到一個姿勢)
key = "10n78ppn3ro00o70r2opop5s3roqq937"
asciis = []
g = []
for i in range(97,123):
asciis.append(chr(((i-84)%26)+97))#生成移位之後的表
for i in range(0,32):
if (97<=ord(key[i])<=122):#小寫才用改 數字就算了
temp = ord(key[i])-97
g.append(asciis[temp])
continue
g.append(key[i])
flag = ""
for i in g:
flag += i
print (flag)
#10a78cca3eb00b70e2bcbc5f3ebdd937
推薦大家看師傅寫的 非常詳細
https://www.52pojie.cn/forum.php?mod=viewthread&tid=813470&extra=page%3D1&page=1