解題概要
使用pe分析是32位文件,使用ida反匯編分析代碼邏輯,是一道要求用戶輸入flag,然后比較的題目。
正確flag并不是明文存儲(chǔ),所以解題關(guān)鍵為分析構(gòu)造flag的函數(shù)。
需注意的是使用wchar_t,分析可得是32bit長(zhǎng)(搜索得到長(zhǎng)度可能是16或32bit)。
以下按時(shí)間順序分享解題過程。
解題過程
主函數(shù)非常直白,連續(xù)調(diào)用四個(gè)函數(shù),然后就什么都沒干了。
setlocale(6, &locale);
banner();
prompt_authentication();
authenticate();
前三個(gè)函數(shù)都莫名奇妙,第一個(gè)搜索得到是用于區(qū)域設(shè)置。
第二個(gè)獲取時(shí)間,搞個(gè)隨機(jī)數(shù)種子,還輸出了歡迎語。
第三個(gè)故弄玄虛,函數(shù)里只輸出了句話叫你輸入。
重點(diǎn)在第四個(gè)
void authenticate()
{
int ws[8192]; // [esp+1Ch] [ebp-800Ch]
wchar_t *s2; // [esp+801Ch] [ebp-Ch]
s2 = decrypt(&s, &unk_8048A90);
if ( fgetws(ws, 0x2000, stdin) )
{
ws[wcslen(ws) - 1] = 0;
if ( !wcscmp(ws, s2) )
wprintf("S");
else
wprintf("A");
}
free(s2);
}
fgetws是wchar_t版的fgets
wcscmp同樣是wchar_t版的strcmp
看到!wcscmp(ws, s2)第一反應(yīng)便是flag在這里。
ws來自用戶輸入,那么s2就是flag了。
而s2來自decrypt。看來這就是構(gòu)造flag的代碼了。
decrypt這個(gè)函數(shù)還算簡(jiǎn)單,自己轉(zhuǎn)成c或py運(yùn)行一遍即可得到flag。
簡(jiǎn)單分析下,實(shí)際上是循環(huán)用a2去減走s的數(shù)據(jù)。兩者差值恰好在ASCII范圍內(nèi),相減后直接轉(zhuǎn)為字符類型即可。
疑點(diǎn)
ida反匯編得到的c代碼中,用于flag數(shù)組下標(biāo)的v4并沒有初始化為0。
v4在棧中的地址是ebp-1Ch
而只有用于a2下標(biāo)的var_18[ebp-18h]被初始化為0。
可能題目出現(xiàn)了錯(cuò)誤,忘記初始化v4了。