吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 6222|回复: 24
收起左侧

[CTF] 学破解第184天,《攻防世界reverse练习区Reversing-x64Elf-100》学习

  [复制链接]
小菜鸟一枚 发表于 2022-2-20 11:51

前言:

  坛友们,年轻就是资本,和我一起逆天改命吧,我的学习过程全部记录及学习资源:https://www.52pojie.cn/thread-1582287-1-1.html

立帖为证!--------记录学习的点点滴滴

0x1 锁定目标

  1.百度攻防世界:Reversing-x64Elf-100,1分题,应该没有难度吧

  2.老规矩,先查壳

https://s4.ax1x.com/2022/02/20/HLFFl4.png

  3.手上没有linux系统,但是简单的题应该用不上动态调试,靠IDA足够了。

0x2 静态分析

  1.直接拖进IDA看看main函数,可以看到sub_4006FD函数是关键,它的返回值决定我们输入的flag是否正确:

__int64 __fastcall main(int a1, char **a2, char **a3)
{
  __int64 result; // rax
  char s[264]; // [rsp+0h] [rbp-110h] BYREF
  unsigned __int64 v5; // [rsp+108h] [rbp-8h]

  v5 = __readfsqword(0x28u);
  printf("Enter the password: ");
  if ( !fgets(s, 255, stdin) )
    return 0LL;
  if ( (unsigned int)sub_4006FD((__int64)s) )
  {
    puts("Incorrect password!");
    result = 1LL;
  }
  else
  {
    puts("Nice!");
    result = 0LL;
  }
  return result;
}

  2.再去看看sub_4006FD函数,通过main函数if条件我们知道这里必须返回true,也就是1:

__int64 __fastcall sub_4006FD(__int64 a1)
{
  int i; // [rsp+14h] [rbp-24h]
  __int64 v3[4]; // [rsp+18h] [rbp-20h]

  v3[0] = (__int64)"Dufhbmf";
  v3[1] = (__int64)"pG`imos";
  v3[2] = (__int64)"ewUglpt";
  for ( i = 0; i <= 11; ++i )
  {
    if ( *(char *)(v3[i % 3] + 2 * (i / 3)) - *(char *)(i + a1) != 1 )
      return 1LL;
  }
  return 0LL;
}

  3.有点懵,if只要成立一次就返回1???那我怎么知道完整的flag计算流程!!!

  4.vs 2015社区版一直自动退出,登录也登不上去,这下直接把代码拷贝过去运行的方法也没了。

  5.人工计算,大脑里运行一下,并记录结果:

for循环:

1)v3[0] + 0 - a1[0]!=1

2)v3[1] + 0 - a1[1]!=1

3)v3[2] + 0 - a1[2]!=1

==================================

1)v3[0] + 2 - a1[3]!=1

2)v3[1] + 2 - a1[4]!=1

3)v3[2] + 2 - a1[5]!=1

==================================

1)v3[0] + 4 - a1[6]!=1

2)v3[1] + 4 - a1[7]!=1

3)v3[2] + 4 - a1[8]!=1

==================================

1)v3[0] + 6 - a1[9]!=1

2)v3[1] + 6 - a1[10]!=1

3)v3[2] + 6 - a1[11]!=1

  6.共循环11次,最后结束循环,最终就是字符串Dpef'ubmlfst减去我们输入的字符串a1的值判断是否不等于1,如果不等于1,就返回1,也就是true。

  7.最后依靠百度,终于整明白了......,据说linux环境下函数执行成功返回0代表正确,非0代表错误,不知道对不对,但是这样理解这个代码就能看懂了。

  8.那么只要让每次if比较结果为真,也就是两个字符串相减等于1,最后循环结束后,返回0,代表true,成功。

  9.v3 -flag =1 ,代换过来就是flag = v3 - 1所以flag就是Dpef'ubmlfst - 1。

0x3 写脚本

  1.这里我就不查表的一个个自己算了,你看看那个循环,算了老半天,不过收获,就是能看到那一行代码的意思了。

  2.看懂代码了,写脚本就好说,以前这种我就是复制到c++ ide工具里,颠倒一下计算过程赋值语句,不用看懂算法代码,跑一下就能得到flag。

  3.打开eclipse,编写java脚本:

1)因为java没有指针,但是学c语言的时候知道,数组就是指针

2)指针取值,这里用数组取值即可

3)字符串可以看做是一个char数组

  4.完整的代码:

package ctf;

public class test01 {

    public static void main(String[] args) {

          int i; 

          //定义一个二维字符数组,把v3字符化
          char[][] v3 = new char[][] {{'D','u','f','h','b','m','f'},{'p','G','`','i','m','o','s'},{'e','w','U','g','l','p','t'}}; 

          StringBuffer flag = new StringBuffer("");

          for ( i = 0; i <= 11; ++i )
          {
              flag.append((char) (v3[i % 3][2 * (i / 3)] - 1)) ;//强制转换char类型,追加到字符串中
          }
         System.out.println("flag:"+ flag);
    }
}

输出:flag:Code_Talkers

  5.去验证一下,输入flag,成功截图:

https://s4.ax1x.com/2022/02/20/HLu4g0.png

0x4 总结

  1.函数返回值那里把我给整懵了,浪费了不少的时间。

  2.vs2015社区版不知道啥原因,一打开就提示要登录,登录不上去,秒退,要不然这代码直接粘过去,都不用分析if里面那一行代码就能直接爆出flag。

免费评分

参与人数 10威望 +1 吾爱币 +28 热心值 +8 收起 理由
Hmily + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
charmy20 + 1 + 1 我很赞同!
小鱼干! + 1 + 1 我很赞同!
孺子韫 + 1 + 1 我很赞同!
香芋 + 1 + 1 谢谢@Thanks!
幼幼小白兔 + 1 + 1 热心回复!
chuiyan121 + 1 + 1 谢谢@Thanks!
m16139 + 1 我很赞同!
Pinsir + 1 用心讨论,共获提升!
hdjcevcas + 1 热心回复!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

TonyDog 发表于 2022-2-20 13:56
羡慕逆向大佬
sto01522 发表于 2022-2-20 15:32
iYoloPPD 发表于 2022-2-20 17:38
yangyi5181 发表于 2022-2-20 23:01
感谢楼主分享
lonelyproperous 发表于 2022-2-21 06:04

感谢楼主分享
jasonA 发表于 2022-2-21 09:08

今天又是仰望大佬的一天
chentest 发表于 2022-2-21 09:53
学习一下下大佬思路
SM898 发表于 2022-2-21 10:11
本人刚接触破解知识,多向前辈学习
yamuel 发表于 2022-2-21 11:20
感谢楼主分享
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-12-24 00:30

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表