BUUCTF_RE_[WUSTCTF2020]level3


64位ELF文件

 查字符串找到这么个字符串,当然,肯定没那么简单就直接base64

主函数:

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char *v3; // rax
  char v5; // [rsp+Fh] [rbp-41h]
  char v6[56]; // [rsp+10h] [rbp-40h] BYREF
  unsigned __int64 v7; // [rsp+48h] [rbp-8h]

  v7 = __readfsqword(0x28u);
  printf("Try my base64 program?.....\n>");
  __isoc99_scanf("%20s", v6);
  v5 = time(0LL);
  srand(v5);
  if ( (rand() & 1) != 0 )
  {
    v3 = base64_encode(v6);
    puts(v3);
    puts("Is there something wrong?");
  }
  else
  {
    puts("Sorry I think it's not prepared yet....");
    puts("And I get a strange string from my program which is different from the standard base64:");
    puts("d2G0ZjLwHjS7DmOzZAY0X2lzX3CoZV9zdNOydO9vZl9yZXZlcnGlfD==");
    puts("What's wrong??");
  }
  return 0;
}

一开始我看着它的随机种子,以为是随机base64加密,

然后尝试之后,发现也不对,解不出来

百度得知

然后得到一个新的快捷键

Ctrl+x,查看调用函数

然后就该是变表了

查看base64_table表的函数调用

 你会发现O_OLookAtYou

跟进汇编C代码

__int64 O_OLookAtYou()
{
  __int64 result; // rax
  char v1; // [rsp+1h] [rbp-5h]
  int i; // [rsp+2h] [rbp-4h]

  for ( i = 0; i <= 9; ++i )
  {
    v1 = base64_table[i];
    base64_table[i] = base64_table[19 - i];
    result = 19 - i;
    base64_table[result] = v1;
  }
  return result;
}

然后这个变换表就很清楚了

exp:

import base64
import string
base64_table0 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
base64_table1=[]
for i in range(len(base64_table0)):
    base64_table1.append(base64_table0[i])
base64_table2=''

s='d2G0ZjLwHjS7DmOzZAY0X2lzX3CoZV9zdNOydO9vZl9yZXZlcnGlfD=='
for i in range(9):
    v1=base64_table1[i]
    base64_table1[i]=base64_table1[19-i]
    result=19-i
    base64_table1[result]=v1
for i in range(len(base64_table1)):
    base64_table2+=base64_table1[i]
string1=base64_table2
string2='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
print(base64.b64decode(s.translate(str.maketrans(string1,string2))))

我的exp有点复杂,我把那个表转换成了数组,让后再转换成字符串,再换表解密

得到flag

wctf2020{Base64_is_the_start_of_reverse}