SWPUCTF 2021 新生赛-老鼠走迷宫

admin 2023年12月26日07:38:54评论18 views字数 6737阅读22分27秒阅读模式
附件下载
https://wwvc.lanzouj.com/iYLez1br84jg

解题思路

◆用pyinstxtrator解析exe。
◆重点:将无后缀的5先修改后缀为pyc,然后随便找一个pyc文件补齐5.pyc的前16位十六进制数值(这道题以struct.pyc为例)。
◆将.pyc反编译为.py。
◆找到maze,从而找到最短路径。

改后缀


下载附件,拿到一个无后缀的文件,丢入winhex里看看,发现是MZ开头的,去搜MZ开头是什么文件。


SWPUCTF 2021 新生赛-老鼠走迷宫

MZ开头的是.EXE可执行文件。


SWPUCTF 2021 新生赛-老鼠走迷宫
修改后缀:


SWPUCTF 2021 新生赛-老鼠走迷宫

查壳

64位,无壳,但是该exe是被pyinstaller打包后得到的,我们需要将exe转换为py形式。


SWPUCTF 2021 新生赛-老鼠走迷宫


python反编译

pyinstxtractor.py自行下载,在这个页面打开cmd。


SWPUCTF 2021 新生赛-老鼠走迷宫

使用pyinstxtractor.py反编译exe文件,命令如下:


python pyinstxtractor.py 可执行文件exe的地址


SWPUCTF 2021 新生赛-老鼠走迷宫

在当前文件夹会多出一个文件夹。SWPUCTF 2021 新生赛-老鼠走迷宫

可以看到可疑的文件5,structSWPUCTF 2021 新生赛-老鼠走迷宫

这里我们需要先将文件5和struct加上后缀.pyc,因为后续需要进行.pyc反编译成.py文件(其实struct可要可不要,struct的作用就是给5.pyc补齐前面缺失的十六进制数值,将其他的正常的.pyc文件替换struct.pyc也可以,因为我发现.pyc文件的前16位数值都是一样的)。


SWPUCTF 2021 新生赛-老鼠走迷宫

在winhex打开两个pyc文件,将struct的前16位十六进制数复制到5.pyc开头。


SWPUCTF 2021 新生赛-老鼠走迷宫
SWPUCTF 2021 新生赛-老鼠走迷宫

记得保存。


SWPUCTF 2021 新生赛-老鼠走迷宫

将5.pyc文件反编译成.py文件,网址:https://tool.lu/pyc/
SWPUCTF 2021 新生赛-老鼠走迷宫

down下来,得到一个python文件。

#!/usr/bin/env python # visit https://tool.lu/pyc/ for more information # Version: Python 3.7 import random import msvcrt (row, col) = (12, 12) (i, j) = (0, 0) maze = [ [ 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], (……省略,参考源文章)
print('Mice walk in a maze: wasd to move,q to quit') print("flag is the shortest path's md5,example:if the shortest path is wasdsdw,the flag is md5('wasdsdw')") (i, j) = (0, 1) n = 0 while i == row * 2 and j == col * 2 - 1: print('ohhhh!!!!you did it') break print('your position:({},{})'.format(i, j)) inp = msvcrt.getch() n += 1 ti = i tj = j if b'a' == inp and i > 0: tj -= 1 elif b'w' == inp and j > 0: ti -= 1 elif b's' == inp and j < row * 2: ti += 1 elif b'd' == inp and i < col * 2: tj += 1 elif b'q' == inp: exit('bye!!') else: print('What???') if maze[ti][tj] == 1: print(random.choice([ 'no wayy!!', "it's wall", 'nop'])) continue elif maze[ti][tj] == 0: print(random.choice([ 'nice!!', 'yeah!!', 'Go on'])) i = ti j = tj return None

在maze下面添加一个for循环,输出maze,会报错,把最下面的return none直接删了,这不是重点不要紧。

修改之后的代码,可以直接输出maze。

#!/usr/bin/env python # visit https://tool.lu/pyc/ for more information # Version: Python 3.7 import random import msvcrt (row, col) = (12, 12) (i, j) = (0, 0) maze = [ [ 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], (……省略,参考源文章)
for row in maze: print(row) print('Mice walk in a maze: wasd to move,q to quit') print("flag is the shortest path's md5,example:if the shortest path is wasdsdw,the flag is md5('wasdsdw')") (i, j) = (0, 1) n = 0 while i == row * 2 and j == col * 2 - 1: print('ohhhh!!!!you did it') break print('your position:({},{})'.format(i, j)) inp = msvcrt.getch() n += 1 ti = i tj = j if b'a' == inp and i > 0: tj -= 1 elif b'w' == inp and j > 0: ti -= 1 elif b's' == inp and j < row * 2: ti += 1 elif b'd' == inp and i < col * 2: tj += 1 elif b'q' == inp: exit('bye!!') else: print('What???') if maze[ti][tj] == 1: print(random.choice([ 'no wayy!!', "it's wall", 'nop'])) continue elif maze[ti][tj] == 0: print(random.choice([ 'nice!!', 'yeah!!', 'Go on'])) i = ti j = tj
[1, 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, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1]
[1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1]
[1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1]
[1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1]
[1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1]
[1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1]
[1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1]
[1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1]
[1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1]
[1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1]
[1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1]
[1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1]
[1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1]
[1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1]
[1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1]
[1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1]
[1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1]
[1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1]
[1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1]
[1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1]
[1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1]
[1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1]
[1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 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, 0, 1]
Mice walk in a maze: wasd to move,q to quit
flag is the shortest path's md5,example:if the shortest path is wasdsdw,the flag is md5('wasdsdw')
Process finished with exit code 0
接下来可以自己慢慢找,也可以写脚本,我直接从(https://blog.csdn.net/qq_42880719/article/details/120581571)那拉的脚本,可以直接输出迷宫的最小路径。

dirs = [(0, 1), (1, 0), (0, -1), (-1, 0)] # 当前位置四个方向的偏移量 path = [] # 存找到的路径 def mark(maze, pos): # 给迷宫maze的位置pos标"2"表示“倒过了” maze[pos[0]][pos[1]] = 2 def passable(maze, pos): # 检查迷宫maze的位置pos是否可通行 return maze[pos[0]][pos[1]] == 0 def find_path(maze, pos, end): mark(maze, pos) if pos == end: print(pos, end=" ") # 已到达出口,输出这个位置。成功结束 path.append(pos) return True for i in range(4): # 否则按四个方向顺序检查 nextp = pos[0] + dirs[i][0], pos[1] + dirs[i][1] # 考虑下一个可能方向 if passable(maze, nextp): # 不可行的相邻位置不管 if find_path(maze, nextp, end): # 如果从nextp可达出口,输出这个位置,成功结束 print(pos, end=" ") path.append(pos) return True return False def see_path(maze, path): # 使寻找到的路径可视化 for i, p in enumerate(path): if i == 0: maze

]

] = "E" elif i == len(path) - 1: maze

]

] = "S" else: maze

]

] = 3 print("n") for r in maze: for c in r: if c == 3: print('&#x0;33[0;31m' + "*" + " " + '&#x0;33[0m', end="") elif c == "S" or c == "E": print('&#x0;33[0;34m' + c + " " + '&#x0;33[0m', end="") elif c == 2: print('&#x0;33[0;32m' + "#" + " " + '&#x0;33[0m', end="") elif c == 1: print('&#x0;33[0;;40m' + " " * 2 + '&#x0;33[0m', end="") else: print(" " * 2, end="") print() if __name__ == '__main__': maze = [ [1, 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, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1], [1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1], [1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1], [1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1], [1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1], [1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1], [1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1], [1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1], [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1], [1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1], [1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1], [1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1], [1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1], [1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1], [1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1], [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1], [1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1], [1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1], [1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1], [1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1], [1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1], [1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 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, 0, 1]] start = (0, 1) end = (24, 23) find_path(maze, start, end) see_path(maze, path)


迷宫最短路径。


SWPUCTF 2021 新生赛-老鼠走迷宫

使用wasd表示最短路径就是(一定不要忘了最后一个 * 还需要往下走一个才到达终点,我服,看了半天才找到这个错误):
sssssddssddssaaaassssddwwddddssssssaawwaassssddssaassddddwwddssddwwwwwwwwaawwddwwwwaaaawwddwwwwddssssddwwwwddddwwddddssaassaassddddssddssaassssssddsssssss

根据python里面的内容,flag是用wasd表示的最短路径的md5值。


SWPUCTF 2021 新生赛-老鼠走迷宫

取32位小写,69193150b15c87d39252d974bc323217。

SWPUCTF 2021 新生赛-老鼠走迷宫

flag:NSSCTF{69193150b15c87d39252d974bc323217}

SWPUCTF 2021 新生赛-老鼠走迷宫

看雪ID:Zer0_0

https://bbs.kanxue.com/user-home-945402.htm

*本文为看雪论坛优秀文章,由 Zer0_0 原创,转载请注明来自看雪社区

原文始发于微信公众号(看雪学苑):SWPUCTF 2021 新生赛-老鼠走迷宫

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年12月26日07:38:54
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   SWPUCTF 2021 新生赛-老鼠走迷宫http://cn-sec.com/archives/2227014.html

发表评论

匿名网友 填写信息