170708 逆向-南郵CTF逆向(maze)
1625-5 王子昂 總結《2017年7月8日》 【連續第279天總結】
A. 南郵CTF逆向(5、6)
B. 5:
又是maze,拖到IDA分析後發現主要內容就在main中:
if ( strlen(&input) != 24 || strncmp(&input, "nctf{", 5uLL) || *(&byte_6010BF + 24) != 125 )
{
LABEL_22:
puts("Wrong flag!");
exit(-1);
}
v3 = 5LL;
if ( strlen(&input) - 1 > 5 ) // v9是行
// v9下一位元組是列
{
while ( 1 )
{
in = *(&input + v3); // 取第i個位元組
// 大寫O是x-1
// 小寫o是x+1
// .是y-1
// 0是y+1
//
v5 = 0;
if ( in > 78 )
{
in = (unsigned __int8)in;
if ( (unsigned __int8)in == 79 ) // O
{
v6 = sub_400650((_DWORD *)&v9 + 1); // v6=v9的下一位元組>0
// v9的下一位元組-1
goto LABEL_14;
}
if ( in == 111 ) // o
{
v6 = sub_400660((int *)&v9 + 1); // v9的下一位元組+1
// v6=v9的下一位元組<8
goto LABEL_14;
}
}
else
{
in = (unsigned __int8)in;
if ( (unsigned __int8)in == 46 ) // .
{
v6 = sub_400670(&v9); // v6=v9>0
// v9=v9-1
goto LABEL_14;
}
if ( in == 48 ) // 0
{
v6 = sub_400680((int *)&v9); // v9+1
// v6=v9<8
LABEL_14:
v5 = v6;
goto LABEL_15;
}
}
LABEL_15:
if ( !(unsigned __int8)sub_400690((__int64)asc_601060, SHIDWORD(v9), v9) )// [a1+a2+8*a3]==32或35
// 每步的落點限制
goto LABEL_22;
if ( ++v3 >= strlen(&input) - 1 )
{
if ( v5 ) // v6需要非0
break;
LABEL_20:
v7 = "Wrong flag!";
goto LABEL_21;
}
}
}
if ( *(&asc_601060[8 * (signed int)v9] + SHIDWORD(v9)) != 35 )// 最後一步需要為35
goto LABEL_20;
v7 = "Congratulations!";
LABEL_21:
puts(v7);
return 0LL;
}
首先判斷格式nctf{}和長度,然後對其中的字元進行不斷接受,四種字元oO0.表示對v9和*(&v9+1)的操作。由最後判斷時為地圖地址601060+8*v9+SHIDWORD(v9)可以猜出,v9為行數,每行8個字元,SHIDWORD為取v9的下一位元組(查詢可得知巨集定義)
直接檢視一下601060發現是一個長字串,裡面只有三種字元32、35和42
要求每步都落在32或35上,最後一步落在35上且不能出界(即橫縱座標超出8)
那麼很簡單,用IDC指令碼把地圖打印出來即可:
從左上角走起,最終走到2結束,正好18步。得到flag
6:IDA開啟,發現同樣是elf,這次F5陷入無響應和報錯中了
大致瀏覽一下彙編:
首先得到輸入,flag初值為1,然後判斷長度是否為0x19,不是則令flag=0
接著進行大量的資料處理,其中對輸入字串的處理夾雜在其中,其餘是無效的
最後對輸入字串和0x694060的字串進行比較,不等則令flag=0
如果flag=1則正確
查看了一下資料處理中沒有對0x694060的字串進行處理,因此只要得到該字串然後dump下對輸入字串的處理然後逆變換即可得到需要輸入的字串
然而,並不知道怎麼把彙編指令有選擇地拖出來……
暫放
C.明日計劃
全國大學生資訊保安競賽