【困难】智慧学园的召集令

给了一个 exe ,要求输入几个选择题的答案和一个幸运数字,全部正确就可以得到 flag 了。

实际上刚开始我挺害怕真的有资深的老二次元把这个题目全部写对了(毕竟好像不是很难),猜数字的 486 实际上也是非常的明显的(应该吧)。

不过你不是二次元也没有关系,我们可以用 python 反汇编的方法加上 z3 解方程轻松将这一题搞定。

嘀咕:486 还是太小了,我竟然看到有人用爆破的方式,写出了,可恶(早知道用本文中最后一行提到的数字了)。

先把 exe 转为 pyd 文件,提供一个在线网站:PyInstaller Extractor WEB,当然用 pyinstaller 也可以。然后在文件中找到 round3.pyc 文件,用 pycdc 反汇编(或在线网站)。

反编译加上一点点的修改得到的源码:

background = """
在二次元的异世界——幻想界,有着一所名为“智慧学园”的魔法学校。这所学园不仅传授魔法,还教导学生们如何运用现代技术解决各种难题。为了庆祝学园的成立纪念日,校长宣布将举行一场名为“智慧解谜大冒险”的特别竞赛。竞赛的任务是在学园内寻找并收集被魔法保护的二次元魔法碎片。只有解开守护着这些碎片的谜题,才能获得它们。

据传,集齐所有魔法碎片的队伍将能够召唤出传说中的“智慧女神”,她将实现获胜队伍的一个愿望。然而,这些谜题可不是那么容易就能解开的,它们包含了数学与编程的挑战,考验着参赛者的智慧和勇气。

\033[1;36m
【智慧学园的召集令】

尊敬的冒险者们,

欢迎来到智慧学园,在这里,魔法与现代科技相互辉映,创造出独一无二的奇迹。为了庆祝学园的成立纪念日,我们特地举办了“智慧解谜大冒险”竞赛!

任务:集齐所有的二次元魔法碎片,并利用这些碎片召唤出“智慧女神”。
规则:每个谜题都会引导你前往学园的不同地点。解开谜题,收集魔法碎片,最终召唤出“智慧女神”,实现你的愿望!
提示:谜题可能涉及一定的数学、编程知识。准备好你的智慧与勇气,让我们一起踏上这场神奇的旅程吧!

在收集完所有魔法碎片之后,传说中的“智慧女神”将会出现。但是,她会要求你输入一个幸运数字。只有当你所输入的幸运数字与所有魔法碎片的答案完美匹配时,你才能获得最终的宝藏——FLAG!

祝你好运,勇敢的冒险者们!
\033[0m
"""

problem = [
"""
1. 在JOJO 中,空条承太郎的舅舅的母亲是谁?
    A.	丝吉 · Q
    B.	东方朋子
    C.	荷莉·乔斯达
    D.	莉莎莉莎
    E.	艾莉娜·潘德鲁顿
""",
"""
2.下面角色中不全为子安武人配音的是:
    A.	《咒术回战 第二季》 伏黑甚尔 ;《伪恋:》 克劳德;
    B.	《死神》 沛薛·卡迪谢;《银魂》 高杉晋助;
    C.	《JOJO的奇妙冒险:星尘斗士》 DIO;《刀剑神域》 须乡伸之;
    D.	《Re:从零开始的异世界生活》 罗兹瓦尔·L·梅札斯;《夏色奇迹》 佐野贵史;
    E.	《天空战记》 夜叉王盖伊;《海贼王》青雉;
""",
"""
3.在JOJO 中,下面替身与替身面板对应不正确的是(按照 “破坏力”、“速度”、“射程距离”、“持续力”、“精密动作性”、“成长性” ):
    A.	愚者 —— BCDCDC
    B.	灰塔 —— EAACEE
    C.	心锁 —— EEAAEE
    D.	辛红辣椒 —— AAAACA
    E.	紫烟 —— ABCEEC
""",
"""
4.在《葬送的芙莉莲》中,芙莉莲一行人在哪一年再次见到了佛尔爷爷:
    A.	辛逝纪28年
    B.	辛逝纪29年
    C.	辛逝纪30年
    D.	辛逝纪31年
    E.	辛逝纪32年
""",
"""
5.《我的青春恋爱物语果然有问题》中,在初中给企比谷八幡发卡的人被谁喜欢: 
    A.	玉绳
    B.	大冈
    C.	相模
    D.	秦野
    E.	叶山隼人
""",
"""
6.《NO GAME NO LIFE 游戏人生》中,最后击败吉普莉尔用的词汇是:
    A.	暗弱
    B.	强力
    C.	库仑力
    D.	大气层
    E.	氧气
""",
"""
7.下列以御坂美琴的基因为蓝本的克隆体番号与对应事迹不匹配的是:
    A.	20001:最后之作,是御坂网络的管理者,会话时有“御坂XXX地说道”的口癖。和妹妹们不同的是,具有丰富的表情,性格活跃。
    B.	9982:是御坂美琴碰到的第一位妹妹。其与美琴度过了一个如姊妹般美好的下午,并得到了美琴赠送的呱太徽章。
    C.	10031:上条当麻碰到的第一位妹妹。因存在“对姐姐来说御坂是个想予以否定掉的存在”的想法而感到自卑。
    D.	19090:布束砥信在其脑内植入了感情程序,但因最后之作的拦截而导致仅自身拥有更为丰富的感情。
    E.	10050:“绝对能力进化计划”实验破产后被发配危地马拉萨卡帕。
""",
"""
8.青春猪头少年男主与朋绘'击股之交'在哪个公园发生的:
    A.	湘南海岸公园
    B.	七里之滨
    C.	江之岛
    D.	御所之谷公园
    E.	御所之谷桥
""",
"""
9.下列选项中中,不全为世萌萌王的是:
    A.	御坂美琴 五河琴里 
    B.	雷姆 薇尔莉特·伊芙加登 
    C.	千反田爱瑠 夏娜
    D.	雪之下雪乃 立华奏 
    E.	桂雏菊 逢坂大河 
"""
]

print(background)
user_answer = [''] * len(problem)

for i in range(len(problem)):
    print(f'\n\033[1;32m你发现了第{i+1}个碎片:')
    print(problem[i]+'\033[0m')
    # 确保用户输入的答案为A、B、C、D、E中的一个
    user_input = input('请输入你的答案:')
    while user_input not in ['A', 'B', 'C', 'D', 'E']:
        print('\033[1;31m输入有误,请重新输入!\033[0m')
        user_input = input('请输入你的答案:')
    user_answer[i] = user_input
    
print("你发现了所有的碎片,现在需要输入一个幸运数字,智慧女神会验证你所有的输入")
lucky_number_input = input('请输入幸运数字:')
while not lucky_number_input.isdigit() :
    print('\033[1;31m输入有误,请重新输入!\033[0m')
    lucky_number_input = input('请输入幸运数字:')

print("您的所有答案:",end="")
tmp = ""
for i in range(len(user_answer)):
    tmp += user_answer[i] + "_"
tmp += str(lucky_number_input)
print(tmp)
print("\n智慧女神正在验证答案,请稍等...")

a = [ord(i) for i in user_answer]
l = int(lucky_number_input)

import hashlib
if (a[1]*33 + a[2] + a[3]*0xFF + a[4]*5 - a[5]*44 + a[6]*23 + a[7] + a[8] - a[0] == 18086 and
    a[1]*123121 + a[2]*456 + l*0x1145 + a[4]*789 + a[6]*111 + l*222 == 10718690 and
    a[3] * 114514 + a[5] * 1919810 + l * 233 + a[7] * 23333 + a[0] * 66666 == 142285032 and
    a[1]*2 + a[2]*223 + l*4 + a[4]*2123 + a[6]*212 + l*22 - a[8] == 179865 and
    a[1]*3 + a[2]*3  + a[0]*3 + l*3 - a[8]*3 + a[7]*2 == 1996 and
    (a[1] - a[2] + a[3] - a[4] + a[5] + a[6]*89 + a[7] - a[8] + a[0]*89 - l) * 22 == 247258 and 
    (a[1] + 90*a[2] - a[3] + a[4] * a[5] * a[6] + a[7] + a[8] + 90*a[0]) * 245 + l * 2 == 72365152 and
    (a[1] + a[5] + a[6] + a[7] + a[8] + a[0]) * 35 + l * 3 == 15563 and 
    a[1] * a[2] * a[3] * a[4] * a[5] * a[6] * a[7] * a[8] * a[0] * 4 + l == 108583887289363686 and 
    a[1] + a[2]*345 - a[3] + a[4]*24 + a[5]*856 - a[6] - a[7] + a[8]*1212 + a[0] + l*33 == 182318
    ):
    print('\033[1;32m恭喜你,你发现了所有的碎片!\033[0m')
    print('\033[1;32m现在,智慧女神将给予你flag:\033[0m')
    print('nex{'+hashlib.md5(tmp.encode()).hexdigest()+'}')
else:
    print('\033[1;31m很遗憾,你并没有完全正确,请再接再厉!\033[0m')
    print('\033[1;32m悄悄地告诉你,本题需要用到了解 python exe 反汇编以及 ...\033[0m')

看到了这里,相信你已经明了了,里面有一大串的方程,如果你提前得到了部分题目的答案,那么你就可以尝试解方程,得到答案,然后通过这个答案和幸运数字,得到flag。当然,如果你没有提前得到答案,但是得到了方程组,也并不影响用 z3 求解。

from z3 import *

# 定义变量
a = IntVector('a', 9)  # 创建长度为9的整数向量
l = Int('l')  # 创建额外的变量l

# 创建Solver实例
s = Solver()

# 添加方程
s.add(a[1]*33 + a[2] + a[3]*0xFF + a[4]*5 - a[5]*44 + a[6]*23 + a[7] + a[8] - a[0] == 18086)
s.add(a[1]*123121 + a[2]*456 + l*0x1145 + a[4]*789 + a[6]*111 + l*222 == 10718690)
s.add(a[3] * 114514 + a[5] * 1919810 + l * 233 + a[7] * 23333 + a[0] * 66666 == 142285032)
s.add(a[1]*2 + a[2]*223 + l*4 + a[4]*2123 + a[6]*212 + l*22 - a[8] == 179865)
s.add(a[1]*3 + a[2]*3 + a[0]*3 + l*3 - a[8]*3 + a[7]*2 == 1996)
s.add((a[1] - a[2] + a[3] - a[4] + a[5] + a[6]*89 + a[7] - a[8] + a[0]*89 - l) * 22 == 247258)
s.add((a[1] + 90*a[2] - a[3] + a[4] * a[5] * a[6] + a[7] + a[8] + 90*a[0]) * 245 + l * 2 == 72365152)
s.add((a[1] + a[5] + a[6] + a[7] + a[8] + a[0]) * 35 + l * 3 == 15563)
s.add(a[1] * a[2] * a[3] * a[4] * a[5] * a[6] * a[7] * a[8] * a[0] * 4 + l == 108583887289363686)
s.add(a[1] + a[2]*345 - a[3] + a[4]*24 + a[5]*856 - a[6] - a[7] + a[8]*1212 + a[0] + l*33 == 182318)

# 添加约束,使得a[i]只能取值 A 到 E
for i in range(9):
    s.add(a[i] >= ord('A'))
    s.add(a[i] <= ord('E'))

# 求解
result = s.check()

if result == sat:
    m = s.model()
    print("Solution found:")
    solution = {}
    for i in range(9):
        solution[f"a[{i}]"] = chr(m[a[i]].as_long())  # 将数字转换为字符
    print(solution)
    print(f"l = {m[l]}")
else:
    print("No solution.")

运行结果:

{'a[0]': 'B', 'a[1]': 'D', 'a[2]': 'E', 'a[3]': 'B', 'a[4]': 'A', 'a[5]': 'C', 'a[6]': 'A', 'a[7]': 'D', 'a[8]': 'E'}
l = 486

把结果输入回源程序中,得到flag。

智慧女神正在验证答案,请稍等...
恭喜你,你发现了所有的碎片!
现在,智慧女神将给予你flag:
nex{2f5acc1c30ab1174fe649feac9fd110e}

什么?你会得到 flag 但是不会二次元的题目,行吧,看看这个:

  1. JOJO 家谱图: JOJO 家谱图

  2. 子安武人_百度百科: 子安武人_百度百科

  3. 紫烟面板图: 紫烟面板图

  4. 详细见《葬送的芙莉莲》第16集——长寿的朋友。

  5. 《我的青春恋爱物语果然有问题》中,在初中给企比谷八幡发卡的人被玉绳喜欢。 1

  6. 库仑力 看过的都会把,不知道可以看看《游戏人生》,好看捏。

  7. 御坂妹妹 - 萌娘百科 万物皆可萌的百科全书 (moegirl.org.cn) 会话时则有 “御坂御坂XXX地说道” 的口癖,而非其他妹妹的 “御坂XXX地说道”。

  8. 《青春猪头少年》巡礼地点大公开(Google坐标强力定位)

  9. 盘点历代日萌萌王和世萌萌王

幸运数字:486,知道的人会心一笑,这个数字的来源还挺多的:安和昴菜月昴、少女乐队也有 486……

题外话:我本来想要把幸运数字改为 0x0d000721 但是我怕没有人懂我,所以改为 486Ciallo~(∠・ω< )⌒☆