首页
社区
课程
招聘
[原创]BUUCTF逆向题:[WUSTCTF2020]level3
发表于: 2022-3-24 23:13 9947

[原创]BUUCTF逆向题:[WUSTCTF2020]level3

2022-3-24 23:13
9947

64位,无壳,ELF文件

image-20220324212148717

image-20220324224904217

函数的逻辑很清晰,v6接受输入,但却是随缘进入if判断因为它的进入条件是随机生成的而随机的种子是系统时间,假设进入了if里面,会将输入作为参数调用一个函数(看名字是base64编码),但是编码完后就直接输出,也不进行判断,奇奇怪怪的,这里看一下下方提示:

对不起,我想它还没有准备好....

我从程序中得到一个奇怪的字符串,它不同于标准的base64:

先去在线网站将这个base64编码的字串解密看一下:

image-20220324215412370

发现解码失败,根据上面的提示它说这个字符串不同于标准的base64,这里猜测base64_encode()这个函数可能不是正常的base64,应该魔改了。

这个函数就是这个程序的base64编码函数,先去看一下它的码表有没有问题:

image-20220324215926075

可以看到码表没什么问题,那就看一下,base64的编码过程有没有问题了。

这里贴一下base64加密的原理:(以“ABC”为例):

image-20220324222213523

修饰后的伪代码:

怎么说呢,这个代码不能说十分正常,只能说是一点毛病没有,到这里我就卡壳了,去百度后发现,这个程序还是换了码表但是它是在运行时动态更换的所以我们在看码表的数据时看不出什么毛病。我们点击码表看他的交叉引用:image-20220324223245007

可以看到除了base64_encode()O_OLookAtYou()也调用了码表,这时候确实有点无语这个函数名这么奇怪做题时一点没发现,先到O_OLookAtYou()函数那去看看,因为main函数是没有调用这个函数的,那这个函数是如何做到修改码表的呢?,还是看它的交叉引用:

image-20220324223647283

可以看到函数其实是在init,也就是初始化函数里被调用,我们知道函数的最开始并不是从main开始,start才是函数的真正入口点,这个知识点可以去看程序员的自我修养那本书,对这些东西分析得很透彻。init和start一样都是编译器加进去的,init函数主要负责设置包、初始化变量或其他要在程序运行前优先完成的引导工作。

这里选择直接动调看码表改完后是个啥样:

这里随便下个断点,没啥影响:

image-20220324225835997

直接双击查看码表:

image-20220324225936441

TSRQPONMLKJIHGFEDCBAUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/

上面这一串就是修改后的码表,然后利用新表解base64就行:

image-20220324230434528

wctf2020{Base64_is_the_start_of_reverse}

提交时记得是flag包裹

 
int __cdecl main(int argc, const char **argv, const char **envp)
{
  const 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 = (const char *)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;
}
int __cdecl main(int argc, const char **argv, const char **envp)
{
  const 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 = (const char *)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;
}
 
 
char *__fastcall base64_encode(char *a1)
{
  int v1; // eax
  int v2; // eax
  int v4; // [rsp+1Ch] [rbp-54h]
  int v5; // [rsp+20h] [rbp-50h]
  int v6; // [rsp+24h] [rbp-4Ch]
  int v7; // [rsp+28h] [rbp-48h]
  int v8; // [rsp+2Ch] [rbp-44h]
  char src[56]; // [rsp+30h] [rbp-40h] BYREF
  unsigned __int64 v10; // [rsp+68h] [rbp-8h]
 
  v10 = __readfsqword(0x28u);
  v1 = strlen(a1);
  v8 = v1 % 3;
  v7 = v1 / 3;
  memset(src, 0, 0x30uLL);
  v6 = 0;
  v4 = 0;
  v5 = 0;
  while ( v4 < v7 )
  {
    src[v6] = base64_table[a1[v5] >> 2];
    src[v6 + 1] = base64_table[(16 * (a1[v5] & 3)) | (a1[v5 + 1] >> 4)];
    src[v6 + 2] = base64_table[(4 * (a1[v5 + 1] & 0xF)) | (a1[v5 + 2] >> 6)];
    v2 = v6 + 3;
    v6 += 4;
    src[v2] = base64_table[a1[v5 + 2] & 0x3F];
    v5 += 3;
    ++v4;
  }
  if ( v8 == 1 )
  {
    src[v6] = base64_table[a1[v5] >> 2];
    src[v6 + 1] = base64_table[16 * (a1[v5] & 3)];
    strcat(src, "==");
  }
  else if ( v8 == 2 )
  {
    src[v6] = base64_table[a1[v5] >> 2];
    src[v6 + 1] = base64_table[(16 * (a1[v5] & 3)) | (a1[v5 + 1] >> 4)];
    src[v6 + 2] = base64_table[4 * (a1[v5 + 1] & 0xF)];
    src[v6 + 3] = 61;
  }
  strcpy(a1, src);
  return a1;
}
char *__fastcall base64_encode(char *a1)
{
  int v1; // eax
  int v2; // eax
  int v4; // [rsp+1Ch] [rbp-54h]
  int v5; // [rsp+20h] [rbp-50h]
  int v6; // [rsp+24h] [rbp-4Ch]
  int v7; // [rsp+28h] [rbp-48h]
  int v8; // [rsp+2Ch] [rbp-44h]
  char src[56]; // [rsp+30h] [rbp-40h] BYREF
  unsigned __int64 v10; // [rsp+68h] [rbp-8h]
 
  v10 = __readfsqword(0x28u);
  v1 = strlen(a1);
  v8 = v1 % 3;
  v7 = v1 / 3;
  memset(src, 0, 0x30uLL);
  v6 = 0;
  v4 = 0;
  v5 = 0;
  while ( v4 < v7 )
  {
    src[v6] = base64_table[a1[v5] >> 2];
    src[v6 + 1] = base64_table[(16 * (a1[v5] & 3)) | (a1[v5 + 1] >> 4)];
    src[v6 + 2] = base64_table[(4 * (a1[v5 + 1] & 0xF)) | (a1[v5 + 2] >> 6)];
    v2 = v6 + 3;
    v6 += 4;
    src[v2] = base64_table[a1[v5 + 2] & 0x3F];
    v5 += 3;
    ++v4;
  }
  if ( v8 == 1 )
  {
    src[v6] = base64_table[a1[v5] >> 2];
    src[v6 + 1] = base64_table[16 * (a1[v5] & 3)];
    strcat(src, "==");
  }

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2022-3-25 00:21 被宇宙大魔王编辑 ,原因:
收藏
免费 2
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//