CTF逆向3

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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值