DelCTF2019 Cplusplus WP

前言

  • 错过了这场比赛,赛后补上。虽有WP可以参考,但是复现起来还是磕磕绊绊。我总不想去依赖wp,于是先自己去分析,一开始好多看不懂的代码,睡过去了,积极性受打击,遂搁置了一天。断断续续逆了3天,然后参考WP,终于弄懂了。

分析

  • 程序无壳,用IDA分析。主要过程分为三步,每一步就是flag的一个组成部分。通过单步调试,可以知道flag的第一部分与第二部分用 @ 做分割,第二部分与第三部分用 # 做分割,并且除分隔符之外全是数字。
  • 第一步:
    • 将flag的第一部分转成数字,作为随机数种子,采用梅森旋转算法生成一个随机数序列,相关代码如下
      在这里插入图片描述
    • 这个函数中多次调用到一个我称之为StrToNumber的函数,其实就是将字符串转为数字形式。
      在这里插入图片描述
    • 梅森旋转算法:
      在这里插入图片描述
      在这里插入图片描述
    • 生成的随机数要满足
((((((((v12 >> 11) ^ v12) & 0xFF3A58AD) << 7) ^ (v12 >> 11) ^ v12) & 0xFFFFDF8C) << 15) ^ ((((v12 >> 11) ^ v12) & 0xFF3A58AD) << 7) ^ (v12 >> 11) ^ v12 ^ (((((((((v12 >> 11) ^ v12) & 0xFF3A58AD) << 7) ^ (v12 >> 11) ^ v12) & 0xFFFFDF8C) << 15) ^ ((((v12 >> 11) ^ v12) & 0xFF3A58AD) << 7) ^ (v12 >> 11) ^ v12) >> 18)) == 0xD4CBCF03 
    • 所以可以通过爆破随机数种子来确定flag的第一部分。这里有两个方法可行:

      1.从IDA中copy下来修改一下在IDE中爆破。
      2.直接patch源程序,在源程序中进行爆破。

    • 显然第二种方法比较好最省力,最不容易出错。因为不需要去考虑IDA的伪代码中函数的参数类型和返回值,这是最容易出错的地方。

    • 我使用x64dbg找到对应的地方:
      在这里插入图片描述

    • 修改为
      在这里插入图片描述
      在这里插入图片描述

    • 修改为
      在这里插入图片描述

    • 并在其下方下个断点,断下的时候观察一下寄存器rbx寄存器,就能得到flag1=78,然后记录最后得到的随机数为0x22,后面会用到。

  • 第二步:
    在这里插入图片描述
    • 将flag的第二部分作为byte_140008530数组的索引,依次得到De1ta,反求得到flag2=20637
  • 第三步:
    在这里插入图片描述
    • 这是IDA识别不好的问题,曾困扰我多时。所以根据第一步得到的随机数0x22可以算出flag3=114
  • 故正确的flag为flag{78@20637#114}

    总结

    • 遇到看不懂的函数就手动剥出来调试,便于理解。
    • 逆向过程需要灵活机动,还要不厌其烦,必须有耐性。没有积极性真的很难坚持下去。
    • 算法千千万,我们不可能都见过,都掌握,所以要善于利用百度谷歌,善于从常数中获得新发现。
    • IDA的反编译结果存在很多误差,变量的类型通常都是错误的,需要手动调试多遍才能确定变量的类型和他们彼此间的联系,只要掌握了这些,后面的都不是大问题。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值