逆向工程實驗Lab1

讚賞碼 & 聯繫方式 & 個人閒話

逆向工程前言

Lab1

1、This is a security check to prevent automated programs from creating accounts.

去下面這個論壇註冊一個賬號https://forum.tuts4you.com/

回答出security check問題就可以。This is a security check to prevent automated programs from creating accounts.(這是一個安全檢查,以防止自動程序創建帳戶。

代碼:

#include<stdio.h>
#include<math.h>
#include<string>

//八進制轉十進制
int OtoD(int oct) {   
	int i, dec = 0, remainder;
	for (i = 0;; i++) {
		remainder = oct % 10;
		dec = dec + remainder * pow(8, i);
		if (oct / 10 == 0) {
			return dec;
		}
		oct = oct / 10;
	}
}

int main() {
	int code[] = { 127,150,141,164,47,163,40,163,150,157,162,164,40,146,157,162,40,42,142,151,156,141,162,171,40,144,151,147,151,164,42,77 };
	int i, len;
	len = sizeof(code) / sizeof(code[0]);

	printf("Code:");  
	for (i = 0; i < len; i++)
		printf("%d ", code[i]);

	printf("\nQuestion: ");
	for (i = 0; i < len; i++) 
		printf("%c", OtoD(code[i]));

}

 運行結果:

輸出內容:

What’s short for “binary digit”?(二進制的簡寫是什麼?)

小結與討論:

二維碼掃出的數字文本,實際上是字符ASCII碼的八進制形式。我們要做的是通過編程將其轉爲十進制,並把對應的字符串輸出。

 

2、elfpass

把elfpass拷貝進seed虛擬機,設成root所有suid程序,用普通用戶去攻擊獲得root權限。可以先靜態分析,搞不定再用gdb動態調試。

Step1:設置權限

把elfpass拷貝進seed虛擬機,設置成root所有,賦予suid權限。

Step2:反彙編main函數

通過GDB調試elfpass,使用disas來反彙編main函數,可以看到如下的彙編代碼:

注意到裏面顯示了printf、scanf、strcmp函數,不難推測出分別是用作輸出提示語“password”,接收輸入的密碼以及將輸入密碼和正確密碼的比較。那麼在比較前esp和esp+4處放置的就爲兩個進行比較的字符串的地址。

Step3:設置斷點,推測正確密碼

我們在strcmp處添加斷點,輸入任意密碼,運行程序。我們首先查看esp得到儲存兩個字符串的地址。再分別查看兩個地址,發現其中一個地址中儲存的是我們輸入的密碼AAAA,另一個地址中儲存的應該就是真實的密碼。

Step4:確定密碼的字符串序列

把得到的ASCII碼拷貝進十六進制編輯器中,我們可以把16進制數轉換爲對應的可顯示字符。結合字符串在內存中的存儲順序,我們可以得到密碼:unixvswindows。

Step5:驗證

 

3、運行win.pyc,要求輸出'You Win'代表成功。

Step1:反編譯pyc文件

反編譯win.pyc文件,得出以下源碼:

Step2:分析py文件

分析源碼可得加密公式爲((ord(v) + seed ^ ord(key[seed])) % 255),flag有23位,諸位爆破即可。

Step3:攻擊

攻擊代碼如下:

#include<stdio.h>
#include<string.h>


int main() {
	char key1[] = "Maybe you are good at decryptint Byte Code, have a try!";
	int key2[] = { 124, 48, 52, 59, 164, 50, 37, 62, 67, 52, 48, 6, 1, 122, 3, 22, 72, 1, 1, 14, 46, 27, 232 };

	char simple[] = "QWERTYUIOPASDFGHJKLZXCVBNM{}";
	char ch;
	int i, j;
	int seed = 5;
	int tmp;

	printf("Flag:");

	for (i = 0; i < 23; i++) {   //flag有23位
		for (j = 0; j < strlen(simple); j++) {  //窮舉來試
			ch = simple[j];
			tmp = (ch + seed ^ (key1[seed])) % 255;  //原算法的加密方法
			if (tmp == key2[i])
				printf("%c", ch);
		}
		seed++;
	}
}

運行結果:

 

4、在windows操作系統下運行cmpy2.exe,要求輸出'you are right!'

參考Solving a PyInstaller-compiled crackme

https://hshrzd.wordpress.com/2018/01/26/solving-a-pyinstaller-compiled-crackme/(上面鏈接的pyc版本較老,pyc頭部缺少8個字節,而下面的cmpy2裏面的pyc則缺12字節)在windows操作系統下運行cmpy2.exe,要求輸出'you are right!'代表成功。

Step1:解析exe文件

使用工具pyinstxtractor,指令爲:python pyinstxtractor.py cmpy2.exe。

輸出結果如下:

Step2:修復crackme2文件

解析了cmpy2.exe這個文件後,會生成很多文件模塊,這裏就有一個名爲crackme2的文件。這個文件頭部缺了12字節。我們只需將正常的pyc文件的前12字節,複製到crackme2的頭部,然後將其另存爲pyc文件,即可實現修復。

Step3:反編譯pyc文件

在線反彙編:http://tools.bugscaner.com/decompyle/

Step4:攻擊

由反彙編的代碼可以看出,只要我們第一次輸入def,第二次輸入1313,程序就能輸出'you are right!'。

運行結果:

 

5、(選做)crackme文件拷貝進seed虛擬機運行,要求輸出'Congratulations!'代表成功。

Step1:反彙編crackme

使用IDApro7反彙編crackme,很容易找到這個和明顯同密碼有關的函數,仔細觀察其僞代碼,我們可以做出如下分析:

以上分析中有三點需要注意:

①for ( i = 0; v10[i]; ++i ); v1 = i == 19;這兩句話如何理解?這裏其實是計算v10的長度,若爲19則v1爲true。主要指明密碼長度爲19位。

②v5 = byte_804869C[v3];中數組byte_804869C具體是多少?我們可以進一步查看該數組:

這裏具體指明瞭該數組中的20個數據,要注意的是數據在內存中的儲存方式,例如0E8D40F58h應爲0x58,0x0F,0xD4,0xE8。

③若要輸出Congratulations則要保持v1爲true,那麼就要保持等式v5=v6^v4始終成立。

Step2:求解密碼

現在我們的目的是解密出密碼,密碼是v10,而v10唯一的利用之處就是被賦值給了v6,所以也就是說如果我們找到v6的所有解則找到了最終密碼。而v6可以根據等式v5=v6^v4計算,即v6=v5^v4,而v5和v4都是可以通過反彙編出的僞代碼知曉的。根據以上分析,編寫代碼如下:

#include<stdio.h>
#include<stdlib.h>
int main()
{
	int i;
	bool v1;
	signed int v2;
	int v3;
	int v4;
	char v5;
	char v6;
	int v7;
	int result;
	int v9;
	char v10[124];

	for (i = 0; v10[i]; ++i);
	v1 = i == 19;
	//數組byte_804869C
	int SS[20] = { 0x6A,0xFB,0x4C,0x8D,0x58,0x0F,0xD4,0xE8,0x94,0x98,0xEE,0x6B,0x18,0x30,0xE0,0x55,0xC5,0x28,0x0E,0x90 };

	printf("密碼:");
	for (i = 0; i < 19; i++)
	{
		v3 = i;
		v4 = 0;
		v5 = SS[v3];

		v9 = v3 + 1;
		v7 = 0;
		while (v7 < v9)
		{
			++v7;
			v4 = 1828812941 * v4 + 12345;
		}
		//v6=v5^v4
		unsigned __int8 aaa = (unsigned __int8)v5;
		unsigned __int8 bbb = (unsigned __int8)v4;
		printf("%c", aaa ^ bbb);
	}
	printf("\n");
	return 0;
}

運行結果:

輸出內容:

密碼:SesameOpenYourself!

Step3:驗證

在虛擬機中運行crackme,輸入求得的密碼,成功輸出'Congratulations!'

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章