攻防世界逆向高手题之EasyRE

99 篇文章 33 订阅

攻防世界逆向高手题之EasyRE

继续开启全栈梦想之逆向之旅~
这题是攻防世界逆向高手题的EasyRE
在这里插入图片描述

下载附件,照例扔入exeinfope中查看信息:
在这里插入图片描述

64位ELF文件,无壳,照例扔入IDA64中查看信息,有Main函数就看main函数:(PS:下面被我注释了一下内容,不过不影响)
在这里插入图片描述

照例分析代码:

  puts(input);    	//这里名称被我重命名过,判断依据是程序运行时的Input字符串在这里被引用,所以这里是输出函数
  v12 = 0;
  v13 = 0;
  *(_OWORD *)input_flag = '\0';
  v11 = '\0';
  sub_401050("%s", input_flag);
  v3 = strlen(input_flag);
  if ( v3 >= 16 && v3 == 24 )                   // 这里两个条件其实是多余的,输入flag等于24即可
  {
    v4 = 0;
    v5 = (char *)&v11 + 7;                      // v5取v11的64位地址下面的7位地址处,这里的(char*)只是对地址转换,并没有取地址的数,也就是说v5还是地址,而且后7位刚好是input_flag开始的24个字节范围的末尾,就是我们输入24字节flag的最后一个。  PS:这里之所以是v11地址的下面7位处是因为这是在main函数内的栈,栈是从下到上的(从高地址到底地址),栈变量都是从第一个分配地址往下划分内存的,后面会再讲~
    do
    {
      v6 = *v5--;                               // 从v5开始取,然后减一个地址,v5现在是input_flag的起始地址开始的24字节的末尾了指针了,也就是指向用户输入字符串的最后一个字符,这里循环24次,符合前面我们输入input_flag长度为24的判断条件。
      byte_40336C[v4++] = v6;                   //这里把v6的值也就是我们inpu_flag末尾位置的值开始,一个个赋值给v4开头,这就造成了v4是我们输入24位flag的反向字符,后续对v4数组操作也是对用户输入的24字符flag的反向操作。
    }
    while ( v4 < 24 );
    for ( i = 0; i < 24; ++i )
      byte_40336C[i] = (byte_40336C[i] + 1) ^ 6;// 赋完值之后有对自身进行异或操作,进一步修改,注意这里是我们输入的24位字符的反向数组
    v8 = strcmp(byte_40336C, aXircjR2twsv3pt);  // 异或完后简单的比较,aXircjR2twsv3pt双击跟踪后一个被/x7f截断的字符串,前18位是xIrCj~<r|2tWsv3PtI,发现不满足24位后再查看才发现后面还有,第19位是/x7f,20~24是zndka。这里留个心眼,/x7f可以阻断字符串
    if ( v8 )
      v8 = v8 < 0 ? -1 : 1;
    if ( !v8 )
    {
      puts("right\n");
      system("pause");
    }
  }
  return 0;
}

分析完了,附上图回顾一下以前犯错的思路,给自己日后提个醒:
犯下第一个错误是对关键数组地址修改的地方不敏感,一开始我只看到了对v4数组异或的代码:

   for ( i = 0; i < 24; ++i )
      byte_81336C[i] = (byte_81336C[i] + 1) ^ 6;

结果逆向逻辑出来后的flag是反的,大概长这样:}NsDkw9sy3qPto4UqNx{galf,可能还是能看出来是反的flag,单要是换其他字符串就不一定了。所以我们应该要注意前面还有对v4操作的代码,也要分析:(分析在前面)

  if ( v3 >= 16 && v3 == 24 )                
  {
    v4 = 0;
    v5 = (char *)&v11 + 7;                     
    do
    {
      v6 = *v5--;                               
      byte_81336C[v4++] = v6;               
    }
    while ( v4 < 24 );

犯下第二个错误就是对栈不熟练,就是基于对前面v4数组操作的分析,才发现这里有个栈操作让v4数组反向获取用户输入的字符串:
在这里插入图片描述

之前在IDA权威指南中了解过栈视图,这里v11是var_14,input_flag就是我们输入24位字符串的首地址,这里给了一个混淆就是v11,前面v5 = (char *)&v11 + 7;就是在v11地址往下取7位,就是0D了,刚好在var_C前面,input_flag首地址24到var_C前面0D处就是完整的24位input_flag地址,所以这里v11的过渡作用混淆了我,我们可以直接在栈中把v11删除,改input_flag为24位字符串,这里也就解释了v4数组取input_flag反向字符的原因了:
在这里插入图片描述

犯下第三个错误是在写脚本中发现的,减号的优先级高于^符号,下面脚本中 flag+=chr((ord(data[i]) ^ 6)-1) #要是写成chr((ord(data[i]) ^ 6 - 1)那就GG了,由于优先级不同所以结果会不同,给的警示是最好什么都用括号括起来,毕竟这种优先级问题是很难发现的,还以为是自己逻辑梳理错误呢。

data="xIrCj~<r|2tWsv3PtI\x7Fzndka"
flag=""
for i in range(24):
    flag+=chr((ord(data[i])^6)-1) 
print(flag)
print(flag[::-1])

结果:
在这里插入图片描述

总结:

1:
犯下第一个错误是对关键数组地址修改的地方不敏感,一开始我只看到了对v4数组异或的代码,结果逆向逻辑出来后的flag是反的,大概长这样:}NsDkw9sy3qPto4UqNx{galf,可能还是能看出来是反的flag,单要是换其他字符串就不一定了。所以我们应该要注意前面还有对v4操作的代码,也要分析!

2:犯下第二个错误就是对栈不熟练,就是基于对前面v4数组操作的分析,才发现这里有个栈操作让v4数组反向获取用户输入的字符串。之前在IDA权威指南中了解过栈视图,这里v11是var_14,input_flag就是我们输入24位字符串的首地址,这里给了一个混淆就是v11,前面v5 = (char *)&v11 + 7;就是在v11地址往下取7位,就是0D了,刚好在var_C前面,input_flag首地址24到var_C前面0D处就是完整的24位input_flag地址,所以这里v11的过渡作用混淆了我,我们可以直接在栈中把v11删除,改input_flag为24位字符串,这里也就解释了v4数组取input_flag反向字符的原因了。

3:犯下第三个错误是在写脚本中发现的,减号的优先级高于^符号,下面脚本中 flag+=chr((ord(data[i]) ^ 6)-1) 要是写成chr((ord(data[i]) ^ 6 - 1)那就GG了,由于优先级不同所以结果会不同,给的警示是最好什么都用括号括起来,毕竟这种优先级问题是很难发现的,还以为是自己逻辑梳理错误呢。

解毕!敬礼!

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

沐一 · 林

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

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

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

打赏作者

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

抵扣说明:

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

余额充值