實驗吧逆向catalyst-system Writeup
下載之後查看知道為ELF文件,linux中執行之後發現很慢;
拖入ida中查看發現有循環調用 sleep 函數:
這是已經改過了,edit -> patch program -> change byte 修改一下比較參數可以去除等待時間,總共去除兩處;
運行之後發現是輸入 username 和 passsword 的方式;
那麽問題就在兩者上面了。
反編譯之後查看源碼,v8對應username, v7為password.
點進第一個函數,在 return 中是對用戶名的判斷,易推斷出用戶名為 12 位長度( 0b1100 );
再看第二個函數,也是對用戶名進行判斷:
關於v4, v3, v2 的賦值,切到對應匯編代碼處看出以4個子節為一個 Int 進行賦值;之後就是一個三元一次方程,可以得到用戶名;
要註意用戶名的順序因為文件是小端序的,所以為 "catalyst_ceo";
第三個函數也是驗證用戶名正確性;
第四個函數,是對密碼的驗證,由此可以反推出密碼;
srand((unsigned int) seed)是C語言中的一個隨機數發生器初始化函數,而種子則為用戶名所對應的三個 int 值之和,因為種子為定值,所以rand()產生的隨機數序列是不變的;之後寫CPP文件得出隨機值,linux中運行得到10個隨機序列(Linux中返回最大32位隨機值,而 Windows 最大為16位),還要註意右邊比較值有正負之分,得到總共10個與密碼相關的數字,這時再註意到每一個 vx 值都為 Int 型,相當於 4 個char型;
在這裏由用戶名和密碼就可以獲得 flag 了,密碼每四個逆序排列;
Welcome to Catalyst systems
Loading.
Username: catalyst_ceo
Password: sLSVpQ4vK3cGWyW86AiZhggwLHBjmx9CRspVGggj
Logging in.
your flag is: ALEXCTF{1_t41d_y0u_y0u_ar3__gr34t__reverser__s33}
最後一個函數是flag生成:
s為密碼串,總共為10*4 = 40 個字符;
雙擊byte_6020A0 數據處,剛好40個字符與得到的字符進行異或;
選中數據,edit -> extractdata 得到數組;
註意因為程序為小端序,所以最後每四個字符逆序異或;
1 _cmp = [ 2 1441465642, 3 251096121, 4 -870437532, 5 -944322827, 6 647240698, 7 638382323, 8 282381039, 9 -966334428, 10 -58112612, 11 605226810 12 ] 13 _rand = [ 14 0x684749, 15 0x673ce537, 16 0x7b4505e7, 17 0x70a0b262, 18 0x33d5253c, 19 0x515a7675, 20 0x596d7d5d, 21 0x7cd29049, 22 0x59e72db6, 23 0x4654600d 24 ] 25 26 _xor = [ 27 0x42, 0x13, 0x27, 0x62, 0x41, 0x35, 0x6B, 0x0F, 0x7B, 0x46, 28 0x3C, 0x3E, 0x67, 0x0C, 0x08, 0x59, 0x44, 0x72, 0x36, 0x05, 29 0x0F, 0x15, 0x54, 0x43, 0x38, 0x17, 0x1D, 0x18, 0x08, 0x0E, 30 0x5C, 0x31, 0x21, 0x16, 0x02, 0x09, 0x18, 0x14, 0x54, 0x59 31 ] 32 33 p = 0 34 L = b‘‘ 35 36 for i in range(10): 37 tmp = hex(_cmp[i] + _rand[i])[2:] 38 # print(tmp) 39 while tmp: 40 L += bytes([int(tmp[:2], base=16) ^ _xor[p//4*4 + 3-p%4]]) 41 tmp = tmp[2:] 42 p += 1 43 44 LL = b‘‘ 45 while L: 46 LL += L[:4][::-1] 47 L = L[4:] 48 print(LL)
得到flag:ALEXCTF{1_t41d_y0u_y0u_ar3__gr34t__reverser__s33}
實驗吧逆向catalyst-system Writeup