BUUCTF-CrackRTF
1.atoi函数
顾名思义ascii to int 把字符串转化为整型
原理是从字符串第一个数字或正负号开始转换,遇到非数字字符时终止转换
结果返回一个整型。
例子:qwe-1239ii321 结果返回-1239
2.使用CryptoAPI
关键是CryptCreateHash函数的第二个参数代表了加密方式
CryptCreateHash(phProv, 0x8004u, 0, 0, &phHash)
查阅winAPI文档可知道0x8004代表SHA1
int __cdecl sub_401230(BYTE *pbData, DWORD dwDataLen, LPSTR lpString1)
{
int result; // eax
DWORD i; // [esp+4Ch] [ebp-28h]
CHAR String2; // [esp+50h] [ebp-24h]
char v6[20]; // [esp+54h] [ebp-20h]
DWORD pdwDataLen; // [esp+68h] [ebp-Ch]
HCRYPTHASH phHash; // [esp+6Ch] [ebp-8h]
HCRYPTPROV phProv; // [esp+70h] [ebp-4h]
if ( !CryptAcquireContextA(&phProv, 0, 0, 1u, 0xF0000000) )
return 0;//取得密钥容器(CSP)句柄
if ( CryptCreateHash(phProv, 0x8004u, 0, 0, &phHash) )
//创建一个Hash对象(关键)
{
if ( CryptHashData(phHash, pbData, dwDataLen, 0) )
//用用户输入的密码产生一个散列
{
CryptGetHashParam(phHash, 2u, (BYTE *)v6, &pdwDataLen, 0);
*lpString1 = 0;
for ( i = 0; i < pdwDataLen; ++i )
{
wsprintfA(&String2, "%02X", (unsigned __int8)v6[i]);
lstrcatA(lpString1, &String2);
}
CryptDestroyHash(phHash);
CryptReleaseContext(phProv, 0);
result = 1;
}
else
{
CryptDestroyHash(phHash);
CryptReleaseContext(phProv, 0);
result = 0;
}
}
else
{
CryptReleaseContext(phProv, 0);
result = 0;
}
return result;
}
深入了解可以看这篇文章
https://my.oschina.net/kivensoft/blog/549369
3.SHA1暴力破解
穷举所有可能破解
import hashlib
s = '6E32D0943418C2C33385BC35A1470250DD8923A9'.lower()
for i in range(100000,1000000):
a = str(i)+'@DBApp'
m = hashlib.sha1()
m.update(a.encode('utf-8'))
sha1 = m.hexdigest()
if sha1 == s:
print(i)
break
注意s中字符一定要小写!,因为hashlib解密后是小写
或者改为整型比较也可以
4.寻找资源
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");
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);
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”的资源copy到 lpBuffer
然后进行 sub_401005
寻找资源可以利用一个工具ResourceHacker
发现确实有名为"AAA"资源
5.RTF
sub_401005
a2 = (int)lpBuffer , a3 = nNumberOfBytesToWrite
unsigned int __cdecl sub_401420(LPCSTR lpString, int a2, int a3)
{
unsigned int result; // eax
unsigned int i; // [esp+4Ch] [ebp-Ch]
unsigned int v5; // [esp+54h] [ebp-4h]
v5 = lstrlenA(lpString);
for ( i = 0; ; ++i )
{
result = i;
if ( i >= a3 )
break;
*(_BYTE *)(i + a2) ^= lpString[i % v5];
}
return result;
}
sub_401005是将lpBuffer和lpString异或
得到的lpBuffer写入到名为"dbapp.rtf"的文件中
从后缀名知道其为RTF格式
利用lpBuffer是RTF格式反推得到密码
输入密码得到RTF文件,RTF文件有flag
RTF深入学习:https://blog.csdn.net/gongzixiaobai8842/article/details/78317580
4192

被折叠的 条评论
为什么被折叠?



