一個go語言crackme分析
by anhkgg(公衆號:漢客兒)
2019年2月23日
0x01.先看看
直接運行看看,嘗試輸入,看看結果。
一個console的程序,有提示信息,入手點應該很明顯,找字符串,或者printf
,scanf
之類的函數。
查個殼,是tElock 1.0 (private) -> tE! *
,沒脫過,常規脫殼方法嘗試弄不掉,百度一番看到挺多經驗分享的,但都是0.9x
版本的分析,不適用於本版本,那就放棄脫殼了(求脫殼大佬分享技巧)。
OD加載後直接運行,通過字符串搜索去查找,並未找到提示信息“口令解碼失敗”。
嘗試再命令窗口輸入bp printf
,然後F9,OD斷下,此時參數如下,OD並沒有解析出中文字符,用工具查看一番,發現是UTF-8編碼。
所以前面OD解析“口令解碼失敗”編碼問題,搜索不到。再次嘗試進入內存(M)
窗口,Ctrl+B
後在HEX
輸入字符的UTF-8
編碼,然後搜索,果然找到了。
另外找到一篇討論OD
編碼問題的文章,有興趣的可以看看:https://bbs.pediy.com/thread-181118.htm
不過此處也沒什麼用了,因爲bp printf
也能找到關鍵代碼。
在輸入uid
和口令之後,在printf
斷下,查看此時調用堆棧。
調用堆棧
地址 堆棧 函數過程 / 參數 調用來自 結構
1104BE80 00461BBD <jiubugao.printf> jiubugao.00461BB8
1104BE84 1104C160 format = ""
1104BE88 110101B0
1104BEA4 004635DD jiubugao.00461AD0 jiubugao.004635D8
1104BEC4 00462FA1 jiubugao.004635A0 jiubugao.00462F9C
1104BEF8 0047BA5A 包含jiubugao.00462FA1 jiubugao.0047BA58
1104BF28 0047BAF5 jiubugao.0047B9F0 jiubugao.0047BAF0
1104BF4C 0048C220 <jiubugao.printf> jiubugao.0048C21B
1104BF50 1104BF9C format = "?J"
1104BF54 00000001
1104BFCC 0042609A 包含jiubugao.0048C220 jiubugao.00426098
此時做了一番思考,作爲console
程序,整個代碼都在main
中完成,可能大概代碼結構如下:
int main() {
printf("【春節】解題領紅包之三\n");
printf("請輸入您的吾愛破解uid:);
scanf("%s", &uid);
printf("請輸入您的口令:);
scanf("%s", &code);
if(check(uid, code)) {
printf("口令解碼失敗");
} else {
//
}
}
那麼通過調用棧回溯到mian
,真個代碼結構就會很清楚了,算法分析也應該會更簡單。
在OD
中回溯直到0048C220
看到結構類似上面猜測的代碼,然後dump出來,通過IDA
查看確認了一下,應該沒錯了。
分析算法
開始分析算法,通過OD
調試確認,前面一部分都是輸入輸出相關代碼,直接跳過。
直到看到下面幾個特徵,明顯看出是hash算法相關特徵了,一番搜索之後確認之後是sha1
。
調試結果和py計算結果一致,將輸入的uid
通過sha1
算法得到一個hash值。
看到這個特別的返回值方式,以及字符串中這種xxx.go
的字符,我才意識到這是一個go
語言寫的程序。
繼續檢查輸入的口令長度,小於0x10
則輸出"口令解碼失敗"。
輸入長於0x10
的口令之後,重新開始,然後看下一個函數。看到這個ABCD...+/
特徵,很明顯就是base64
編碼,第一個反應是把口令編碼。
結果發現並不是我想的那樣,結果如下。
看到輸出"口令解碼失敗"意識到這可能是base64
解碼函數,生成一個base64
編碼字符輸入嘗試一下。
>>> base64.b64encode('1234567890')
'MTIzNDU2Nzg5MA=='
果然,調試中看到解碼正確。
繼續往下走,到48BC80
,輸入剛纔解碼的口令以及uid
的hash
,先直接F8跳過。
程序異常提示出一些信息,可以看出這個在AesDecrypt
的時候出錯。
所以意識到48BC80
是AES
解密算法。那麼輸入的口令結構應該是這樣的才能解密成功。
輸入口令=Base64Encode(AesCrypt(口令,sha1(uid)))
找了一段aes
加密的python
代碼,構造一個口令,如下:
python aes.py
kJgRdtADqzjDKXiHHr770g== 11111111
在口令出輸入kJgRdtADqzjDKXiHHr770g==
之後,再次嘗試,果然解密成功。
繼續往下,看到判斷解密的口令長度是不是0x1A
,如果不是則錯誤。
所以加密前口令長度應該0x1A
,先修改標誌讓OD正常繼續執行,到402000
,三個參數,解密後口令,HappyNewYearFrom52PoJie.CnLine Islands Standa
,以及口令長度,很明顯是一個字符串比較函數。
結合長度限制0x1A
,那麼口令應該是HappyNewYearFrom52PoJie.Cn
,用python加密後輸入嘗試一下。
python aes.py
9D7boJcaCbENFCpf6YRBmJFZjPsPyUot8sHdR5YTChw= HappyNewYearFrom52PoJie.Cn
果然成功。
彩蛋
最後已經完成了,我用IDA
打開了原始程序看一看,沒想到看到了這個。
IDA
完全支持go
語言IDL
符號解析,然後最開始PEID
查的啥殼啊,完全是忽悠人的。
所以如果剛開我就用IDA
來分析這個代碼,是不是更快呢!
第一次分析go
的坑,以後會長記性了。