天天看點

逆向工程實驗Pre9Pre9

贊賞碼 & 聯系方式 & 個人閑話

逆向工程前言

Pre9

1、閱讀 C語言随機數的實作:mingw與glibc

https://blog.csdn.net/elicococoo/article/details/41851473

C語言随機數的實作:mingw與glibc

關于随機數的實作都是基于線性同餘生成器(LCG,linear congruential generator)。

r(n + 1)= (r(n) * a + c) mod m     其中參數a、c、m直接影響r的品質。vc上微軟對随機數生成範圍進行了修改,方法較簡單,直接執行上述方程并取高16位數即可。作者在文章中給出了随機數産生方式的推理過程以及代碼實作。

2、閱讀 java 代碼混淆原理 ProGuard代碼混淆技術詳解

https://blog.csdn.net/u013378306/article/details/63682945

http://www.cnblogs.com/cr330326/p/5534915.html

java 代碼混淆原理

混淆器是由于Java程式運作時是動态連接配接的,是以編譯成的目标檔案中包含有符号表,使得Java程式很容易被反編譯,混淆器可以打亂class檔案中的符号資訊,使反向工程變得非常困難。現有的混淆器仍然存在很多無法完全避免的問題。Java混淆編譯器是在Sun JDK中提供的Java編譯器(javac)的基礎上完成的,修改了代碼生成過程,對編譯器生成的中間代碼進行混淆,最後再生成class檔案,這樣編譯和混淆隻需要一個步驟就可以完成。最後,作者介紹了如何安裝并運作JOC、如何使用符号保留指令以及給出一個JOC混淆後的案例。

ProGuard代碼混淆技術詳解

首先,Proguard是一個Java類檔案壓縮器、優化器、混淆器、預校驗器。壓縮環節會檢測以及移除沒有用到的類、字段、方法以及屬性。優化環節會分析以及優化方法的位元組碼。混淆環節會用無意義的短變量去重命名類、變量、方法。這些步驟讓代碼更精簡,更高效,也更難被逆向(破解)。 在編寫一個ProGuard檔案時,需要經過基本混淆、針對APP的量身定制、針對第三方jar包的解決方案三個基本過程。Android項目的安全性需要Proguard去保證,Proguard使開發的APK更健壯。

3、閱讀 結構體(對齊規則及舉例)

https://www.cnblogs.com/wsq-888/p/jie-gou-ti-dui-qi-gui-ze-ji-ju-li.html

結構體(對齊規則及舉例)

結構體是C語言中聚合資料類型的一類;可以被聲明為變量、數組、指針等,用以實作比較複雜的資料結構;是一系列元素的集合,這些元素被稱為結構體成員;結構體成員需要用結構體名通路。文章主要闡述了結構體進行對齊的原因和規則,并在文章末尾處舉例說明。對于結構體對齊有如下說明:計算結構體大小不是元素單純相加;32位CPU取四個位元組比一個位元組更高效友善;一般情況下32位預設4位元組對齊。平台原因(移植原因):不是所有的硬體平台都能通路任意位址的任意資料,某些硬體平台隻能在某些位址處取某些特定類型的資料的,否則抛出硬體異常。性能原因:資料結構(尤其是棧),應該盡可能在自然邊界上對齊,因為在通路為對齊的記憶體時,處理器需要通路兩次,而對齊的記憶體處理器隻需要通路一次。這些外部和内部的原因都決定了對于編譯器來講,結構體是否對齊會影響處理器的性能。

5、MD5 Collision Attack Lab(Task 4選做)

http://www.cis.syr.edu/~wedu/seed/Labs_16.04/Crypto/Crypto_MD5_Collision/

Task1: Generating Two Different Files with the Same MD5 Hash

1)用md5collgen生成兩個不同的檔案:

逆向工程實驗Pre9Pre9

2)比較生成的兩檔案:

逆向工程實驗Pre9Pre9

可以看出,生成的兩個檔案内容并不相同,但他們的哈希值是一樣的。

3)bless編輯器檢視兩檔案:

逆向工程實驗Pre9Pre9
逆向工程實驗Pre9Pre9

可以看出,兩檔案的字首都是一樣的(qwerty),而兩檔案的内容是存在差異的,比如0000006d處的位元組就不同。從中可以分析出md5collgen的原理。它從prifix.txt中取字首,如果字首不是64的倍數,則用零填充。md5collgen為兩個輸出檔案生成128位元組的内容,這兩個輸出檔案就是在這128位元組中存在部分差異。

問題1:如果字首檔案的長度不是64的倍數會發生什麼?

答1:md5collgen會自動填充0,直到字首長度滿足是64的倍數。

問題2:建立一個正好64位元組的字首檔案,然後再次運作沖突工具看看會發生什麼。

答2:無填充,64位元組即為字首。

逆向工程實驗Pre9Pre9

問題3:md5collgen為兩個輸出檔案生成的資料(128位元組)是否完全不同?請識别所有不同的位元組。

答3:不是完全不同,其中不同的位元組如下表所示:

逆向工程實驗Pre9Pre9
逆向工程實驗Pre9Pre9

Task2: Understanding MD5’s Property

1)将二進制檔案out1.bin和out2.bin分别與out3.bin連接配接成一個檔案(命名分别為out13.bin,out23.bin):

逆向工程實驗Pre9Pre9

2)計算out13.bin和out23.bin的哈希值:

逆向工程實驗Pre9Pre9

可以看出,兩檔案的哈希值是一樣的。可以證明MD5具有該屬性:給定兩個輸入M和N,如果MD5(M) = MD5(N),即M和N的MD5散列相同,那麼對于任何輸入T,MD5(M || T) = MD5(N || T),其中||代表串聯。

Task3: Generating Two Executable Files with the Same MD5 Hash

1)編譯題目所給代碼命名為1,将1複制一份命名為2。我們的目的是程式1,2雖不同,但它們的哈希值是一樣的:

逆向工程實驗Pre9Pre9
逆向工程實驗Pre9Pre9

2)bless打開程式1,找出數組的位置:

逆向工程實驗Pre9Pre9

可以看出,數組的起始位置是0x00001040。前面有0x1040位元組,正好是0x40的倍數,是以我們可以用前0x1040位元組當字首。

3)将程式1的前0x1040位元組作為prefix,用md5collgen生成兩哈希值相同的檔案out1.bin,out2.bin:

逆向工程實驗Pre9Pre9

4)用out1.bin的尾綴128位元組覆寫程式1的數組,用out2.bin的尾綴128位元組覆寫程式2的數組:

逆向工程實驗Pre9Pre9
逆向工程實驗Pre9Pre9

5)運作程式1和程式2,計算程式1和程式2的哈希值:

逆向工程實驗Pre9Pre9

運作程式1和程式2,發現程式1和程式2的輸出結果不同:說明程式1和程式2是不同的程式。同時這兩個程式的md5哈希值是相同的。這就說明我們構造哈希值相同但内容不同的兩個可執行檔案,是以實驗成功。

Task4: Making the Two Programs Behave Differently

1)編譯構造的代碼并命名為1。将1複制命名為2。我們的目的是程式1和程式2行為雖不同,但它們的哈希值是一樣的。

代碼如下:

#include <stdio.h>
unsigned char X[200] = { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 };
unsigned char Y[200] = { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 };
main() { 
	if (!strcmp(X, Y))
		printf("run benign code");
	else 
		printf("run malicious code");
	return;
}
           
逆向工程實驗Pre9Pre9

2)bless打開程式1,找出數組的位置:

逆向工程實驗Pre9Pre9

可以看出,數組的起始位置是0x00001040。前面有0x1040位元組,正好是0x40的倍數,是以我們可以用前0x1040位元組當字首。

3)将程式1的前0x1040位元組作為prefix,用md5collgen生成兩哈希值相同的檔案out1.bin,out2.bin:

逆向工程實驗Pre9Pre9

4)用out1.bin的尾綴128位元組覆寫程式1的數組X、數組Y和程式2的數組Y,用out2.bin的尾綴128位元組覆寫程式2的數組X:

逆向工程實驗Pre9Pre9
逆向工程實驗Pre9Pre9
逆向工程實驗Pre9Pre9
逆向工程實驗Pre9Pre9

5)運作程式1和程式2,計算程式1和程式2的哈希值:

逆向工程實驗Pre9Pre9

運作程式1時會執行正常代碼,而運作程式2時會執行惡意代碼,且這兩個程式的md5哈希值相同。這就說明我們構造了行為不同但哈希值相同的兩個程式,是以實驗成功。