1. 程式人生 > >170708 逆向-南郵CTF逆向(maze)

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.明日計劃
全國大學生資訊保安競賽