BUUCTF [ACTF新生赛2020]usualCrypt

文件无壳 直接拖入IDA shift+F12查看可疑字符串 发现有很多可以字符串 继续跟进

跟进后发现还是没有什么头绪 先看看主函数吧

主函数是这个样子

可以发现主函数引用了sub_403CF8函数,sub_401080函数

1.sub_403CF8函数

sub_403CF8 函数执行了一个与文件相关的操作,该操作涉及到了文件的某种“开始”和“结束”处理(通过 _stbuf_ftbuf),以及一个自定义的文件操作函数 sub_406119。这个函数能够处理可变数量的参数,并通过这些参数(以及文件句柄)来执行具体的文件操作。并没有什么实际意义

2.sub_401080函数

这段代码实现了一个自定义的编码过程,它将一个输入字符串(通过 a1 指针传递)和一个输出缓冲区(通过 a3 指针传递)的长度进行编码处理。这个编码过程看应该是针对Base64编码的变种。我们继续跟进sub_401000函数

int __cdecl sub_401080(int a1, int a2, int a3)
{
  int v3; // edi
  int v4; // esi
  int v5; // edx
  int v6; // eax
  int v7; // ecx
  int v8; // esi
  int v9; // esi
  int v10; // esi
  int v11; // esi
  _BYTE *v12; // ecx
  int v13; // esi
  int v15; // [esp+18h] [ebp+8h]

  v3 = 0;
  v4 = 0;
  sub_401000();
  v5 = a2 % 3;
  v6 = a1;
  v7 = a2 - a2 % 3;
  v15 = a2 % 3;
  if ( v7 > 0 )
  {
    do
    {
      LOBYTE(v5) = *(_BYTE *)(a1 + v3);
      v3 += 3;
      v8 = v4 + 1;
      *(_BYTE *)(v8 + a3 - 1) = byte_40E0A0[(v5 >> 2) & 0x3F];
      *(_BYTE *)(++v8 + a3 - 1) = byte_40E0A0[16 * (*(_BYTE *)(a1 + v3 - 3) & 3)
                                            + (((int)*(unsigned __int8 *)(a1 + v3 - 2) >> 4) & 0xF)];
      *(_BYTE *)(++v8 + a3 - 1) = byte_40E0A0[4 * (*(_BYTE *)(a1 + v3 - 2) & 0xF)
                                            + (((int)*(unsigned __int8 *)(a1 + v3 - 1) >> 6) & 3)];
      v5 = *(_BYTE *)(a1 + v3 - 1) & 0x3F;
      v4 = v8 + 1;
      *(_BYTE *)(v4 + a3 - 1) = byte_40E0A0[v5];
    }
    while ( v3 < v7 );
    v5 = v15;
  }
  if ( v5 == 1 )
  {
    LOBYTE(v7) = *(_BYTE *)(v3 + a1);
    v9 = v4 + 1;
    *(_BYTE *)(v9 + a3 - 1) = byte_40E0A0[(v7 >> 2) & 0x3F];
    v10 = v9 + 1;
    *(_BYTE *)(v10 + a3 - 1) = byte_40E0A0[16 * (*(_BYTE *)(v3 + a1) & 3)];
    *(_BYTE *)(v10 + a3) = 61;
LABEL_8:
    v13 = v10 + 1;
    *(_BYTE *)(v13 + a3) = 61;
    v4 = v13 + 1;
    goto LABEL_9;
  }
  if ( v5 == 2 )
  {
    v11 = v4 + 1;
    *(_BYTE *)(v11 + a3 - 1) = byte_40E0A0[((int)*(unsigned __int8 *)(v3 + a1) >> 2) & 0x3F];
    v12 = (_BYTE *)(v3 + a1 + 1);
    LOBYTE(v6) = *v12;
    v10 = v11 + 1;
    *(_BYTE *)(v10 + a3 - 1) = byte_40E0A0[16 * (*(_BYTE *)(v3 + a1) & 3) + ((v6 >> 4) & 0xF)];
    *(_BYTE *)(v10 + a3) = byte_40E0A0[4 * (*v12 & 0xF)];
    goto LABEL_8;
  }
LABEL_9:
  *(_BYTE *)(v4 + a3) = 0;
  return sub_401030(a3);
}

sub_401000函数使用一个for循环,从result(初始值为6)开始,直到小于15为止,每次循环result递增1。这个循环遍历了从索引6到14的数组元素。函数的主要目的是交换两个数组中索引从6到14的元素。将byte_40E0AA数组的第7个到第15个和byte_40E0A0数组进行交换

我们跟进byte_40E0A0 此处是base64编码

根据以上的代码 可以推测sub_401080函数实现的是交换过6到15的编码表的base64编码

而当这个函数执行完后,base64的编码表就被修改为
ABCDEFQRSTUVWXYPGHIJKLMNOZabcdefghijklmnopqrstuvwxyz0123456789+/

我们跟进最后一个函数sub_401030

这个函数是对字符串MXHz3TIgnxLxJhFAdtZn2fFk3lYCrtPC2l9进行大小写转换

反脚本的思路是先对字符串进行大小写转换,再对新的编码表进行新的base64解密

import base64
import string

# 原始字符串
original_string = 'zMXHz3TIgnxLxJhFAdtZn2fFk3lYCrtPC2l9'
# 大小写转换
swapped_case_string = original_string.swapcase()

# 原始的 base64 字符集
original_base64_table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
# 自定义的 base64 字符集
custom_base64_table = 'ABCDEFQRSTUVWXYPGHIJKLMNOZabcdefghijklmnopqrstuvwxyz0123456789+/'

# 创建一个转换表,将自定义 base64 字符集映射回原始的 base64 字符集
trans_table = str.maketrans(custom_base64_table, original_base64_table)

# 使用转换表将字符串中的字符从自定义 base64 转换为标准 base64
standard_base64_string = swapped_case_string.translate(trans_table)

# 解码 base64 字符串
decoded_data = base64.b64decode(standard_base64_string)

# 打印解码后的数据
print(decoded_data)

得到flag

flag{bAse64_h2s_a_Surprise}

  • 9
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值