[buuctf]特殊的base64

[buuctf]特殊的base64

首先查壳,发现是一个无壳的,64位的一个文件,那就直接拖入到ida中查看main函数,看到算法。

int __cdecl main(int argc, const char **argv, const char **envp)
{
  __int64 v3; // rax
  __int64 v4; // rax
  std::string result; // [rsp+20h] [rbp-60h]
  std::string rightFlag; // [rsp+30h] [rbp-50h]
  std::string str; // [rsp+40h] [rbp-40h]
  char v9; // [rsp+4Fh] [rbp-31h]
  std::string v10; // [rsp+50h] [rbp-30h]

  _main();
  std::string::string(&str);
  std::allocator<char>::allocator(&v9);
  std::string::string(&rightFlag, "mTyqm7wjODkrNLcWl0eqO8K8gc1BPk1GNLgUpI==", &v9);
  std::allocator<char>::~allocator(&v9);
  v3 = std::operator<<<std::char_traits<char>>(refptr__ZSt4cout, "Please input your flag!!!!");
  std::ostream::operator<<(v3, refptr__ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_);
  std::operator>><char,std::char_traits<char>,std::allocator<char>>(refptr__ZSt3cin, &str);
  std::string::string(&v10, &str);
  base64Encode(&result);
  std::string::~string(&v10);
  if ( std::operator==<char>(&result, &rightFlag) )
    v4 = std::operator<<<std::char_traits<char>>(refptr__ZSt4cout, "The flag is right!!!!!!!!!");
  else
    v4 = std::operator<<<std::char_traits<char>>(refptr__ZSt4cout, "This is a wrong flag!!!!!!!!");
  std::ostream::operator<<(v4, refptr__ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_);
  std::string::~string(&result);
  std::string::~string(&rightFlag);
  std::string::~string(&str);
  return 0;
}

发现,特殊的base给了&rightFlag,之后跟&result比较,之后输出是否正确,那么直接进base64Encode看看编码是怎么编码的。

std::string __cdecl base64Encode(std::string *p_decode)
{
  std::string *v1; // rdx
  char *v2; // rax
  int v3; // eax
  int v4; // ebx
  char *v5; // rax
  int v6; // eax
  int v7; // ebx
  char *v8; // rax
  int v9; // eax
  _BYTE *v10; // rax
  int v11; // eax
  char *v12; // rax
  int v13; // eax
  _BYTE *v14; // rax
  int v15; // eax
  char *v16; // rax
  int v17; // eax
  int v18; // ebx
  char *v19; // rax
  int v20; // eax
  _BYTE *v21; // rax
  int v22; // eax
  __int64 v24; // [rsp+0h] [rbp-80h]
  char v25; // [rsp+2Fh] [rbp-51h]
  int pos_0; // [rsp+30h] [rbp-50h]
  int pos; // [rsp+34h] [rbp-4Ch]
  int len; // [rsp+38h] [rbp-48h]
  int i; // [rsp+3Ch] [rbp-44h]
  std::string *p_encodeResult; // [rsp+60h] [rbp-20h]
  std::string *p_decodea; // [rsp+68h] [rbp-18h]

  p_encodeResult = p_decode;
  p_decodea = v1;
  std::allocator<char>::allocator((char *)&v24 + 47);
  std::string::string(p_encodeResult, &unk_489084, &v25);
  std::allocator<char>::~allocator(&v25);
  len = std::string::length(p_decodea);
  for ( i = 0; len / 3 > i; ++i )
  {
    v2 = (char *)std::string::operator[](p_decodea, 3 * i);
    v3 = *(char *)std::string::operator[](&baseKey, *v2 >> 2);
    std::string::operator+=(p_encodeResult);
    v4 = 16 * (*(_BYTE *)std::string::operator[](p_decodea, 3 * i) & 3);
    v5 = (char *)std::string::operator[](p_decodea, 3 * i + 1);
    v6 = *(char *)std::string::operator[](&baseKey, v4 | (*v5 >> 4));
    std::string::operator+=(p_encodeResult);
    v7 = 4 * (*(_BYTE *)std::string::operator[](p_decodea, 3 * i + 1) & 0xF);
    v8 = (char *)std::string::operator[](p_decodea, 3 * i + 2);
    v9 = *(char *)std::string::operator[](&baseKey, v7 | (*v8 >> 6));
    std::string::operator+=(p_encodeResult);
    v10 = (_BYTE *)std::string::operator[](p_decodea, 3 * i + 2);
    v11 = *(char *)std::string::operator[](&baseKey, *v10 & 0x3F);
    std::string::operator+=(p_encodeResult);
  }
  if ( len % 3 == 1 )
  {
    pos = 3 * (len / 3);
    v12 = (char *)std::string::operator[](p_decodea, 3 * (len / 3));
    v13 = *(char *)std::string::operator[](&baseKey, *v12 >> 2);
    std::string::operator+=(p_encodeResult);
    v14 = (_BYTE *)std::string::operator[](p_decodea, pos);
    v15 = *(char *)std::string::operator[](&baseKey, 16 * (*v14 & 3));
    std::string::operator+=(p_encodeResult);
    std::string::operator+=(p_encodeResult, "==");
  }
  if ( len % 3 == 2 )
  {
    pos_0 = 3 * (len / 3);
    v16 = (char *)std::string::operator[](p_decodea, 3 * (len / 3));
    v17 = *(char *)std::string::operator[](&baseKey, *v16 >> 2);
    std::string::operator+=(p_encodeResult);
    v18 = 16 * (*(_BYTE *)std::string::operator[](p_decodea, pos_0) & 3);
    v19 = (char *)std::string::operator[](p_decodea, pos_0 + 1);
    v20 = *(char *)std::string::operator[](&baseKey, v18 | (*v19 >> 4));
    std::string::operator+=(p_encodeResult);
    v21 = (_BYTE *)std::string::operator[](p_decodea, pos_0 + 1);
    v22 = *(char *)std::string::operator[](&baseKey, 4 * (*v21 & 0xF));
    std::string::operator+=(p_encodeResult);
    std::string::operator+=(p_encodeResult, "=");
  }
  return (std::string)p_encodeResult;
}

发现,没有对于编码表的动作,咱们再去看看编码表,直接查找字符串。

.rdata:0000000000489090 aAabbccddeeffgg db 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0987654321/+',0

获得了一个编码,没有对于这个编码做什么,那么就直接替换编码表,来获得flag,直接写脚本即可。

import base64
str_1 = "mTyqm7wjODkrNLcWl0eqO8K8gc1BPk1GNLgUpI=="
str_base = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0987654321/+"
str_zh_base = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
flag = base64.b64decode(str_1.translate(str.maketrans(str_base,str_zh_base)))
print(flag)#flag{Special_Base64_By_Lich}'

最后获得flag就是flag{Special_Base64_By_Lich}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

逆向萌新

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值