逆向初学者做题记录3.28
[ACTF新生賽2020]rome
查殼
ida打開,通過字符窗口(按shift+F12)找可疑字符
int func() {int result; // eaxint v1; // [esp+14h] [ebp-44h]int v2; // [esp+18h] [ebp-40h]int v3; // [esp+1Ch] [ebp-3Ch]int v4; // [esp+20h] [ebp-38h]unsigned __int8 v5; // [esp+24h] [ebp-34h]unsigned __int8 v6; // [esp+25h] [ebp-33h]unsigned __int8 v7; // [esp+26h] [ebp-32h]unsigned __int8 v8; // [esp+27h] [ebp-31h]unsigned __int8 v9; // [esp+28h] [ebp-30h]int v10; // [esp+29h] [ebp-2Fh]int v11; // [esp+2Dh] [ebp-2Bh]int v12; // [esp+31h] [ebp-27h]int v13; // [esp+35h] [ebp-23h]unsigned __int8 v14; // [esp+39h] [ebp-1Fh]char v15; // [esp+3Bh] [ebp-1Dh]char v16; // [esp+3Ch] [ebp-1Ch]char v17; // [esp+3Dh] [ebp-1Bh]char v18; // [esp+3Eh] [ebp-1Ah]char v19; // [esp+3Fh] [ebp-19h]char v20; // [esp+40h] [ebp-18h]char v21; // [esp+41h] [ebp-17h]char v22; // [esp+42h] [ebp-16h]char v23; // [esp+43h] [ebp-15h]char v24; // [esp+44h] [ebp-14h]char v25; // [esp+45h] [ebp-13h]char v26; // [esp+46h] [ebp-12h]char v27; // [esp+47h] [ebp-11h]char v28; // [esp+48h] [ebp-10h]char v29; // [esp+49h] [ebp-Fh]char v30; // [esp+4Ah] [ebp-Eh]char v31; // [esp+4Bh] [ebp-Dh]int i; // [esp+4Ch] [ebp-Ch]v15 = 81;v16 = 115;v17 = 119;v18 = 51;v19 = 115;v20 = 106;v21 = 95;v22 = 108;v23 = 122;v24 = 52;v25 = 95;v26 = 85;v27 = 106;v28 = 119;v29 = 64;v30 = 108;v31 = 0;printf("Please input:");scanf("%s", &v5);result = v5;if ( v5 == 65 ){result = v6;if ( v6 == 67 ){result = v7;if ( v7 == 84 ){result = v8;if ( v8 == 70 ){result = v9;if ( v9 == 123 ){result = v14;if ( v14 == 125 ){v1 = v10;v2 = v11;v3 = v12;v4 = v13;for ( i = 0; i <= 15; ++i ){if ( *((_BYTE *)&v1 + i) > 64 && *((_BYTE *)&v1 + i) <= 90 )// 對大寫的字母進行下面的加密*((_BYTE *)&v1 + i) = (*((char *)&v1 + i) - 51) % 26 + 65;if ( *((_BYTE *)&v1 + i) > 96 && *((_BYTE *)&v1 + i) <= 122 )// 對小寫的字母進行下面的加密*((_BYTE *)&v1 + i) = (*((char *)&v1 + i) - 79) % 26 + 97;}for ( i = 0; i <= 15; ++i ){result = (unsigned __int8)*(&v15 + i);if ( *((_BYTE *)&v1 + i) != (_BYTE)result )return result;}result = printf("You are correct!");}}}}}}return result; }在寫腳本的時候,一定要注意取余運算,這個運算在逆向的時候比較麻煩,比較好的方法是枚舉,
觀察這個取余運算的數,65(A的ASCII碼)、97(a的ASCII碼)、26,不難想到,實質上就是對字母進行偏移;然后再看51和79,都是26的倍數加或減1;也可以直接打開這個括號,再進行運算。那么這個取余運算的作用也比較容易理解,下面是代碼:
decry = "Qsw3sj_lz4_Ujw@l" v = list(decry)for i in range(16):if ord(v[i])>64 and ord(v[i])<=90:v[i] = chr(ord(v[i])-65+51) if (ord(v[i])-65+51) > 64 else chr(ord(v[i])-65+26+51)if ord(v[i]) > 96 and ord(v[i]) <= 122:v[i] = chr(ord(v[i]) - 97 + 79) if (ord(v[i])-97+79) > 96 else chr(ord(v[i])-97+26+79)print("".join(v))flag{Cae3ar_th4_Gre@t}
[FlareOn4]login
下載有兩個文件,文本文件沒什么用,看網頁
源代碼里有用的是下面這段代碼
document.getElementById("prompt").onclick = function () {var flag = document.getElementById("flag").value;var rotFlag = flag.replace(/[a-zA-Z]/g, function(c){return String.fromCharCode((c <= "Z" ? 90 : 122) >= (c = c.charCodeAt(0) + 13) ? c : c - 26);});if ("PyvragFvqrYbtvafNerRnfl@syner-ba.pbz" == rotFlag) {alert("Correct flag!");} else {alert("Incorrect flag, rot again");}}replace的第一個參數,/[a-zA-Z]/g??這部分是正則表達式,相關內容可參考https://www.runoob.com/regexp/regexp-syntax.html
replace的第二個參數,是一個函數,也就是將輸入的字符串的所有字符,進行這個函數的加密
加密后的字符串是"PyvragFvqrYbtvafNerRnfl@syner-ba.pbz"?
.charCodeAt(i) 方法是返回字符串的第i個字符的Unicode編碼(i從0算起)
.fromCharCode() 方法是將一個Unicode編碼轉換成對應的字符
實質上就是對字符串進行偏移,偏移量為固定的13。。ROT13加密
flag{ClientSideLoginsAreEasy@flare-on.com}
CrackRTF
哈希
首先了解一下關于哈希(Hash):
哈希(Hash)是將任意長度的數據映射到固定長度的數據的過程,被映射后的數據稱為哈希值(Hash Value)。哈希函數是實現哈希的算法,它可以將輸入數據(也稱為消息)轉換為哈希值。哈希值具有以下特點:
固定長度:無論輸入數據的大小,哈希值的長度都是固定的。
唯一性:哈希函數將不同的輸入數據映射到不同的哈希值,因此不同的輸入數據生成的哈希值是唯一的。
散列性:哈希函數應該具有很高的散列性,即對于微小的輸入數據變化,生成的哈希值應該有很大的差異,從而使哈希值更難以被預測或攻擊者更難以針對性地構造相同的哈希值。
不可逆性:哈希函數應該是單向的,即無法通過哈希值還原出原始數據。
哈希值在密碼學中廣泛應用,例如數字簽名、消息認證和數據完整性驗證。在網絡安全中,哈希函數也被用于驗證文件的完整性和防止篡改,例如文件校驗和和數字指紋。
一些常用的哈希函數包括:MD5、SHA-1、SHA-2 和 SHA-3。需要注意的是,隨著計算機計算能力的不斷提高,一些早期的哈希函數,如 MD5 和 SHA-1,已經被認為不再安全,建議使用更安全的哈希函數。
不同哈希函數簡介
MD5:輸出長度為128位的散列值。由于其輸出長度較短,MD5易于被暴力破解。因此,MD5已經不再被推薦用于安全加密。
SHA-1:輸出長度為160位的散列值。SHA-1的安全性也被認為不足,容易受到碰撞攻擊。因此,SHA-2和SHA-3等更強大的哈希函數已被推薦用于安全加密。
SHA-2:SHA-2系列包括SHA-224、SHA-256、SHA-384和SHA-512,分別輸出長度為224、256、384和512位的散列值。SHA-2相對于MD5和SHA-1更加安全,被廣泛使用于安全加密領域。
SHA-3:SHA-3是NIST于2012年發布的新一代哈希函數標準。SHA-3與SHA-2不同的是,它采用了基于置換的架構,具有更好的安全性和效率。
BLAKE2:BLAKE2是一種高速哈希函數,輸出長度可以從1到512位不等。它比SHA-3和SHA-2更快,也被廣泛用于數據完整性校驗和密碼學協議等領域。
這里的散列值相當于一個字節,下面是不同進制的單個字符再計算機里所占內存大小:
二進制:每個二進制字符(0或1)占據1比特位,8個二進制字符組成一個字節。
八進制:每個八進制字符(0-7)占據3比特位,3個八進制字符組成一個字節。
十進制:每個十進制字符(0-9)占據1個字節(8個比特位)。
十六進制:每個十六進制字符(0-9,A-F)占據4比特位,2個十六進制字符組成一個字節。
題目
查殼,32位無殼,IDA32打開,找到main_0,有以下代碼
int __cdecl main_0() {DWORD v0; // eaxDWORD v1; // eaxCHAR String; // [esp+4Ch] [ebp-310h]int v4; // [esp+150h] [ebp-20Ch]CHAR String1; // [esp+154h] [ebp-208h]BYTE pbData; // [esp+258h] [ebp-104h]memset(&pbData, 0, 0x104u);memset(&String1, 0, 0x104u);v4 = 0;printf("pls input the first passwd(1): ");scanf("%s", &pbData);if ( strlen((const char *)&pbData) != 6 ){printf("Must be 6 characters!\n");ExitProcess(0);}v4 = atoi((const char *)&pbData);if ( v4 < 100000 )ExitProcess(0);strcat((char *)&pbData, "@DBApp");v0 = strlen((const char *)&pbData);sub_40100A(&pbData, v0, &String1);if ( !_strcmpi(&String1, "6E32D0943418C2C33385BC35A1470250DD8923A9") ){printf("continue...\n\n");printf("pls input the first passwd(2): ");memset(&String, 0, 0x104u);scanf("%s", &String);if ( strlen(&String) != 6 ){printf("Must be 6 characters!\n");ExitProcess(0);}strcat(&String, (const char *)&pbData);memset(&String1, 0, 0x104u);v1 = strlen(&String);sub_401019((BYTE *)&String, v1, &String1);if ( !_strcmpi("27019e688a4e62a649fd99cadaafdb4e", &String1) ){if ( !sub_40100F(&String) ){printf("Error!!\n");ExitProcess(0);}printf("bye ~~\n");}}return 0; }26行的一串,是40位數字,并且是16進制,那么就是SHA-1加密了
要求兩位6位字符的passwd,先輸入第一段字符,在其后面加上@DBApp,再經過sub_40100A加密;再輸入第二段字符,sub_401019加密,將其拼接在第一段字符的前面;然后整體再加密一次
這里的atoi()函數用于將字符串轉換成整型數
memset()函數:void *memset(void *ptr, int value, size_t num),其中,ptr是指向內存區域的指針,value是要設置的值,num是要設置的字節數。用于將指定內存區域的每個字節都設置成指定的值。
其中,第一段和第二段加密后的字符給出了
那么先來爆破第一段:
import hashlibflag = "@DBApp"for i in range(100000, 1000000):s = str(i)+flagx = hashlib.sha1(s.encode())cnt = x.hexdigest()if "6e32d0943418c2c" in cnt:print(cnt)print(str(i)+flag)由于SHA-1哈希函數只接受字節序列作為輸入,所以需要.encode(),encode()默認為UTF-8
結果123321@DBApp
第二次加密,給出的字符長度有變,是32位,可能是MD5加密,往后看,有個sub_40100F函數,點進去,看到這種字符串,這個函數肯定有用,看起來像從AAA這個文件取出什么東西
進入這個函數,是個異或運算
這里附上一個工具Resource Hacker的官網http://www.angusj.com/resourcehacker/#download,這個工具可以直接查看文件中的資源。
文件.rtf的文件頭固定為{\rtf1\ansi\ansicpg936\deff0\......,取前六位{\rtf1。
所以{\rtf1與AAA中前六個數據異或就行了
結果~!3a@0
寫到這突然不知道接下來要干什么了,這道題對小白來說也算難的了吧
那就運行一下exe,兩次輸入,最后發現dbapp.rtf,
flag{N0_M0re_Free_Bugs}
總結
以上是生活随笔為你收集整理的逆向初学者做题记录3.28的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 实现发送xml格式的请求
- 下一篇: [ICCV 2019] Few-Shot