• 【bugku】【ZSCTF】【迷宫RE】Take The Maze WriteUp


    Take The Maze

      首先拿进PEID里查一下有没有壳:

      无壳,果断拖进IDA。可是Graph View中找不到主程序的位置,在函数表里寻找主函数:

      函数太多阻扰了我们找到主程序,运行一下程序找一些关键词来搜索主程序位置:

      得知主程序中应当含有“welcome to zsctf!”字符串,在IDA中搜索来找到主程序:

      成功找到主函数,双击进入主函数,F5出伪代码:

      可以看出输入的KEY为24位由0-9,a-f构成的字符串,且需要根据sub_45E593()的返回值确定是否为正确KEY。其他函数先放下,先分析一下sub_45E593():

      多个if对应多个处理函数,且根据dlru初步猜测是迷宫问题。先来看看这个byte_541168存着什么:

      该数组存的是"delru0123456789",在回过头分析四个if上面的switch语句:

      可以根据两次的自加操作判断,输入的数据两两为一组。而且drc的值被用于在下面的if语句中判断是byte_541168[]前五个中的哪一个字符,所以drc就决定了迷宫的走向。stp是朝着byte_541168[drc]方向行走的步数。

      点开四个if对应的函数分别分析一下:

      从这个函数可以推测出这个迷宫一行有26个元素。根据中pos == 311则return true,而311 == 11 * 26 + 25,再加上每一行的列标号从零开始,所以相当于从地图的左上角走到地图的(12, 25)的位置,即左上角走到右下角。

      而且在上图向下走的函数中,往下走能否可行是根据dword_540548[i] ^ dword_540068[i]的值来确定的,所以可以直接根据四个方向函数中的数组地址写出IDC脚本来判断某个节点是否可以往某个特定的方向走。IDC脚本如下:

     1 auto i;
     2 for(i = 0;i <= 311; ++i){
     3     if(Dword(0x540548 + i * 4) ^ Dword(0x540068 + i * 4))
     4         Message(".");
     5     else
     6         Message("D");
     7         
     8     if(Dword(0x5404DC + i * 4) ^ Dword(0x53FFFC + i * 4))
     9         Message(".");
    10     else
    11         Message("L");        
    12         
    13     if(Dword(0x5404E4 + i * 4) ^ Dword(0x540004 + i * 4))
    14         Message(".");
    15     else
    16         Message("R");
    17     
    18     if(Dword(0x540478 + i * 4) ^ Dword(0x53FF98 + i * 4))
    19         Message(".");
    20     else
    21         Message("U");
    22     
    23     Message("  ");
    24     if(!((i + 1) % 26))
    25         Message("
    
    ");
    26 }
    27 return 0;

      在IDA中执行效果如下:

      放到记事本里走一遍迷宫:

       手动走迷宫走出来的字符串为06360836063b0839073e0639,结果输到程序里发现还是错误的KEY,返回到主函数检查一下有没有加密函数:

      v5因为地址和v4紧挨着,所以v5其实就是v4[16],所以v5 ^= 1就相当于v4[16] ^= 1。这是加密的第一部分,分析一下疑似为加密函数的sub_45C748():

      。。。。。。这tm是什么玩意儿。

      看不太懂这是什么神奇加密,移步OD碰下运气。

      令输入的字符串为24个“1”,步过这加密函数后它变成了这样:

      右下角的框框高亮部分就是经过加密函数的样子。

      。。。。。。这不就是按位异或吗加密函数那么复杂作死啊??

      再试验一组24个“0”,发现其实是按位异或了一下,python脚本如下:

    1 a = list("06360836063b0839073e0639")
    2 a[16] = chr(ord(a[16]) ^ 1)
    3 for i in range(24):
    4     print chr(ord(a[i])^i),

      跑出来结果如下:

      去掉空格就是真正的KEY了,输进程序里面:

      工作目录下便生成了一个.png文件,点开发现是个二维码:

      扫出来:

      把之前解出来的KEY后面加上Docupa就是zsctf{}中括号里的内容啦!

  • 相关阅读:
    《你的灯还亮着吗?》读后感(一)
    课堂练习-找水王
    私人助手-典型用户和场景描述
    课堂练习-哈利波特
    战略会议2
    战略会议总结
    "私人助手"NABCD分析
    返回一个首尾相连的二维数组的最大子数组的和
    返回一个首尾相连的一位数组中最大子数组的和
    5个常用Java代码混淆器 助你保护你的代码
  • 原文地址:https://www.cnblogs.com/reddest/p/10121550.html
Copyright © 2020-2023  润新知