2018網鼎杯re--beijing writeup
昨天一上午一直在做這道逆向題,這個題目執行起來輸出是亂碼,就很煩氣,一直在搞這個終端的編碼問題,搞了半天結果方向錯了,然後就放棄了,其實這道題做出來的人還是很多的,還是自己太菜了,感覺自己的re和pwn還是要多加努力學習才行,今天看到writeup來學習下,做一下學習的筆記哈。
拿到這個binary,用file命令看一下,這個binary的基本資訊,這是一個32位的elf檔案,放到ubuntu下執行一下發現是亂碼。
用ida反彙編逆向一下
int __cdecl main()
{
char v0; // al
char v1; // al
char v2; // al
char v3; // al
char v4; // al
char v5; // al
char v6; // al
char v7; // al
char v8; // al
char v9; // al
char v10; // al
char v11; // al
char v12; // al
char v13; // al
char v14; // al
char v15; // al
char v16; // al
char v17; // al
char v18; // al
char v19; // al
char v20; // al
v0 = encode(dword_804A03C); // 6
printf("%c", v0);
fflush(stdout);
v1 = encode(dword_804A044); // 9
printf("%c", v1);
fflush(stdout);
v2 = encode(dword_804A0E0); // ??
printf("%c", v2);
fflush(stdout);
v3 = encode(dword_804A050); // 1
printf("%c", v3);
fflush(stdout);
v4 = encode(dword_804A058); // 0xa
printf("%c", v4);
fflush(stdout);
v5 = encode(dword_804A0E4); // ??
printf("%c", v5);
fflush(stdout);
v6 = encode(dword_804A064); // 8
printf("%c", v6);
fflush(stdout);
v7 = encode(word_804A0E8); // ??
printf("%c", v7);
fflush(stdout);
v8 = encode(dword_804A070); // 0xb
printf("%c", v8);
fflush(stdout);
v9 = encode(dword_804A078); // 2
printf("%c", v9);
fflush(stdout);
v10 = encode(dword_804A080); // 3
printf("%c", v10);
fflush(stdout);
v11 = encode(dword_804A088); // 1
printf("%c", v11);
fflush(stdout);
v12 = encode(dword_804A090); // 0xd
printf("%c", v12);
fflush(stdout);
v13 = encode(dword_804A098); // 4
printf("%c", v13);
fflush(stdout);
v14 = encode(dword_804A0A0); // 5
printf("%c", v14);
fflush(stdout);
v15 = encode(dword_804A0A8); // 2
printf("%c", v15);
fflush(stdout);
v16 = encode(dword_804A0B0); // 7
printf("%c", v16);
fflush(stdout);
v17 = encode(dword_804A0B8); // 2
printf("%c", v17);
fflush(stdout);
v18 = encode(dword_804A0C0); // 3
printf("%c", v18);
fflush(stdout);
v19 = encode(dword_804A0C8); // 1
printf("%c", v19);
fflush(stdout);
v20 = encode(dword_804A0D0); // 0xc
printf("%c", v20);
fflush(stdout);
printf("\n");
return 0;
}
//ecode函式
case 0:
v2 = byte_804A021 ^ byte_804A020; // 0x61
break;
case 1:
v2 = byte_804A023 ^ byte_804A022; // 0x67
break;
case 2:
v2 = byte_804A025 ^ byte_804A024; // 0x69
break;
case 3:
v2 = byte_804A027 ^ byte_804A026; // 0x6e
break;
case 4:
v2 = byte_804A029 ^ byte_804A028; // 0x62
break;
case 5:
v2 = byte_804A02B ^ byte_804A02A; // 0x65
break;
case 6:
v2 = byte_804A02D ^ byte_804A02C; // 0x66
break;
case 7:
v2 = byte_804A02F ^ byte_804A02E; // 0x6a
break;
case 8:
v2 = byte_804A031 ^ byte_804A030; // 0x6d
break;
case 9:
v2 = byte_804A033 ^ byte_804A032; // 0x6c
break;
case 10:
v2 = byte_804A035 ^ byte_804A034; // 0x7b
break;
case 11:
v2 = byte_804A037 ^ byte_804A036; // 0x7a
break;
case 12:
v2 = byte_804A039 ^ byte_804A038; // 0x7d
break;
case 13:
v2 = byte_804A03B ^ byte_804A03A; // 0x5f
break;
經過手工探測發現,發現把異或表示式中的第二個地址的資料按照先前傳入的引數所執行case的運算的順序整理出來再弄成字元就是flag
例如:第一次傳入的資料是6,執行case6:chr(66h) --->'f'
但是這裡有一個問題,有三個傳入的引數是未知的,但是我們可以根據flag字串的順序,推斷出??=0
然後就得到flag{amazing_beijing}