RC4 + base64换表

main函数 能看到是有一个base字符串的

int sub_400BC8()
{
  int result; // $v0
  int v1; // [sp+18h] [+18h]
  int v2; // [sp+1Ch] [+1Ch]
  unsigned __int8 v3[100]; // [sp+20h] [+20h] BYREF
  int v4; // [sp+84h] [+84h]

  v4 = dword_49E990;
  sub_408940("please input your flag:");
  sub_408A40("%s", (const char *)v3);
  v1 = sub_41A6E0((char *)v3);
  sub_4009DC((int)v3);
  v2 = sub_400550(v3, v1);
  if ( sub_41A1E0(v2, "ScDZC1cNDZaxnh/2eW1UdqaCiJ0ijRIExlvVEgP43rpxoxbYePBhpwHDPJ==") )
  {
    sub_4098B0("wrong!");
    result = -1;
  }
  else
  {
    sub_4098B0("correct!");
    result = 0;
  }
  if ( v4 != dword_49E990 )
    sub_420350();
  return result;
}

strlen函数 也就是统计字符长度的

char *__fastcall sub_41A6E0(char *a1)
{
  char *v1; // $v0

  v1 = a1;
  if ( ((unsigned __int8)a1 & 3) == 0 )
  {
    while ( 1 )
    {
LABEL_7:
      if ( ((*(_DWORD *)a1 - 16843009) & ~*(_DWORD *)a1 & 0x80808080) != 0 )
      {
        if ( !*a1 )
          return (char *)(a1 - v1);
        if ( !a1[1] )
          return (char *)(a1 - v1 + 1);
        if ( !a1[2] )
          return (char *)(a1 - v1 + 2);
        if ( !a1[3] )
          return (char *)(a1 - v1 + 3);
      }
      a1 += 4;
    }
  }
  if ( !*a1++ )
    return nullptr;
  while ( 1 )
  {
    if ( ((unsigned __int8)a1 & 3) == 0 )
      goto LABEL_7;
    if ( !*a1 )
      return (char *)(a1 - v1);
    ++a1;
  }
}

RC4 函数 sub_400864() 做 s 盒初始化操作 sub_4009DC() 做加解密操作

BOOL __fastcall sub_4009DC(int a1)
{
  BOOL result; // $v0
  unsigned int i; // [sp+1Ch] [+1Ch]
  int v3; // [sp+20h] [+20h]
  int v4; // [sp+24h] [+24h]
  unsigned __int8 v5; // [sp+2Bh] [+2Bh]

  sub_400864(a1);
  v4 = 0;
  v3 = 0;
  for ( i = 0; ; ++i )
  {
    result = i < sub_41A6E0(a1);
    if ( !result )
      break;
    v3 = (v3 + 1) % 256;
    v4 = (byte_4A0860[v3] + v4) % 256;
    v5 = byte_4A0860[v3];
    byte_4A0860[v3] = byte_4A0860[v4];
    byte_4A0860[v4] = v5;
    *(_BYTE *)(a1 + i) ^= byte_4A0860[(unsigned __int8)(byte_4A0860[v3] + byte_4A0860[v4])];
  }
  return result;
}

sub_400864

BOOL sub_400864()
{
  BOOL result; // $v0
  unsigned int i; // [sp+18h] [+18h]
  unsigned int j; // [sp+18h] [+18h]
  int v3; // [sp+1Ch] [+1Ch]
  int v4; // [sp+20h] [+20h]
  unsigned __int8 v5; // [sp+27h] [+27h]

  for ( i = 0; i < 0x100; ++i )
    byte_4A0860[i] = i;
  v4 = 0;
  LOBYTE(v3) = 0;
  for ( j = 0; ; ++j )
  {
    result = j < 0x100;
    if ( j >= 0x100 )
      break;
    v5 = byte_4A0860[j];
    v3 = (unsigned __int8)(v5 + v3 + aFlag1233213211[v4]);
    byte_4A0860[j] = byte_4A0860[v3];
    byte_4A0860[v3] = v5;
    if ( ++v4 >= (unsigned int)strlen(aFlag1233213211) )
      v4 = 0;
  }
  return result;
}

RC4有一个key 也就是这个aFlag1233213211 我们提取 那我们知道这个是RC4加密了 还有一个呢

能看到这个函数进行了一个标准的base64加密 IDA反编译出来的总有一点点差异 不过也不难看出来

int __fastcall sub_400550(unsigned __int8 *a1, int a2)
{
  int v2; // $v0
  int v3; // $v0
  int v4; // $v0
  int v5; // $v0
  int v6; // $v0
  unsigned __int8 *v8; // [sp+1Ch] [+1Ch]
  int i; // [sp+20h] [+20h]
  int v10; // [sp+24h] [+24h]
  int v11; // [sp+24h] [+24h]
  int v12; // [sp+24h] [+24h]
  int v13; // [sp+2Ch] [+2Ch]

  v13 = sub_418210(4 * a2 / 3 + 1);
  v10 = 0;
  v8 = a1;
  for ( i = a2; i > 0; i -= 3 )
  {
    v2 = v10;
    v11 = v10 + 1;
    *(_BYTE *)(v13 + v2) = aZyxwvutsrqponm[*v8 >> 2];
    if ( i < 2 )
    {
      *(_BYTE *)(v13 + v11) = aZyxwvutsrqponm[(16 * *v8) & 0x30];
      *(_BYTE *)(v13 + v11 + 1) = 61;
      v6 = v11 + 2;
      v10 = v11 + 3;
      *(_BYTE *)(v13 + v6) = 61;
      break;
    }
    v3 = v11;
    v12 = v11 + 1;
    *(_BYTE *)(v13 + v3) = aZyxwvutsrqponm[(16 * *v8) & 0x30 | (v8[1] >> 4)];
    if ( i < 3 )
    {
      *(_BYTE *)(v13 + v12) = aZyxwvutsrqponm[(4 * v8[1]) & 0x3C];
      v5 = v12 + 1;
      v10 = v12 + 2;
      *(_BYTE *)(v13 + v5) = 61;
      break;
    }
    *(_BYTE *)(v13 + v12) = aZyxwvutsrqponm[(4 * v8[1]) & 0x3C | (v8[2] >> 6)];
    v4 = v12 + 1;
    v10 = v12 + 2;
    *(_BYTE *)(v13 + v4) = aZyxwvutsrqponm[v8[2] & 0x3F];
    v8 += 3;
  }
  *(_BYTE *)(v13 + v10) = 0;
  return v13;
}

那这两个都没有魔改 那我们直接提取数据解密叭

数据

enc = "ScDZC1cNDZaxnh/2eW1UdqaCiJ0ijRIExlvVEgP43rpxoxbYePBhpwHDPJ=="
base1 = "ZYXWVUTSRQPONMLKJIHGFEDCBAabcdefghijklmnopqrstuvwxyz/+9876543210"
base2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
key = "flag{123321321123badbeef012}"

exp

import base64
from Crypto.Cipher import ARC4

enc = "ScDZC1cNDZaxnh/2eW1UdqaCiJ0ijRIExlvVEgP43rpxoxbYePBhpwHDPJ=="
base1 = "ZYXWVUTSRQPONMLKJIHGFEDCBAabcdefghijklmnopqrstuvwxyz/+9876543210"
base2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
key = "flag{123321321123badbeef012}"
Str = base64.b64decode(enc.translate(str.maketrans(base1, base2)))
flag = ARC4.new(bytes(key, encoding='utf-8')).decrypt(Str)
print(flag.decode())

flag

flag{RC_f0ur_And_Base_s1xty_f0ur_Encrypt_!}

一把梭

image