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
版權聲明:允許轉載,但是一定要注明出處。
|