生活随笔
收集整理的這篇文章主要介紹了
REVERSE-PRACTICE-BUUCTF-18
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
REVERSE-PRACTICE-BUUCTF-18
- [SWPU2019]ReverseMe
- [FlareOn1]Bob Doge
- [FlareOn5]Ultimate Minesweeper
- [GKCTF2020]Chelly's identity
[SWPU2019]ReverseMe
exe程序,運行后提示輸入flag,輸入錯誤打印“Try again”,無殼,ida分析
交叉引用字符串“Please input your flag:”來到sub_C22810函數
主要的邏輯為
獲取輸入,輸入的長度為32,輸入與字符串"SWPU_2019_CTF"循環異或,sub_C225C0函數對異或后的input進行處理,結果放在v27和v28,最后v27和v28與v36~v43比較,驗證輸入
int __thiscall
sub_C22810(void *this
)
{int v1
; int v2
; int v3
; int v4
; signed int v5
; unsigned int v6
; int *v7
; int *input_copy
; int *v9
; __int128
*v10
; unsigned int v11
; int v12
; int v13
; bool v14
; unsigned __int8 v15
; unsigned __int8 v16
; unsigned __int8 v17
; const char *v18
; int v19
; int v20
; int v22
; int v23
; int *input
; int v25
; unsigned int v26
; __int128 v27
; __int128 v28
; int v29
; __int128 v30
; __int128 v31
; int v32
; __int64 v33
; int v34
; __int16 v35
; int v36
; int v37
; int v38
; int v39
; int v40
; int v41
; int v42
; int v43
; int v44
; v25
= 0;v26
= 15;LOBYTE(input
) = 0;v44
= 0;LOBYTE(v44
) = 1;v1
= printf(this
, "Please input your flag: ");printf_(v1
);sub_C237B0(&dword_C50068
, &input
); v34
= 'TC_9'; v33
= qword_C4B9A0
;v35
= 'F';if ( v25
== 32 ) {v40
= 0xBA143D17;v41
= 0x1D730350;v42
= 0x9404607A;v43
= 0x290AF070;v5
= 0;v30
= 0i64
;v32
= 0;v31
= 0i64
;v6
= strlen((const char *)&v33
);do {v7
= (int *)&input
;if ( v26
>= 16 )v7
= input
;*((_BYTE
*)v7
+ v5
) ^= *((_BYTE
*)&v33
+ v5
% v6
);++v5
;}while ( v5
< 32 );input_copy
= (int *)&input
;v4
= (int)input
;if ( v26
>= 0x10 )input_copy
= input
;v29
= 0;v27
= 0i64
;v28
= 0i64
;*(_QWORD
*)&v30
= *(_QWORD
*)input_copy
;*((_QWORD
*)&v30
+ 1) = *((_QWORD
*)input_copy
+ 1);*(_QWORD
*)&v31
= *((_QWORD
*)input_copy
+ 2);*((_QWORD
*)&v31
+ 1) = *((_QWORD
*)input_copy
+ 3);sub_C225C0(v22
, v23
, 256, (unsigned int)&v30
, (unsigned int)&v27
);v36
= 0xF80F37B3;v37
= 0x5DAEBCBC;v9
= &v36
;v38
= 0x864D5ABA;v10
= &v27
;v39
= 0xD3629744;v11
= 28;v40
= 0x1624BA4F;v41
= 0x1A729F0B;v42
= 0x266D6865;v43
= 0x67C86BBA;while ( 1 ) {v12
= *v9
;if ( *v9
!= *(_DWORD
*)v10
)break;++v9
;v10
= (__int128
*)((char *)v10
+ 4);v14
= v11
< 4;v11
-= 4;if ( v14
) {v13
= 0;goto LABEL_19
;}}v14
= (unsigned __int8
)v12
< *(_BYTE
*)v10
;if ( (_BYTE
)v12
!= *(_BYTE
*)v10
|| (v15
= *((_BYTE
*)v9
+ 1), v14
= v15
< *((_BYTE
*)v10
+ 1), v15
!= *((_BYTE
*)v10
+ 1))|| (v16
= *((_BYTE
*)v9
+ 2), v14
= v16
< *((_BYTE
*)v10
+ 2), v16
!= *((_BYTE
*)v10
+ 2))|| (v17
= *((_BYTE
*)v9
+ 3), v14
= v17
< *((_BYTE
*)v10
+ 3), v17
!= *((_BYTE
*)v10
+ 3)) ){v13
= -v14
| 1;}else{v13
= 0;}
LABEL_19
:if ( v13
) v18
= "Try again!\r\n";elsev18
= "Congratulations! I always knew you could do it.";v19
= printf(v9
, v18
);printf_(v19
);sub_C2ADBE("pause");}else{v3
= printf(v2
, "Try again!\r\n");printf_(v3
);sub_C2ADBE("pause");v4
= (int)input
;}if ( v26
>= 0x10 ){v20
= v4
;if ( v26
+ 1 >= 0x1000 ){v4
= *(_DWORD
*)(v4
- 4);if ( (unsigned int)(v20
- v4
- 4) > 0x1F )sub_C2AFF7(v26
+ 36);}sub_C264DE(v4
);}return 0;
}
sub_C225C0函數對異或后的input進行處理,可通過下內存斷點得知具體情況
首先在調用sub_C225C0函數前下斷點,開始調試
輸入為abcdefghijklmnopqrstuvwxyz123456,經過與"SWPU_2019_CTF"的循環異或及變量賦值后,v30即為input循環異或后的結果
在0x4FF858處按F2下內存斷點
按F9執行,來到一個v30(下圖中為v25)與v28異或的地方
可知sub_C225C0函數是對循環異或后的input的結果的再一次異或,但是不知道異或的是哪些值
由于我們輸入是“abcdefghijklmnopqrstuvwxyz123456”,與"SWPU_2019_CTF"異或后的結果v30是確定的,可以通過調試得到sub_C225C0函數調用完后,結果v27和v28的值,再用v30異或v27和v28得到sub_C225C0函數中參與異或運算的另一些值
調試得到v27和v28為
寫逆運算腳本即可得到flag
a
=[0xB4, 0x39, 0x0D, 0xFB, 0xA2, 0x83, 0xF9, 0x40, 0xB2, 0x42,0x43, 0x9E, 0x41, 0x9C, 0x4F, 0x90, 0x4D, 0xBC, 0x76, 0x41,0x3E, 0xB6, 0x53, 0x0B, 0x6E, 0x66, 0x29, 0x75, 0xE5, 0x1C,0xBE, 0x2C]
b
=[0x32, 0x35, 0x33, 0x31, 0x3A, 0x54, 0x57, 0x59, 0x50, 0x35,0x28, 0x38, 0x2B, 0x3D, 0x38, 0x20, 0x24, 0x2D, 0x41, 0x44,0x44, 0x4F, 0x28, 0x3B, 0x2D, 0x3C, 0x62, 0x65, 0x63, 0x61,0x6A, 0x04]
cipher
=[0xB3, 0x37, 0x0F, 0xF8, 0xBC, 0xBC, 0xAE, 0x5D, 0xBA, 0x5A,0x4D, 0x86, 0x44, 0x97, 0x62, 0xD3, 0x4F, 0xBA, 0x24, 0x16,0x0B, 0x9F, 0x72, 0x1A, 0x65, 0x68, 0x6D, 0x26, 0xBA, 0x6B,0xC8, 0x67]
s
="SWPU_2019_CTF"
flag
=""
for i
in range(len(cipher
)):flag
+=chr(a
[i
]^b
[i
]^cipher
[i
]^ord(s
[i
%len(s
)]))
print(flag
)
[FlareOn1]Bob Doge
exe程序,運行后點擊“DECODE”,看到一段不明白意義的字符串
查殼,發現是.Net程序,用dnSpy打開
找到“DECODE”按鈕的響應函數,看到該函數會得到三個字符串text,text2和text3,調試看看這三個字符串分別是什么
可以看到,字符串text即為flag
[FlareOn5]Ultimate Minesweeper
exe程序,運行后是個掃雷游戲,一共30x30=900個格子,897個雷,只有3個不是雷,提示說找到那3個不是雷的格子就能得到flag
查殼,發現是.Net程序,用dnSpy打開
先找到決定彈出失敗(FailurePopup)或成功(SuccessPopup)對話框(ShowDialog)的SquareRevealedCallback函數
選中SquareRevealedCallback函數名,右鍵->分析->被使用,來到MainForm函數
挨著點進去分析,發現在AllocateMemory函數會對900個格子,每個格子賦一個bool值,雷的格子賦為true,非雷的格子賦為false
在this.VALLOC_TYPES數組中就保存著非零格子的信息,但是不知道具體下標
調試,在執行完“this.mineFieldControl.DataSource = this.MineField;”后,在GarbageCollect數組中可以看到,雷的格子為true,非雷為false
找到3個非雷格子的位置分別為[7,20],[24,28],[28,7]
運行exe程序,點出3個非雷的格子(注意[]中第一個坐標為列,第二個坐標為行,且均從0開始),即可得到flag
[GKCTF2020]Chelly’s identity
exe程序,運行后輸入,無殼,ida分析
交叉引用字符串“flag is flag{(your answer)}!”來到sub_41C290函數
主要邏輯為,獲取輸入,驗證輸入長度是否為16,對輸入進行處理(實際上為對輸入進行異或運算),驗證處理后的輸入
sub_411721->sub_41B3B0
首先獲取2~128之間的素數,存到v12
然后進入while循環體,while里面有個小的for循環,for循環中的i小于輸入字符的ascii碼,且i每次的取值是2~128之間的素數,for循環中v9從0開始累加i,當i的取值大于等于輸入字符的ascii碼時,退出for循環,輸入和累加好的v9異或,再進入下一次while循環,直到輸入的每個字符都完成異或運算
從sub_411852函數中取出最后要比較的數據,寫逆腳本即可得到flag
import gmpy2
res
=[438,1176,1089,377,377,1600,924,377,1610,924,637,639,376,566,836,830]
sushu
=[]
for i
in range(2,128):if gmpy2
.is_prime
(i
):sushu
.append
(i
)
flag
=""
for i
in range(len(res
)):for j
in range(32,128):tmp
=0for k
in range(len(sushu
)):if sushu
[k
]<j
: tmp
+=sushu
[k
] else:breakif j
^tmp
==res
[i
]: flag
+=chr(j
)
print(flag
)
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎
總結
以上是生活随笔為你收集整理的REVERSE-PRACTICE-BUUCTF-18的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。