maze迷宫MD5
前言:该篇文章会介绍一个在ctf当中reverse方向中常见的一种迷宫题,我从攻防世界中选取了一道比较有代表性的题目,逐一讲解,并且每个思路都相当清晰透彻,借此分享,相信看完之后对于迷宫类型的题目会有更深的理解。
例题1:攻防世界-reverse_re3
第一步
首先看有无壳,直接丢到exeinfope—发现是elf文件是linux的可执行程序

第二步
反手丢进ida看到main 直接F5反编译看一手

第三步
一个一个函数来,sub_11B4双击点开好像没啥东西,看看sub_940
1 | |
这里留个心眼,flag是要输入的md5值
接下来分析wasd到底是怎么走的(像这种题大概率就是迷宫图,所以要明白它是怎么运动的)
先打开sub_E23康康

第四步
千万不要给这几个变量绕晕了
dword_202020:其实就是题目给的地图,可以双击进去看看(shift+e 提取数据)
dword_202AB0:代表哪个迷宫,此题有3个迷宫(至于为什么后文会提及)
dword_202AB4:代表行(因为15*,说明可能是一行15个数字,大胆猜测!)
dword_202AB8:代表列
225:地图尺寸15*15
这里我转换了一下不容易混淆

第五步
第一个if!=14 是因为跟下标有关系,一行15个数字下标最大是14,我们这个函数是”d“的操作也就是向右移,所以是如果下标等于14的话就不能再”d“了
第二个if 判断当前位置右移的数字是不是1,如果是将该位置标志为3,之前的位置标志为1,其实就是暗示我们1是可以走的,而3其实是我们的起点,如果不理解后面看看迷宫就明白了,
第三个if如果右移后是4就返回1,说明4就是我们的终点
再看看上下移动的函数(下图是”s“的函数,也就是下移)——有一些题目上下移动不是单纯的往上或者往下 而是斜向下或者斜向上噢

第六步
每次加15说明每次加一行
注意:这里分析的是右移”d“和下移”s“的函数至于”w“ ”a“都是差不多的,这里就不过多赘述了
再回到sub_940函数

第七步
这里的dword_202AB0==2 我们在前面提到它可能是标识哪一个迷宫的,这里说==2的话就break,否则就++,说明这里会循环3次,说明会有3个迷宫,接下来我们来看看这个稍微的迷宫长什么样。
双击点开前文提到的dword_202020

第八步
这密密麻麻的数字就是它的数据啦,现在按shift+e提取数据,然后导出来

这里有个大大大坑,就是dword类型的数据是4位一组,只取第一位作为数值,也就是说100010000111 最终会变成110 ,后3位是填充的,接下来就是怎么转换成一个迷宫了,网上一堆wp却几乎没有人提到如何去把这份原始数据转换成迷宫,下面我提供了一个python脚本针对这道题目,只要运行即可得到迷宫的样子,

一开始数据是这样的,先利用记事本的功能替换掉 ,和空格 以及前面的括号等等

之后利用一下py脚本即可完成转换
1 | |
之后可以将输出结果复制到word 改格式会好看一点

第九步
之后再按每15行为一个迷宫分成3个小迷宫,以3为起点4为终点进行运动,之后再md5加密即可得到flag
第一个迷宫
[1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[1, 1, 1, 1, 1, 0, 3, 1, 1, 0, 0, 0, 0, 0, 0]
[1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0]
[1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0]
[1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0]
[1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0]
[1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0]
[1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0]
[1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]
[1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0]
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
第二个迷宫
[1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[1, 1, 0, 3, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0]
[1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0]
[1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0]
[1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0]
[1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0]
[1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0]
[1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0]
[1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0]
[1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]
[1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0]
[1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0]
[1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0]
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
第三个迷宫
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
[0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0]
行动轨迹为:ddsssddddsssdssdddddsssddddsssaassssdddsddssddwddssssssdddssssdddss
经过md5编码后flag是flag{aeea66fcac7fa80ed8f79f38ad5bb953}
总结:
逆向遇到迷宫题的思路大概分2点
1.弄清楚移动的方式
2.分析迷宫图的尺寸
3.手动走迷宫或写脚本走迷宫(建议BFS算法)
例题2
查壳,放ida

注意flag是md5(留个心眼),然后去动态调试找flag,这个createmap非常显眼

先下个断点,然后开始调试

任意输入一些,然后去search map
这里的快捷键有ctrl+T,查找下一个text


找到后shift+E提取数据,然后放入我们的脚本文件


修改脚本中行列参数,运行脚本得到16*16的二维列表
将二维列表复制到【二.(一)】中的<脚本二:获得迷宫路径>中

分析check()函数得到起点坐标为(15, 1),且本题未给出确切终点而是在main函数中给出了路径长为54
并且用aswd键位移动


这里附上最终代码
1 | |
exp
1)
1 | |
2)
1 | |
wsad可以根据题目要求更改键位
3)
1 | |
例题3 doublegame

运行

ctrl F搜索gameover出现的地方,然后x查找调用函数

(key非预期)发现有个可疑的数据,是key=13371337

key正常

发现key ^0x1DC4=13376013

静态分析发现,sub_14001136B函数是第二关,将去第二关路上的 if的字节码全部修改为相反的, 然后patch,重新调试 (记得备份)
或者找到迷宫,

先拿出迷宫
1 | |

然后运行脚本
exp
1 | |

更新: 2024-07-29 17:33:02
原文: https://www.yuque.com/chaye-apqbl/vsc85q/qpt77zl7ce0pzudz