2018.7.24學習筆記
二進位制逆向題目解析
ctf2—-Input flag
用ida開啟這個檔案,進入流程圖模式:
使用Shift+12調出字串表,尋找有效字串:
這裡的字串很少,我們可以在下面看到一個”Flag is right”,點選進去可以進入彙編程式碼區:
點選紅色區域,進入流程圖模式,F5則可以進入彙編程式碼段,我們可以得到下面一串程式碼:
int __cdecl main()
{
char s; // [esp+10h] [ebp-110h]
printf("Input flag:");
sub_80485A0(&s, 0x100u);
if ( (unsigned __int8)sub_8048630(&s) )
puts("Flag is right.");
else
puts("Flag is wrong.");
return 0;
}
觀察程式碼,想要得到”Flag is right.”,我們要想先知道sub_8048630是什麼,點選進去,我們可以看到另外一串程式碼:
int __cdecl sub_8048630(char *s)
{
size_t v1; // eax
int v3; // edx
if ( s )
{
v1 = strlen(s);
if ( v1 )
{
if ( v1 == 29 )
{
v3 = 0;
while ( s[v3] == byte_8049AE0[(unsigned __int8)((unsigned __int8)byte_8049B15[v3] / 3u - 2)] )
{
if ( ++v3 == 29 )
return 1;
}
}
}
}
return 0;
}
兩個程式碼結合,我們知道,上面這個必須返回值為1,那我們就看怎麼令它為1,:
v1 = strlen(s);
if ( v1 )
{
if ( v1 == 29 )
{
v3 = 0;
while ( s[v3] == byte_8049AE0[(unsigned __int8)((unsigned __int8)byte_8049B15[v3] / 3u - 2)] )
{
if ( ++v3 == 29 )
return 1;
}
}
}
v1是s的字串長度,當v1=29時,才能向下執行,所以字串s的長度為29,向下執行,v3=0,
while ( s[v3] == byte_8049AE0[(unsigned __int8)((unsigned __int8)byte_8049B15[v3] / 3u - 2)] )
{
if ( ++v3 == 29 )
return 1;
當v3加到29時,才能返回1,所以while迴圈進行了29次,我們把 byte_8049AE0點進去發現了一串字串:
這串字串為:lk2j9Gh}AgfY4ds-a6QW1#k5ER_T[cvLbV7nOm3ZeX{CMt8SZo]U
再把byte_8049B15點進去:
會得到一串十六進位制數,用shift+E快捷鍵以字串陣列把它們提取出來,得到:
{
0x48, 0x5D, 0x8D, 0x24, 0x84, 0x27, 0x99, 0x9F, 0x54, 0x18,
0x1E, 0x69, 0x7E, 0x33, 0x15, 0x72, 0x8D, 0x33, 0x24, 0x63,
0x21, 0x54, 0x0C, 0x78, 0x78, 0x78, 0x78, 0x78, 0x1B
}
而byte_8049B15[v3] / 3u - 2)
這一句的意思是以v3作為下標來取byte_8049B15
這裡的數,取出來的數除以3,再減去2,得到另一個數,再以最後得到的這個數為下標去byte_8049AE0
裡面的字元,放到s下表為v3的裡面,所以,我們大概理清思路,就可以寫程式,獲得flag,
以下是python程式:
a=[0x48,0x5D,0x8D,0x24,0x84,0x27,0x99,
0x9F,0x54,0x18,0x1E,0x69,0x7E,0x33,0x15,
0x72,0x8D,0x33,0x24,0x63,0x21,0x54,0x0C,
0x78,0x78,0x78,0x78,0x78,0x1B]
b=[]
c='lk2j9Gh}AgfY4ds-a6QW1#k5ER_T[cvLbV7nOm3ZeX{CMt8SZo]U'
flag=''
for i in range(len(a)):
b.append(int(a[i]/3-2))
for j in range(len(b)):
flag+=c[b[j]]
print (flag)
得到的flag:
kctf{YoU_hAVe-GOt-fLg_233333}