欢迎来到 黑吧安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

分析BSidesSF CTF 2020中Crypto方向题目

来源:本站整理 作者:佚名 时间:2020-03-18 TAG: 我要投稿


 
前言
在BSidesSF CTF 2020中有9道Crypto相关的题目,题目整体难度适中,在这里对这9道题目进行一下分析。
 
chameleon
题目描述:Somebody encrypted our flag and lost the key! Can you decrypt it? We’ve included the encryption utility, it should come in handy!Note: The file was encrypted in the past few months. We don’t have a more specific date.
题目附件:chameleon.exeflag.png.enc
用IDA加载本题的exe程序,发现程序去除了符号表,在main函数的最后可以找到encrypt和decrypt函数,我们跟进encrypt函数看一下:
void __usercall sub_401FC0(const CHAR *a1@)
{
  void *v1; // eax
  BYTE *v2; // esi
  FILE *v3; // eax
  DWORD pdwDataLen; // [esp+4h] [ebp-2Ch]
  HCRYPTKEY phKey; // [esp+8h] [ebp-28h]
  HCRYPTPROV phProv; // [esp+Ch] [ebp-24h]
  BYTE pbData; // [esp+10h] [ebp-20h]
  char v8; // [esp+11h] [ebp-1Fh]
  __int16 v9; // [esp+12h] [ebp-1Eh]
  int v10; // [esp+14h] [ebp-1Ch]
  int v11; // [esp+18h] [ebp-18h]
  int v12; // [esp+1Ch] [ebp-14h]
  int v13; // [esp+20h] [ebp-10h]
  int v14; // [esp+24h] [ebp-Ch]
  int v15; // [esp+28h] [ebp-8h]
  v1 = (void *)sub_401EA0(&pdwDataLen);
  v2 = (BYTE *)realloc(v1, pdwDataLen + 16);
  if ( !CryptAcquireContextA(&phProv, 0, "Microsoft Enhanced Cryptographic Provider v1.0", 1u, 0xF0000000) )
    goto LABEL_9;
  sub_401A10((int)&v14);
  v9 = 0;
  pbData = 8;
  v11 = 8;
  v12 = v14;
  v13 = v15;
  v8 = 2;
  v10 = 26113;
  if ( !CryptImportKey(phProv, &pbData, 0x14u, 0, 1u, &phKey)
    || !CryptEncrypt(phKey, 0, 1, 0, v2, &pdwDataLen, pdwDataLen + 8) )
  {
LABEL_9:
    v3 = _iob_func();
    fprintf(v3 + 2, "Encryption failedn");
    exit(1);
  }
  sub_401AA0((int)&v14);
  sub_401F50(a1, v2, pdwDataLen);
  free(v2);
}
可以看到程序调用了CryptAcquireContextA、CryptImportKey、CryptEncrypt等API,查阅API手册可以看到这里程序使用DES-CBC进行加密,key来自sub_401A10函数,那么我们接下来跟进sub_401A10函数来看一下:
char __usercall sub_401A10@(int a1@)
{
  __time64_t v1; // rax
  signed int v2; // ecx
  unsigned int v3; // esi
  v1 = time64(0);
  v2 = 0;
  do
  {
    LODWORD(v1) = 29945647 * v1 - 1;
    dword_404380[v2++] = v1;
  }
  while ( v2 351 );
  dword_404018 = v2;
  v3 = 0;
  do
  {
    LOBYTE(v1) = sub_401870(v2, HIDWORD(v1)) ^ 0x55;
    *(_BYTE *)(v3++ + a1) = v1;
  }
  while ( v3 8 );
  return v1;
}
这里看到v1 = time64(0),结合题目描述,看起来像是使用系统时间在设置种子,第一个循环根据种子来设置数组,我们继续跟进sub_401870函数来看一下:
int sub_401870()
{
  int v0; // eax
  int v1; // eax
  unsigned int *v2; // ecx
  unsigned int v3; // esi
  int v4; // eax
  unsigned int v5; // edi
  unsigned int v6; // esi
  int v7; // eax
  unsigned int v8; // esi
  unsigned int v9; // edi
  int v10; // eax
  unsigned int v11; // edi
  unsigned int v12; // esi
  int v13; // eax
  unsigned int v14; // esi
  unsigned int v15; // ecx
  int v16; // ecx
  v0 = dword_404018;
  if ( dword_404018 >= 351 )
  {
    v1 = 175;
    v2 = (unsigned int *)&unk_404384;
    do
    {
      v3 = *v2;
      v4 = v1 + 1;
      *(v2 - 1) = ((*(v2 - 1) ^ (*v2 ^ *(v2 - 1)) & 0x7FFFF) >> 1) ^ dword_40437C[v4] ^ -((*((_BYTE *)v2 - 4) ^ (unsigned __int8)(*(_BYTE *)v2 ^ *((_BYTE *)v2 - 4))) & 1) & 0xE4BD75F5;
      if ( v4 >= 351 )
        v4 = 0;
      v5 = v2[1];
      v6 = ((v3 ^ (v3 ^ v2[1]) & 0x7FFFF) >> 1) ^ dword_404380[v4] ^ -(((unsigned __int8)v3 ^ (unsigned __int8)(v3 ^ *((_BYTE *)v2 + 4))) & 1) & 0xE4BD75F5;
      v7 = v4 + 1;
      *v2 = v6;
      if ( v7 >= 351 )
        v7 = 0;
      v8 = v2[2];
      v9 = ((v5 ^ (v5 ^ v2[2]) & 0x7FFFF) >> 1) ^ dword_404380[v7] ^ -(((unsigned __int8)v5 ^ (unsigned __int8)(v5 ^ *((_BYTE *)v2 + 8))) & 1) & 0xE4BD75F5;

[1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12]  下一页

【声明】:黑吧安全网(http://www.myhack58.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱admin@myhack58.com,我们会在最短的时间内进行处理。
  • 最新更新
    • 相关阅读
      • 本类热门
        • 最近下载