MRCTF的MR_register.exe復現
首先先用exeinfope查一下殼

沒有加殼,64位的程式 ,拉入ida64進行分析

這兩個肯定有一個里面有主函式,我們都點進去看看
sub_402E50()

確實看不出什么東西
sub_401180()

往下翻翻,看到initenv 初始環境的意思,所有main函式很可能在下面
繼續跟sub_4015F0()

這題其實是個雙執行緒問題,就是父行程(else后的內容)執行后,擔任除錯器的角色,去呼叫if中的 sub_4026EA()函式
注意一點:
當我們在除錯這個程式的時候,會有報錯

這里報錯的原因應該是分母為0導致的

在子行程中V19=1,列印出flag
所以關鍵是看DebugEvent.dwDebugEventCode == 1的活動:接受處理來自子行程的例外,進而修改子行程代碼

SMC的題目,我們就讓它自己跑起來解密就行了
關鍵代碼還是在除錯的子執行緒中,我們分析一下
為什么會程式自報錯?
原本兩個行程是互不相關的,當子行程產生錯誤后,回傳給父行程,父行程才知道要進行處理了,但是也不是一直處理,所以就會出現另外一個錯誤,告訴父行程處理完了,可以停止了,
所以現在關鍵就是要去尋找子行程要執行函式中出現觸發例外地方

繼續分析子行程

加密邏輯主要就關注到sub_401CA7

點進去是這樣的,我們發現很多代碼被混淆了

這里前面會有int 3觸發斷點,后面還有很多錯誤指令,實際是一個smc,那可以猜到就是先觸發斷點后被主行程除錯器所捕獲,然后進行解密,之后被除錯行程繼續運行
我們寫腳本跑一下SMC,這里直接貼上官方WP的腳本
下面展示一下
#include <idc.idc>
static main(){
auto addr = 0x401E1F;
auto i = 0;
for(i=0;i<0x57E;i++){
PatchByte(addr + i,Byte(addr + i) ^i);
}
}

在函式開頭按d 決議成資料
將黃色部分全部選中 按c 決議成代碼

將int 3 nop掉

我們發現rip+2
直接跳到兩個位元組之后,patch混淆的三個位元組
現在所有代碼都紅了,直接全選,按p創建函式,f5反編譯

加密代碼就出來了
回傳之前的子行程中看了下傳參,第一次引數密鑰credentials,第二個是email

這是加密流程
加密操作不復雜,查看驗證函式


就是把郵箱密文和密鑰密文按照-的分割來分別讀取出來,最后把密鑰最后一次與郵箱密文的異或加密給異或回去,經過這個解密操作后進行比較

但是這還沒完,因為這個驗證陣列是被修過的,在主行程進行除錯的某一時刻會重新修改此處記憶體,這一部分的實作主要是通過管道通信和環境變數的設定來完成的
子行程在這里活得自己行程check陣列的儲存位置后利用v24/=Buffer[19]觸發除零例外,在這之前講記憶體地址用writefile寫到管道中,子行程捕獲例外后獲取地址,修改記憶體位置的值,處理例外,子程式繼續執行,但是check陣列已被改變,


處理除零例外,此處sub_402545進行修改記憶體,進行了加花,patch即可,改call+ret+pop為jmp即可



對記憶體進行了一次異或操作
大概就分析完了,其實還是挺有難度的,我的思路也比較亂,把網上各位師傅的WP都翻看了下,進行了總結
最后貼上大師傅的腳本
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void map(char key,int *x,int *y){
int i = 0,j = 0;
char table[9][9]={'\0'};
strcpy(table[0],"ABCDEFGH");
strcpy(table[1],"12345678");
strcpy(table[2],"0IJKLMNO");
strcpy(table[3],"+OPQRStu");
strcpy(table[4],"\\vwxyzTU");
strcpy(table[5],"abcdefgh");
strcpy(table[6],"VWXYZijk");
strcpy(table[7],"lmnopqrs");
for(i=0;i<8;i++){
for(j=0;j<8;j++){
if(table[i][j]==key){
*x = i;
*y = j;
return ;
}
}
}
}
int main()
{
int x,y,z;
int count = 0;
int i = 0,j = 0,k = 0;
char tmp[10]={'\0'};
int result[100]={0};
char plain[376]={'\0'};
int flag[376]={29,110,78,63,57,58,40,41,23,20,55,70,67,48,17,18,45,46,2,12,48,49,50,62,37,38,5,118,94,45,15,12,29,30,63,76,102,
21,56,59,21,22,6,117,111,28,3,0,13,124,127,3,16,108,122,11,5,6,42,43,33,82,125,14,80,83,127,124,91,90,86,88,108,16,6,119,113,114,
80,81,125,14,17,98,120,123,107,104,118,120,126,112,113,112,67,64,93,81,70,58,5,121,66,76,121,122,87,38,35,95,74,68,109,108,108,111,
73,74,102,103,84,90,94,80,99,98,82,81,189,190,157,156,169,168,151,153,173,209,198,183,177,178,144,227,220,160,183,185,139,138,187,184,
165,166,183,182,130,241,221,174,190,176,134,138,153,232,229,150,184,185,180,199,225,146,128,131,141,142,162,163,165,164,171,216,247,132,
148,231,241,128,131,128,208,163,129,242,233,232,217,216,230,231,213,214,241,242,209,162,147,146,144,227,196,197,201,200,199,196,231,228,
193,192,240,241,240,241,252,143,166,213,248,251,213,214,199,180,141,140,163,208,222,223,236,237,233,234,203,186,186,201,231,148,176,204,
219,213,46,47,44,47,57,58,22,23,23,22,23,25,41,85,65,64,82,46,55,59,41,42,6,117,84,40,63,49,48,62,58,52,13,126,110,31,25,26,57,74,73,72,
101,22,60,61,2,12,21,105,126,15,9,10,43,88,116,7,22,24,25,23,47,46,109,30,0,113,121,122,106,25,4,119,100,23,15,115,106,100,77,76,66,65,105,
24,27,26,27,26,22,101,66,76,122,6,45,44,46,95,89,90,118,119,117,123,78,64,115,0,33,82,96,110,86,42,54,71,75,120};
for(i=374;i>=0;i--){
flag[i] = flag[i] ^ i ^ flag[i+1];
}
for(i=0;i<376;i+=2){
map(flag[i],&x,&y);
map(flag[i+1],&y,&z);
plain[j++] = ((x << 6)|(y << 3)|(z));
}
j = 0;
for(i=0;i<strlen(plain);i++){
while(plain[i+j]!='#'&&plain[i+j]!='\0'){
j++;
}
strncpy(tmp,plain+i,j);
result[k++] = strtoul(tmp,0,16);
count++;
i = i+j;
j = 0;
}
for(i = count-1;i>=2;i--){
result[i] = result[i] - result[i-1] - result[i-2];
}
for(i=0;i<count;i++)
printf("%c",result[i]);
return 0;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/278549.html
標籤:其他
