[LitCTF 2023]debase64 WP

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int res[4]; // [esp+10h] [ebp-44h] BYREF
  char v5; // [esp+20h] [ebp-34h]
  __int16 v6; // [esp+21h] [ebp-33h]
  __int16 v7; // [esp+23h] [ebp-31h]
  __int16 v8; // [esp+25h] [ebp-2Fh]
  __int16 v9; // [esp+27h] [ebp-2Dh]
  __int16 v10; // [esp+29h] [ebp-2Bh]
  __int16 v11; // [esp+2Bh] [ebp-29h]
  __int16 v12; // [esp+2Dh] [ebp-27h]
  char input[20]; // [esp+3Ch] [ebp-18h] BYREF

  sub_402290();
  puts("请开始你的表演");
  memset(res, 0, 15);
  memset(input, 0, sizeof(input));
  scanf("%s", input);
  if ( strlen(input) != 20 )                    // 长度为20
  {
    puts("长度不对哦");
    return 0;
  }
  v5 = 0x46;
  v6 = 0x18ED;
  v7 = 0x5696;
  v8 = 0xD29E;
  v9 = 0xB272;
  v10 = 0x80B3;
  v11 = 0xFF70;
  v12 = 0;
  base64_decode(input, res);
  if ( v5 != LOBYTE(res[0])
    || v6 != *(_WORD *)((char *)res + 1)
    || v7 != *(_WORD *)((char *)res + 3)
    || v8 != *(_WORD *)((char *)&res[1] + 1)
    || v9 != *(_WORD *)((char *)&res[1] + 3)
    || v10 != *(_WORD *)((char *)&res[2] + 1)
    || v11 != *(_WORD *)((char *)&res[2] + 3)
    || v12 != *(_WORD *)((char *)&res[3] + 1) )
  {
    puts("不对哦");
    return 0;
  }
  return puts("恭喜你答对啦");
}

在这里插入图片描述

  • 分析主函数,按tab查看v5-v12赋值情况

int __cdecl base64_decode(_BYTE *input, char *res)
{
  _BYTE *input_4; // ebp
  _BYTE *input_; // ecx
  int v4; // ebx
  int v5; // eax
  int i; // edx
  _BYTE *input_3; // edx
  int j; // ecx
  _BYTE *v9; // ecx
  int k; // ebx
  int v12; // [esp+0h] [ebp-38h]
  int v13; // [esp+4h] [ebp-34h]
  int v14; // [esp+Ch] [ebp-2Ch]

  if ( !*input )
    return 0;
  input_4 = input + 4;
  input_ = input;
  v4 = 0;
  v5 = 0;
  v13 = 0;
  while ( 1 )
  {
    v14 = -1;
    for ( i = 0; i != 64; ++i )
    {
      while ( base64_alphabet[i] != *input_ )
      {
        if ( ++i == 64 )
          goto LABEL_7;
      }
      LOBYTE(v14) = i;                          // LOBYTE(v14)为input第1个字符在base64码表所在的位置
    }
LABEL_7:
    LOBYTE(i) = 0;
    do
    {
      while ( base64_alphabet[i] != input[v4 + 1] )
      {
        if ( ++i == 64 )
          goto LABEL_11;
      }
      BYTE1(v14) = i++;                         // BYTE1(v14)为为input第2个字符在base64码表所在的位置
    }
    while ( i != 64 );
LABEL_11:
    input_3 = &input[v4 + 2];
    for ( j = 0; j != 64; ++j )
    {
      while ( base64_alphabet[j] != *input_3 )
      {
        if ( ++j == 64 )
          goto LABEL_15;
      }
      BYTE2(v14) = j;                           // BYTE2(j)为input第3个字符在base64码表所在的位置
    }
LABEL_15:
    v9 = &input[v4 + 3];
    for ( k = 0; k != 64; ++k )
    {
      while ( base64_alphabet[k] != *v9 )
      {
        if ( ++k == 64 )
          goto LABEL_19;
      }
      HIBYTE(v14) = k;                          // HIBYTE(v14)为input第4个字符在base64码表所在的位置
    }
LABEL_19:
    v12 = v5 + 1;                               // v12 = 1 + 4*循环次数
    res[v5] = (4 * HIBYTE(v14)) | (BYTE2(v14) >> 4) & 3;// 得到res[0]
    if ( *input_3 == '=' )                      // 遇到=号结束循环
      return v12;
    v12 = v5 + 2;                               // v12 = 2 + 4*循环次数
    res[v5 + 1] = (16 * BYTE2(v14)) | (BYTE1(v14) >> 2) & 0xF;// 得到res[1]
    if ( *v9 == '=' )                           // 遇到=号结束循环
      return v12;
    v5 += 3;
    input_ = input_4;
    input_4 += 4;
    v13 += 4;
    v4 = v13;
    res[v5 - 1] = (BYTE1(v14) << 6) | v14 & 0x3F;// 得到res[2]
    if ( !*(input_4 - 4) )                      // 遇到空值结束循环
      return v5;
  }
}
  • 发现base64_decode魔改
  • 根据input每4个字符,得到其对应base64下标,再通过计算得出每3个一组的res

flag = []
res = [0x46,0xED,0x18,0x96,0x56,0x9E,0xD2,0x72,0xB2,0xB3,0x80,0x70]
base64_alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'

# flag爆破
for i in range(0,4):
    v = 0
    for LOBYTE in range(len(base64_alphabet)):
        for BYTE1 in range(len(base64_alphabet)):
            for BYTE2 in range(len(base64_alphabet)):
                for HIBYTE in range(len(base64_alphabet)):
                    if (res[0 + i*3] == ((4 * HIBYTE)&0xff) | ((BYTE2 >> 4)&0xff) & 3) and  (res[1 + i*3] == ((16 * BYTE2)&0xff) | ((BYTE1 >> 2)&0xff) & 0xF) and (res[2 + i*3] == ((BYTE1 << 6)&0xff) | LOBYTE & 0x3F) :
                        flag.extend([base64_alphabet[LOBYTE],base64_alphabet[BYTE1],base64_alphabet[BYTE2],base64_alphabet[HIBYTE]])
                        print(flag)
                        v = 1
                        break
                if v == 1:
                    break
            if v == 1:
                break
        if v == 1:
            break

flag = "".join(flag)
print(flag)

# md5爆破
import hashlib
def md5(str):           # md5加密
    return hashlib.md5(str.encode()).hexdigest()

for i in range(32,128):
    flags = flag + chr(i) + '==='
    if md5(flags) == '5a3ebb487ad0046e52db00570339aace':
        print(flags)
        break

在这里插入图片描述

  • 4个字符一组,对flag进行爆破,得出flag前16位
  • flag最后3位为=,还差一位通过md5爆破得到
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值