0x00前言
一直以來都在研究Android的逆向,最近才開始研究PE逆向。這是第一次發關于PE逆向的帖子,所以有什么不妥或錯誤之處,還請壇友糾正。5月份,山西省舉辦了首屆大學生信息安全技能大賽--個人賽(借助i春秋平臺),本人有幸得到了本次大賽中唯一的一道逆向題目(價值200分,屬于中級題目)。本文以該題目作為研究對象(題目會在文章末尾的附件給出),下面正式開始題目的初探。。。
0x01初探
當得到這個題目之后,我們需要先了解該題目類型,下面是我得到的題目屬性截圖:
顯然這是一個windows平臺上面的題目,接下來我們看一下這個CrackMe的運行效果
這里是在cmd中運行的,這里要說一下的是,如果直接雙擊運行的話,在輸入答案之后,程序就會直接退出,看不見“回答錯誤!!!”這個信息,所以我們需要在cmd中運行,才能看到輸入答案后的結果。
明白了運行的效果,我們接下來看一下,這個CrackMe有沒有加殼,以及使用了哪些加密算法(看了官方的writeup之后,才知道PEID可以查出來)
通過PEID查殼,我們可以看出,該CM沒有加殼。而且借助PEID的插件,我們也可以看出來該CM使用了MD5和Rijndael(AES)加密算法。
0x02分析加密流程
分析完了CM加殼和加密情況之后,我們正式開始CM的調試之旅。
通過動態靜態分析,我們在這里看到了MD5加密的特征數。
F5我們進一步分析,發現該CM對前8字節進行MD5加密(不太熟悉MD5的話可以去補習一下)。
繼續分析,這里是對MD5加密后的密文進行比較,大概的流程如下:
這可以看作是一個解方程組的過程,最后解出的結果是:
a=0x4d2ea664
b=0xd50fa3b6
c=0x3f67863b
d=0x9560e59b
那么MD5密文就是64a62e4db6a30fd53b86673f9be56095
因為MD5加密是不可逆的,也就是說MD5加密是沒有解密算法的,這里就需要我們借助在線的MD5解密平臺了。
通過在線解密,我們看到明文是ichunqiu,接下來,我們繼續分析。
繼續分析,我們發現這里對剩下的字符串長度進行了比較,可以看出來,如果剩下字符串長度不等于0x10就退出,所以這里的字符串長度一定是0x10。
在這里對剩下字符串判斷,是否是大寫字母,到這里我們可以得到“字符串是16字節的大寫字母字符串”這個結論。
往下分析,我們看到,在這里以FROMYWWAY作為密鑰,對16字節的字符串進行了維吉尼亞加密。
最后到了這里就是AES加密了,這里就不再具體看匯編代碼了,值得一提的是,這里用的AES加密模式CBC模式。
因為使用的是AES-CBC加密,所以需要一個IV,在這里,我們看到IV就是ichunqiu的MD5密文。
在這里是比較AES加密后的結果,比較數據是:
到這里加密流程就分行完了,接下來詳細對加密進行分析。
0x03加密詳解
通過對加密流程的分析,我們可以得到加密流程如下:
在這里我們主要要找的明文是全是大寫字母的16字節字符串,所以我們需要詳細分析一下AES加密流程。
[C] 純文本查看 復制代碼
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
void func6(unsigned char*mi,unsigned char*key,unsigned char*md5) {
int i;
//輪密鑰加
for (i = 0; i < 0x10; i++) {
mi ^= key;
}
for (i = 1; i < 10;i++) {
func4(mi,key,i);
func5(mi); //列混淆
}
func4(mi,key,10);
for (i = 0; i < 0x10; i++) {
mi ^= md5;
}
}
|
[C] 純文本查看 復制代碼
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
void func4(unsigned char*mi,unsigned char*key,int k) {
int i, j;
unsigned char a, b;
unsigned char *c,*d;
//向下列移位
/*
state’[j] = state[(4+i-j)%4][j]
*/
a = mi[9];
b = mi[0xD];
mi[0xD] = a;
a = mi[5];
mi[9] = a;
a = mi[1];
mi[5] = a;
a = mi[0xA];
mi[1] = b;
b = mi[2];
mi[2] = a;
a = mi[0xE];
mi[0xA] = b;
b = mi[6];
mi[6] = a;
a = mi[7];
mi[0xE] = b;
b = mi[3];
mi[3] = a;
a = mi[0xB];
mi[7] = a;
a = mi[0xF];
mi[0xB] = a;
mi[0xF] = b;
//字節替換
d = mi;
for (i = 0; i < 4;i++) {
c = d;
for (j = 0; j < 4;j++) {
a = *c;
c += 4;
a=table3[a];
*(c - 4) = a;
}
d++;
}
//輪密鑰加
for (i = 0; i < 0x10; i++) {
mi ^= *(key-0x10*k+i);
}
}
|
這就是我分析出來的AES加密流程代碼,大致分為以下幾個流程:
1.密鑰擴展
2.10輪加密變換
3.矩陣行列互換
通過對標準AES的加密流程的分析,我們來分析一下,CM用的AES加密流程是什么樣的?
根據我編寫的加密代碼,AES的加密流程是:
1.輪密鑰加
2.(向下列移位,字節替代,列混淆)9輪加密
3.向下列移位,字節替代
4.異或MD5
通過比較,我們發現這里的AES加密過程事實上是一個標準的AES解密過程

但是如果我們足夠細心,還可以發現一處不同之處,明明在標準的AES加密解密過程中,進行的是行移位,但是在CM中卻是列移位。按我的理解是,因為在最后進行了矩陣的行列互換導致的吧,這一點我依然持保留意見。
詳細分析了加密流程,寫出解密代碼就簡單多了。加解密代碼我都會在附件中給出。
0x04結語
最后以成功的效果圖作為結尾。
附件: http://pan.baidu.com/s/1mi3beeG 密碼: 6xjf
版權聲明:允許轉載,但是一定要注明出處。
|