讚賞碼 & 聯繫方式 & 個人閒話
逆向工程前言
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!'