BUUCTF-RE-CrackRTF
一、查壳
二、IDA分析
1 int __cdecl main_0() 2 { 3 DWORD v0; // eax 4 DWORD v1; // eax 5 CHAR String; // [esp+4Ch] [ebp-310h] 6 int v4; // [esp+150h] [ebp-20Ch] 7 CHAR String1; // [esp+154h] [ebp-208h] 8 BYTE pbData; // [esp+258h] [ebp-104h] 9 10 memset(&pbData, 0, 0x104u); 11 memset(&String1, 0, 0x104u); 12 v4 = 0; 13 printf("pls input the first passwd(1): "); 14 scanf("%s", &pbData); 15 if ( strlen((const char *)&pbData) != 6 ) //first passwd(1) 6个字符 16 { 17 printf("Must be 6 characters!\n"); 18 ExitProcess(0); 19 } 20 v4 = atoi((const char *)&pbData); //atoi()将&pbData转换为一个整数 21 if ( v4 < 100000 ) //first passwd大于100000 22 ExitProcess(0); 23 strcat((char *)&pbData, "@DBApp"); //连接@DBApp到&pbData后面 24 v0 = strlen((const char *)&pbData); 25 sub_40100A(&pbData, v0, &String1); //进入加密函数 下有详细分析 26 if ( !_strcmpi(&String1, "6E32D0943418C2C33385BC35A1470250DD8923A9") ) 27 { 28 printf("continue...\n\n"); 29 printf("pls input the first passwd(2): "); 30 memset(&String, 0, 0x104u); 31 scanf("%s", &String); 32 if ( strlen(&String) != 6 ) //6位密码 33 { 34 printf("Must be 6 characters!\n"); 35 ExitProcess(0); 36 } 37 strcat(&String, (const char *)&pbData); //拼接在&pbData前面 38 memset(&String1, 0, 0x104u); 39 v1 = strlen(&String); 40 sub_401019((BYTE *)&String, v1, &String1); //进入加密函数 下有详细分析 41 if ( !_strcmpi("27019e688a4e62a649fd99cadaafdb4e", &String1) ) 42 { 43 if ( !sub_40100F(&String) )//进入该判断函数 下有详解 44 { 45 printf("Error!!\n"); 46 ExitProcess(0); 47 } 48 printf("bye ~~\n"); 49 } 50 } 51 return 0; 52 }
第25行 进入加密函数 该函数如下
1 int __cdecl sub_401230(BYTE *pbData, DWORD dwDataLen, LPSTR lpString1) 2 { 3 int result; // eax 4 DWORD i; // [esp+4Ch] [ebp-28h] 5 CHAR String2; // [esp+50h] [ebp-24h] 6 BYTE v6[20]; // [esp+54h] [ebp-20h] 7 DWORD pdwDataLen; // [esp+68h] [ebp-Ch] 8 HCRYPTHASH phHash; // [esp+6Ch] [ebp-8h] 9 HCRYPTPROV phProv; // [esp+70h] [ebp-4h] 10 11 if ( !CryptAcquireContextA(&phProv, 0, 0, 1u, 0xF0000000) ) 12 return 0; 13 if ( CryptCreateHash(phProv, 0x8004u, 0, 0, &phHash) ) 14 { 15 if ( CryptHashData(phHash, pbData, dwDataLen, 0) ) 16 { 17 CryptGetHashParam(phHash, 2u, v6, &pdwDataLen, 0); 18 *lpString1 = 0; 19 for ( i = 0; i < pdwDataLen; ++i ) 20 { 21 wsprintfA(&String2, "%02X", v6[i]); 22 lstrcatA(lpString1, &String2); 23 } 24 CryptDestroyHash(phHash); 25 CryptReleaseContext(phProv, 0); 26 result = 1; 27 } 28 else 29 { 30 CryptDestroyHash(phHash); 31 CryptReleaseContext(phProv, 0); 32 result = 0; 33 } 34 } 35 else 36 { 37 CryptReleaseContext(phProv, 0); 38 result = 0; 39 } 40 return result; 41 }
通过函数名猜测 这段加密函数进行的是hash加密 通过hash-identifirt识别类型为sha1
1)通过在线工具查询 解
2)通过python的hashlib包可以进行爆破解密
import hashlib flag2="@DBApp" for i in range(100000,999999): h2 = hashlib.sha1((str(i)+flag2).encode('utf8')) flags = h2.hexdigest() if "6e32d0943418c2c33385bc35a1470250dd8923a9" == flags: print (str(i)+flag2) print (flags)
解出first passwd(1)=123321@DBApp
——————————————————————————————————————————————
第40行进入加密函数 该函数如下
1 int __cdecl sub_401040(BYTE *pbData, DWORD dwDataLen, LPSTR lpString1) 2 { 3 int result; // eax 4 DWORD i; // [esp+4Ch] [ebp-24h] 5 CHAR String2; // [esp+50h] [ebp-20h] 6 BYTE v6[16]; // [esp+54h] [ebp-1Ch] 7 DWORD pdwDataLen; // [esp+64h] [ebp-Ch] 8 HCRYPTHASH phHash; // [esp+68h] [ebp-8h] 9 HCRYPTPROV phProv; // [esp+6Ch] [ebp-4h] 10 11 if ( !CryptAcquireContextA(&phProv, 0, 0, 1u, 0xF0000000) ) 12 return 0; 13 if ( CryptCreateHash(phProv, 0x8003u, 0, 0, &phHash) ) 14 { 15 if ( CryptHashData(phHash, pbData, dwDataLen, 0) ) 16 { 17 CryptGetHashParam(phHash, 2u, v6, &pdwDataLen, 0); 18 *lpString1 = 0; 19 for ( i = 0; i < pdwDataLen; ++i ) 20 { 21 wsprintfA(&String2, "%02X", v6[i]); 22 lstrcatA(lpString1, &String2); 23 } 24 CryptDestroyHash(phHash); 25 CryptReleaseContext(phProv, 0); 26 result = 1; 27 } 28 else 29 { 30 CryptDestroyHash(phHash); 31 CryptReleaseContext(phProv, 0); 32 result = 0; 33 } 34 } 35 else 36 { 37 CryptReleaseContext(phProv, 0); 38 result = 0; 39 } 40 return result; 41 }
跟第一部分一样是hash加密 用hash-identifirt识别类型 为 MD5 但是一番尝试解不出 先跳过去接着看
进入判断函数
char __cdecl sub_4014D0(LPCSTR lpString) { LPCVOID lpBuffer; // [esp+50h] [ebp-1Ch] DWORD NumberOfBytesWritten; // [esp+58h] [ebp-14h] DWORD nNumberOfBytesToWrite; // [esp+5Ch] [ebp-10h] HGLOBAL hResData; // [esp+60h] [ebp-Ch] HRSRC hResInfo; // [esp+64h] [ebp-8h] HANDLE hFile; // [esp+68h] [ebp-4h] hFile = 0; hResData = 0; nNumberOfBytesToWrite = 0; NumberOfBytesWritten = 0; hResInfo = FindResourceA(0, (LPCSTR)0x65, "AAA");//FindResourceA()查找资源 if ( !hResInfo ) return 0; nNumberOfBytesToWrite = SizeofResource(0, hResInfo); hResData = LoadResource(0, hResInfo); if ( !hResData ) return 0; lpBuffer = LockResource(hResData); sub_401005(lpString, (int)lpBuffer, nNumberOfBytesToWrite);//lpBuffer在函数里就是a2 hFile = CreateFileA("dbapp.rtf", 0x10000000u, 0, 0, 2u, 0x80u, 0); if ( hFile == (HANDLE)-1 ) return 0; if ( !WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, &NumberOfBytesWritten, 0) ) return 0; CloseHandle(hFile); return 1; }
通过一系列函数名猜操作 找到一个叫“AAA”的资源 加载"AAA"文件内的内容进入sub_401005函数
之后在sub_401005函数操作后创建“dapp.rtf”
sub_401005函数如下
1 unsigned int __cdecl sub_401420(LPCSTR lpString, int a2, int a3) 2 { 3 unsigned int result; // eax 4 unsigned int i; // [esp+4Ch] [ebp-Ch] 5 unsigned int v5; // [esp+54h] [ebp-4h] 6 7 v5 = lstrlenA(lpString); 8 for ( i = 0; ; ++i ) 9 { 10 result = i; 11 if ( i >= a3 ) 12 break; 13 *(_BYTE *)(i + a2) ^= lpString[i % v5]; //进行按位异或 14 } 15 return result; 16 }
a2就是AAA中的数据内容
用Resource Hacker工具获取AAA数据内容
我们第二部分的密码是六位数
而后在sub_401005函数的xor操作后创建“dapp.rtf”
所以我们推测RTF文件格式的前六位与AAA文件的前六位异或之后,将会得到我们的密码
新建RTF文档查看基本文件头
RTF文件的文件头前6位基本是固定的 为 {\rtf1
通过脚本将他们异或
key = [0x05,0x7D,0x41,0x15,0x26,0x01] key1="{\\rtf1" flag = '' for i in range(0,5): x=ord(key1[i])^key[i] flag+=chr(x) print(flag)
解出第二部分为 ~!3a@
还差一位密码 利用脚本爆破
from hashlib import md5 key1="123321@DBApp" key2 ="~!3a@" for i in range(33,127): h=md5((key2+chr(i)+key1).encode('utf8')) flags=h.hexdigest() if "27019e688a4e62a649fd99cadaafdb4e" in flags: print (key2+chr(i)+key1) print (flags)
解出完整密码~!3a@0123321@DBApp
运行程序输入密码 (1)123321 (2)~!3a@0
在该程序的文件夹里会出现一个RTF文件,文件内容即为flag
三、flag
Flag{N0_M0re_Free_Bugs}
文章参考:https://www.b1ndsec.cn/?p=76
https://www.52pojie.cn/thread-994588-1-1.html