【攻防世界】REVERSE新手练习区 - no-strings-attached

no-strings-attached - wp

分析题目附件:

https://adworld.xctf.org.cn/media/task/attachments/554e0986d6db4c19b56cfdb22f13c834
在这里插入图片描述ELF文件,32位。

拖入ida64,找main函数按F5(Fn+F5)查看伪代码:

int __cdecl main(int argc, const char **argv, const char **envp)
{
  setlocale(6, &locale); //开辟内存空间
  banner(); //输出
  prompt_authentication(); //输入
  authenticate(); //加密过程
  return 0;
}

四个函数都跟进后发现,只有authenticate()函数有关键信息,所以直接分析authenticate()函数:

void authenticate()
{
  wchar_t ws[8192]; // [esp+1Ch] [ebp-800Ch]
  wchar_t *s2; // [esp+801Ch] [ebp-Ch]

  s2 = (wchar_t *)decrypt(&s, &dword_8048A90); //decrypt表示加密
  if ( fgetws(ws, 0x2000, stdin) ) //进行输入
  {
    ws[wcslen(ws) - 1] = 0;
    if ( !wcscmp(ws, s2) ) //判断输入的ws是否等于加密过后的s2
      wprintf((int)&unk_8048B44); //如果ws=s2,得到unk_8048B44,跟进得到success!
    else
      wprintf((int)&unk_8048BA4);
  }
  free(s2);
}

在这里插入图片描述
当 ws 和 s2 相等时,会输出正确结果,那么s2就是flag,而s2经过了decrypt()加密。
那么跟进decrypt()函数:

wchar_t *__cdecl decrypt(wchar_t *s, wchar_t *a2)
{
  size_t v2; // eax
  signed int v4; // [esp+1Ch] [ebp-1Ch]
  signed int i; // [esp+20h] [ebp-18h]
  signed int v6; // [esp+24h] [ebp-14h]
  signed int v7; // [esp+28h] [ebp-10h]
  wchar_t *dest; // [esp+2Ch] [ebp-Ch]

  v6 = wcslen(s);
  v7 = wcslen(a2);
  v2 = wcslen(s);
  dest = (wchar_t *)malloc(v2 + 1);
  wcscpy(dest, s);
  while ( v4 < v6 )
  {
    for ( i = 0; i < v7 && v4 < v6; ++i )
      dest[v4++] -= a2[i];
  }
  return dest;
}

它先把参数 s 复制给 dest,与就是s=dest,然后把 dest 的每个值减去 a2 的值,然后再返回加密后的 dest。那么,我们就把s与a2找出来,相减就得到flag。

跟进s:
在这里插入图片描述
选中按shift+E提取出来:
在这里插入图片描述
根据得到的信息写c脚本:

#include <stdio.h>
int main()
{
    int x=0,i=0,j=0;
    int s[] =
    {
      58,  20,   0,   0,  54,  20,   0,   0,  55,  20,
       0,   0,  59,  20,   0,   0, 128,  20,   0,   0,
     122,  20,   0,   0, 113,  20,   0,   0, 120,  20,
       0,   0,  99,  20,   0,   0, 102,  20,   0,   0,
     115,  20,   0,   0, 103,  20,   0,   0,  98,  20,
       0,   0, 101,  20,   0,   0, 115,  20,   0,   0,
      96,  20,   0,   0, 107,  20,   0,   0, 113,  20,
       0,   0, 120,  20,   0,   0, 106,  20,   0,   0,
     115,  20,   0,   0, 112,  20,   0,   0, 100,  20,
       0,   0, 120,  20,   0,   0, 110,  20,   0,   0,
     112,  20,   0,   0, 112,  20,   0,   0, 100,  20,
       0,   0, 112,  20,   0,   0, 100,  20,   0,   0,
     110,  20,   0,   0, 123,  20,   0,   0, 118,  20,
       0,   0, 120,  20,   0,   0, 106,  20,   0,   0,
     115,  20,   0,   0, 123,  20,   0,   0, 128,  20,
       0,   0,
    };
    int b[] =
    {
       1,  20,   0,   0,   2,  20,   0,   0,   3,  20,
       0,   0,   4,  20,   0,   0,   5,  20,   0,   0,
    };
    while(i < 152)
    {

       x = s[i ++] - b[j ++ % 20];
       if(x>32)
        printf("%c",x);

    }
    return 0;
}

运行结果:
在这里插入图片描述
则 flag = 9447{you_are_an_international_mystery} 。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值