这一篇应该是我写过的最短的文章了。
个人赛+团体赛,不能和队员交流就很阴间,好吧整个赛制就很阴间。
两题逆向,C++基础太薄弱了…boost test摸不到头脑。
pyc
拿到手uncompyle6跑一下,就知道文件头被改了,看了下大小,代码量比较小干脆就直接撸字节码了。
import marshal, dis fp = open("mtctf/Final/pyc.pyc", 'rb') fp.seek(16) co = marshal.load(fp) dis.dis(co)
字节码还原之后,主逻辑如下
# -*- coding:utf-8 -*- """ @Author: Mas0n @File: mtctff1.py @Time: 2021-12-19 10:06 @Desc: It's all about getting better. """ import hashlib s = input() if len(s) == 72: a1 = set() a2 = set() a3 = set() a4 = [0x9e3779b9, 0x9e3779b9] for d in "012345678": a3.add(s.count(d)) for i in range(0, len(s), 9): for l in range(0, 15, 2): a2.add(sum((int(s[i + j:i + j + 1]) for j in [int(v) for v in str(a4[1] ^ 64201746666225664 ^ 3446703994)[l:l + 3]]))) if int(s[i:i + 9]) < a4[0]: a4[0] = int(s[i:i + 9]) a1.add(s[i:i + 9]) if len(a1) == 8 and len(a2) == 1 and len(a3) == 1 and s.count('9') == 0: print('flag{' + hashlib.md5(s.encode('ascii')).hexdigest() + "}") exit() print("wrong")
分析代码很难看出流程,只知道一些条件
- 输入字符区间0~8
- 输入长度72位
- 9位一组,每组又分8次取索引对应值求和
- 每一组都要比前一组的值小,
且最大值小于0x9e3779b9(没啥用) - 每次sum的和为唯一值
逻辑很模糊,还是分析一下核心点sum究竟在做些什么
# a4[1] ^ 64201746666225664 ^ 3446703994 > 0x9e3779b9 ^ 64201746666225664 ^ 3446703994 > 64201748063452867 > idxArr = [6, 4, 2, 0, 1, 7, 4, 8, 0, 6, 3, 4, 5, 2, 8, 6, 7] > for i in range(0, 72, 9): > for l in range(0, 15, 2): > print(idxArr[l:l+3]) [6, 4, 2] [2, 0, 1] [1, 7, 4] [4, 8, 0] [0, 6, 3] [3, 4, 5] [5, 2, 8] [8, 6, 7] ···
画一张3×3的图,一切都很清晰了
| 0 | 1 | 2 | | 3 | 4 | 5 | | 6 | 7 | 8 |
特征是行列斜对角和都相等
想到是3阶幻方…
知道是幻方就能做了,偷懒找了张网图直接抄
整体值-1
排序拼接
723048561705246381561048723507642183381246705327840165183642507165840327
放回脚本跑就可以了
发表回复