zoukankan      html  css  js  c++  java
  • 10月月赛

      记录下两个逆向的writeup,第二个还是有点费事的。

    Re elf

      题目比较简单,算法也很简单,求用户名为ctfking的注册码。

      注册码需要满足条件:

      1. 全是数字 2. 长度10的倍数 3. 由serial经过算法生成的serial_gen和由用户名ctfking生成的name_gen相等

      如下图:

      下面简单分析下算法:

      

      Serial_gen 由 输入的serial的每一个字节模上一个从9开始依次递加的值。由于用户名已经固定,即ctfking。所以调试后,可以直接发现name_gen为0x8c,进而直接写了几行脚本爆破一下,秒出结果。

      

    Re pe

      直接定位到关键位置

      

      在handle函数内,inputstring必须满足xxxxxxxx-xxxxxxxx的格式,并将前8个字节和后8个字节转为两个整数存在v8和v7当中。

      举个例子,如果输入格式为12ab34cd-ab345678,那么v8=0x12ab34cd,

      v7=0x12ab34cd ^ 0xab345678。

      在judge函数内判断这两个整数是否满足条件,如果满足条件,那么注册成功。

      重点在judge函数内。

      

      算法比较简明,所以我的重点就是如何求出一个符合条件的num1和num2。暴力搜索的话,搜索空间太大,我们可以对算法分析来减少搜索的范围。

      v4形成的字符串String1需要满足等于String2,而v7就是机器码,都已知。

      如图中所示,*v4++ = num1 ^ ( v7 – num2 ),记lsb(i)取i的最低位,根据此,我们可以知道,Lsb(*v4++) = lsb(num1) ^ lsb(v7) ^ lsb(num2),那么我们就能知道lsb(num1) ^ lsb(num2)。那么经过32轮循环后,我们可以知道了 num1 ^ num2的值。 

      记byte0(i)为整数i的低8位,byte1(i)为整数i的[8,16]位,byte3(i)为整数i的[16,24]位,byte4(i)为整数i的最高8位。

      如果仔细琢磨的话,会发现,每当循环移位8次后,就会运算到num1和num2的byte0、byte1、byte2、byte3中的一个。

      也就是说, String2[0] = byte0(num1) ^ (String1[0] – byte0[num2]),即,String2[0] ^ byte0(num1) ^ byte0(num2) = byte0(num2) ^ (String1[0] – byte0[num2])。而num1 ^ num2我们已经得到,所以byte0(num1) ^ byte0(num2)也已经知道,byte0[num2]总共256中情况,遍历这256种情况也就可以确定byte0[num2]可以取哪些值。

      同理,可以确定byte1[num2]、byte2[num2]、byte3[num2],从而确定num2可以取的范围,因此,大大缩小了搜索空间。

      根据上述的思想,写出下列脚本,几秒出注册码。

  • 相关阅读:
    错误 : 资产文件“项目objproject.assets.json”没有“.NETCoreApp,Version=v2.0”的目标。确保已运行还原,且“netcoreapp2.0”已包含在项目的 TargetFrameworks 中。
    .NET core RSA帮助类
    vs2010单步调试崩溃
    常用排序算法比较与分析
    js原生的轮播图
    vue-cli脚手架使用-- 初学者
    vue-cli配置基础
    jq轮播图插件
    bootstrap 获得轮播中的索引或当前活动的焦点对象
    jQuery学习笔记之Ajax用法详解
  • 原文地址:https://www.cnblogs.com/wangaohui/p/4970278.html
Copyright © 2011-2022 走看看