逆向工程實驗Lab0

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

逆向工程前言

Lab0

1. cipher text

bmjs dtz uqfd ymj lfrj tk ymwtsjx dtz bns tw dtz inj ymjwj nx st rniiqj lwtzsi

代碼:

#include<stdio.h>
#include<string.h>
int main()
{
	//密文
	char cipher[] = "bmjs dtz uqfd ymj lfrj tk ymwtsjx dtz bns tw dtz inj ymjwj nx st rniiqj lwtzsi";
	char clear[100] = { 0 };
	int i;
	//嘗試25種位移量
	for (i = 1; i <= 25; i++)
	{
		memset(clear,0,sizeof(clear));
		int j;
		//對密文逐字符處理
		for (j = 0; j < strlen(cipher); j++)
		{
			int temp = int(cipher[j]);
			//若是小寫字母則進行移位,其他字符不處理
			if (cipher[j] <= 'z'&&cipher[j] >= 'a')
			{
				temp = cipher[j] + i;
				//超過z則從a開始
				if (temp > 'z')
				{
					temp -= 26;
				}
			}
			clear[j] = temp;
		}
		printf("\n偏移量%d: ",i);
		//打印出本次移位解密結果
		for (j = 0; j < strlen(cipher); j++)
		{
			printf("%c", clear[j]);
		}
	}
	return 0;
}

運行結果:

破解出的明文:

when you play the game of thrones you win or you die there is no middle ground.(在權力遊戲中,要麼贏要麼死,沒有中間地帶。)

小結與討論:

上述密文的加密過程使用了凱撒密碼:凱撒密碼的加密原理非常簡單,通過移位,使得每個字母有了一個唯一的加密字母。這種加密方法無法抵抗詞頻分析,暴力攻擊即可破解。所以在對上述密文行破解時,我們通過編程將移位密碼所有移位位數的可能性結果全部列出,可以發現在第21次解密即當移位位數爲5時可以得到句義完整的明文。

 

2. cipher text

"ryf utxy?"

"ryf utxy," orqf jhqihu. "nx nqww urwz! ax bhgo roogix, trouqyvo - utxix qo yhutqyv oh fryvxihgo chi rylhyx nth tro ohdxutqyv uh tqfx ro ehybxioruqhy! ojxxet, oh r nqox hwf cixyetdry orqf uh dx hyex, qo ry qybxyuqhy hc dry'o uh jixbxyu tqd cihd utqyzqyv. qu qo rwoh ry qycrwwqswx dxryo hc fqoehbxiqyv utru ntqet tx nqotxo uh tqfx. r tgdry sxqyv, trouqyvo, eryyhu ixoqou utx hjjhiugyqul uh ixbxrw tqdoxwc ryf xpjixoo tqo jxiohyrwqul ntqet ehybxioruqhy vqbxo tqd. xbxil uqdx tx nqww vqbx tqdoxwc rnrl."

"ntru fh lhg xpjxeu egou uh uxww lhg?"

txiegwx jhqihu odqwxf.

"r wqx," tx orqf. "ryf sl qu, q otrww zyhn utx uigut!"

代碼:

#include<stdio.h>
#include<string.h>
int main() 
{
	//密文
	char cipher[] = "ryf utxy?ryf utxy,orqf jhqihu.nx nqww urwz! ax bhgo roogix, trouqyvo - utxix qo yhutqyv ohfryvxihgo chi rylhyx nth tro ohdxutqyv uh tqfx ro ehybxioruqhy! ojxxet, oh r nqox hwf cixyetdry orqf uh dx hyex, qo ry qybxyuqhy hc dry'o uh jixbxyu tqd cihd utqyzqyv. qu qo rwoh ry qycrwwqswx dxryo hc fqoehbxiqyv utru ntqet tx nqotxo uh tqfx. r tgdry sxqyv, trouqyvo, eryyhu ixoqou utx hjjhiugyqul uh ixbxrw tqdoxwc ryf xpjixoo tqo jxiohyrwqul ntqet ehybxioruqhy vqbxo tqd. xbxil uqdx tx nqww vqbx tqdoxwc rnrl.ntru fh lhg xpjxeu egou uh uxww lhg?txiegwx jhqihu odqwxf.r wqx,tx orqf.ryf sl qu, q otrww zyhn utx uigut!";
	int i;
	//統計頻數
	int a[26][3];
	for (int i = 0; i < 26; i++) {
		a[i][1] = 0;
		a[i][2] = i;
	}
	for (int i = 0; i < strlen(cipher); i++) {
		if (cipher[i] >= 97 && cipher[i] <= 122) {
			a[(cipher[i] - 97)][1]++;
		}
	}
	int  j, tmp1, tmp2;
	for (i = 0; i < 25; i++) {
		for (j = 0; j < 25 - i; j++) {
			if (a[j][1] > a[j + 1][1]) {
				tmp1 = a[j][1];
				tmp2 = a[j][2];
				a[j][1] = a[j + 1][1];
				a[j][2] = a[j + 1][2];
				a[j + 1][1] = tmp1;
				a[j + 1][2] = tmp2;
			}
		}
	}

	int b[26][2];
	for (i = 0; i < 25; i++) {
		b[i][1] = a[i][2];
	}
	//輸出頻數
	char d[26];
	printf("字符:");
	for (i = 0; i < 26; i++) {
		printf("%2c ", a[i][2] + 97);
		d[i] = a[i][2] + 97;
	}
	printf("\n頻數:");
	for (i = 0; i < 26; i++) {
		printf("%2d ", a[i][1]);
	}

	//嘗試不同的替換方式
	char c[] = "zqjxkvbpgywmfcudlhrsnioate";
	//char dd[] = "kmapszcljbgvnedfiwtrhuyoqx";
	//char dd[] = "kmapszcljbdvnegfwtioyqhrux";
	char dd[] = "kmapzbsjvlndcegfwtioyqhrux";
	printf("\n");

	//進行替換
	for (i = 0; i < strlen(cipher); i++) {
		for (j = 0; j < 26; j++) {
			if (cipher[i] == dd[j]) {
				cipher[i] = c[j];
				break;
			}
		}
	}

	//輸出明文
	printf("\n明文:\n");
	for (i = 0; i < strlen(cipher); i++) {
		printf("%c", cipher[i]);
	}
	printf("\n");

	return 0;
}

運行結果:

破解出的明文:

and then?and then,said poirot.we will talk! je vous assure, hastings - there is nothing sodangerous for anyone who has something to hide as conversation! speech, so a wise old frenchman said to me once, is an invention of man's to prevent him from thinking. it is also an infallible means of discovering that which he wishes to hide. a human being, hastings, cannot resist the opportunity to reveal himself and express his personality which conversation gives him. every time he will give himself away.what do you expect cust to tell you?hercule poirot smiled.a lie,he said.and by it, i shall know the truth!

小結與討論:

上述密文的加密過程使用了較複雜的替換密碼:對字母表中的每一個字母用其他的唯一的不同的一個密文字母代替,即在明文x與密文y之間建立一對一的映射。本題明文與密文的映射函數並不是簡單的一次函數,所以需要根據字母或字母組合在密文片段中出現的頻率先進行部分猜測。在破解明文時,我們首先通過編程計算出字母出現的頻率,並將字母按頻率從小到大的順序依次輸出。對照英文字母頻率表,猜測出密文字母”x”出現頻率最高可能對應明文字母”e”。字母組合”utx”、”tx”、以及字母”r”、”q”在英文語段中特殊的用法等幫助我們逐步確定明文和密文之間的替換表,並通過程序一一檢驗不同的替換方式,最終破解出完整的明文。

 

3. Vigenere cipher text

Ivikdkdqmjglpwlzgmpfbjiidbbysljdxfgbiwwehapheysgnccyootstzabcobvrtazeywvwwazaidgazpethpvbpwobvjxgfmdobcgpfkxkszzaigcjrpetacjhuthpvhkjhpzhfpmevzeqsbyomhsdvftasfgztcobzcghfmdobcwvnvbrvkrgxdbmkfbtgbvgmptbvfmtgblbmxzweshgcbyskdtbysfwoarqhcjqeqbcuidcnchwwgnedwihptkqczgdkigdenhpzgigwvtwiasbfhatqijsbcdwzbmpgqkkthtqigmefmjsgislkcfthpvfxlszvhagsmgclhwjcsxmdtrbtiwweghuhpvgxrzcjwhcczzbvpfkvftiwwecyivqjuxchtvatcwvrbhjhpfiltcnywluobyskhaiegbdbbysktkijhatsfgztcobzcgivikvxloazbaxrqeuydfitfbbswihaphpvkthaiuogshprhmwsgnwlwslkctkcquogpggcifdfbyomwsprrldamuwltoavkaxqptonhslywlhsoiszphqfbbrcccrmwwvbcyccwkvxgolvenphmjcejhqfblivmjsmwsvyowicjvgbuhmuogspicogrslrutxbakstrvwkvxg

代碼:

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

int main() {
	char cipher[] = "ivikdkdqmjglpwlzgmpfbjiidbbysljdxfgbiwwehapheysgnccyootstzabcobvrtazeywvwwazaidgazpethpvbpwobvjxgfmdobcgpfkxkszzaigcjrpetacjhuthpvhkjhpzhfpmevzeqsbyomhsdvftasfgztcobzcghfmdobcwvnvbrvkrgxdbmkfbtgbvgmptbvfmtgblbmxzweshgcbyskdtbysfwoarqhcjqeqbcuidcnchwwgnedwihptkqczgdkigdenhpzgigwvtwiasbfhatqijsbcdwzbmpgqkkthtqigmefmjsgislkcfthpvfxlszvhagsmgclhwjcsxmdtrbtiwweghuhpvgxrzcjwhcczzbvpfkvftiwwecyivqjuxchtvatcwvrbhjhpfiltcnywluobyskhaiegbdbbysktkijhatsfgztcobzcgivikvxloazbaxrqeuydfitfbbswihaphpvkthaiuogshprhmwsgnwlwslkctkcquogpggcifdfbyomwsprrldamuwltoavkaxqptonhslywlhsoiszphqfbbrcccrmwwvbcyccwkvxgolvenphmjcejhqfblivmjsmwsvyowicjvgbuhmuogspicogrslrutxbakstrvwkvxg";
	int len, sum, sum2 = 0;

	int i, j;

	//錯位值爲i時,相同字符的數目
	for (i = 1; i < 10; i++) {
		sum = 0;
		for (j = 0; j < strlen(cipher); j++) {
			if (i + j < strlen(cipher)) {
				if (cipher[j] == cipher[i + j])
					sum++;
			}
			else {
				if (cipher[j] == cipher[strlen(cipher) - i - j])
					sum++;
			}
		}
		if (sum2 < sum) {
			sum2 = sum;
			len = i;
		}
		printf("移位%d的字符相同數:%d\n", i, sum);
	}
	printf("所以,密鑰的長度爲:%d\n\n\n", len);  //相同字符數目最多對應的錯位值i,即爲密鑰的長度

	int count[6][26] = { 0 };
	char count2[6][27];

	//初始化,每個count2[i]都爲abcdefghijklmnopqrstuvwxyz
	for (i = 0; i < 6; i++) {
		strcpy_s(count2[i], 27, "abcdefghijklmnopqrstuvwxyz");
	}

	int k;

	//由密鑰第i項加密的字母的頻度
	for (i = 0; i < 6; i++) {
		for (j = i; j < strlen(cipher); j = j + 6) {
			count[i][cipher[j] - 97]++;
		}
	}


	char ctmp;
	int tmp;

	//冒泡排序
	for (i = 0; i < 6; i++) {
		for (j = 0; j < 25; j++) {
			for (k = 0; k < 25 - j; k++) {
				if (count[i][k] > count[i][k + 1]) {
					tmp = count[i][k];
					ctmp = count2[i][k];
					count[i][k] = count[i][k + 1];
					count2[i][k] = count2[i][k + 1];
					count[i][k + 1] = tmp;
					count2[i][k + 1] = ctmp;
				}
			}
		}
	}

	for (i = 0; i < 6; i++) {
		printf("由密鑰第%d項加密的字母的頻度:\n", i + 1);
		for (j = 0; j < 26; j++) {
			printf("%d%c  ", count[i][j], count2[i][j]);
		}
		printf("\n\n");
	}

	//對應的映射關係,一般來說,頻度最高的字母對應的是e
	//t----e  p
	//s----e  o
	//m----e  i
	//v----e  r
	//s----e  o
	//x----e  t
	printf("\n映射關係:\n");
	printf("t----e  p\n");
	printf("s----e  o\n");
	printf("m----e  i\n");
	printf("v----e  r\n");
	printf("s----e  o\n");
	printf("x----e  t\n\n");

	//利用密鑰解密
	for (i = 0; i < 6; i++) {
		for (j = i; j < strlen(cipher); j = j + 6) {
			switch (i) {
			case 0:
				cipher[j] = (cipher[j] - 97 - 15 + 26) % 26 + 97;
				break;
			case 1:
				cipher[j] = (cipher[j] - 97 - 14 + 26) % 26 + 97;
				break;
			case 2:
				cipher[j] = (cipher[j] - 97 - 8 + 26) % 26 + 97;
				break;
			case 3:
				cipher[j] = (cipher[j] - 97 - 17 + 26) % 26 + 97;
				break;
			case 4:
				cipher[j] = (cipher[j] - 97 - 14 + 26) % 26 + 97;
				break;
			case 5:
				cipher[j] = (cipher[j] - 97 - 19 + 26) % 26 + 97;
				break;
			}
		}
	}
	printf("明文爲:\n");
	for (i = 0; i < strlen(cipher); i++) {
		printf("%c", cipher[i]);
	}

	printf("\n");
}

運行結果:

破解出的明文:

Thatprocesssaidistartsuponthesuppositionthatwhenyouhaveeliminatedallwhichisimpossiblethenwhateverremainshoweverimprobablemustbethetruthitmaywellbethatseveralexplanationsremaininwhichcaseonetriestestaftertestuntiloneorotherofthemhasaconvincingamountofsupportwewillnowapplythisprincipletothecaseinpointasitwasfirstpresentedtometherewerethreepossibleexplanationsoftheseclusionorincarcerationofthisgentlemaninanouthouseofhisfathersmansiontherewastheexplanationthathewasinhidingforacrimeorthathewasmadandthattheywishedtoavoidanasylumorthathehadsomediseasewhichcausedhissegregationicouldthinkofnootheradequatesolutionsthesethenhadtobesiftedandbalancedagainsteachother

小結與討論:

上述密文的加密過程使用了維吉尼亞密碼:維吉尼亞密碼是一種典型的多表替換密碼,可以看成是使用一系列不同移位的凱撒密碼組成的密碼方案,這樣的加密過程中可能會出現同一個明文字母對應多個密文字母或者多個明文字母對應同一個密文字母的情況。破解維吉尼亞密碼的關鍵是要先獲取密鑰長度:編程選取不同的移位值比較得出在移動多少位置時具有最多的字符相同數。由輸出結果可以看出,當移動6個位置時具有最多的相同數,故移位值6就是最可能的密鑰長度值。然後我們需要獲取密鑰值:觀察第1、第7、第13個......字母,即由密鑰第一項元素加密的這些字母,看哪一個字母出現的頻率最高則最可能代替明文中的字母e。重複上述過程我們可以依次找到其他5組的密鑰即移位數,得到最後的密鑰猜想:p o i r o t。

維吉尼亞密碼加密有自己優勢:在一定程度上改變了密文字母的頻率,採用了密鑰在明文上重複書寫的原理,這樣一個字母可能對應多個替換即多表替換而非一對一的字符替換。但是隻要密文足夠多,就可以生成合理的統計樣本,維吉尼亞密碼依然可以通過頻率分析被破解。

 

4.Rar file without password

代碼:

import binascii
import string
tmp=string.printable     #各種打印字符
crc = 0x05665E74   #文件的CRC,0x開頭

#文件的內容爲3位,所以三層循環遍歷
for i in tmp :
    for j in tmp:
        for k in tmp:
            s=str(i)+str(j)+str(k)

            #將其轉爲無符號整數,與文件的crc比較
            if crc == ((binascii.crc32(bytes(s,'UTF-8'))) & 0xffffffff):

               print("內容:"+s)    #打印文件內容

運行結果:

破解出的文件內容:

文件內容:77%

小結與討論:

主要思想:每個不同的文件都有唯一的CRC32值。對於內容相同的文件,它們的CRC32值是一樣的。所以我們可以根據CRC32值,暴力破解文件的內容,而無需知道壓縮密碼。

破解步驟:

Step 1: 獲知文件內容的長度

用WinRAR打開壓縮文件,裏面會顯示文件內容的長度:

從截圖中紅色方框的內容可以看出,文件內容由三個字符組成。

Step 2: 暴力破解文件的內容

文件內容只有三個字符,我們只要將所有可能的情況列出來,將其CRC32值與壓縮文件比較。一旦相同,就表明這三個字符就是文件的內容。

由此我們藉助編程破解得到了rate.txt文件的內容。

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