Hackergame 2021 题解
Contents
Hackergame 2021(中科大第八届信息安全大赛)个人题解
年份 | id | 分数 | 总排名 | 组内排名 |
---|---|---|---|---|
2020 | 3223 | 1300 | 297 | 46 |
2021 | 450 | 3100 | 45 | 7 |
题目及其余题解见 hackergame2021-writeups
环境
- Ubuntu 20.04
- Python 3.8
- Mathematica 12
1. 签到
不是去年的检查元素。观察发现 URL 会变,于是用二分法。
2. 进制十六——参上
用十六进制编辑器,例如 okteta。
这题的难点在于将十六进制数正确地输入编辑器,我就输错了很多次
3. 去吧!追寻自由的电波
一开始什么都听不出来,注意到题目中说
录音的速度有所改变
但是一般的慢放不行,需要修改采样率
|
|
然而还是听不懂,再查
使用了无线电中惯用的方法来区分字符串中读音相近的字母,
这是 字母解释法。
4. 猫咪问答 Pro Max
- 在 web archive 上找到历史内容 信息安全俱乐部社团章程
- 找到了 中国科学技术大学 Linux 用户协会介绍,不过不能确定是 4 还是 5,因为没有更新 2021 年的情况
实地考察- 找到相应的文档 SIGBOVIK 2021,这篇文章的后 13 张图分别展示了一个数据集
- 查找该文档 IETF : Establishing the Protocol Police,注意是阅读正文部分的 Reporting Offenses,而不是末尾的 Email
5. 卖瓜
6 和 9 怎么凑出 20 ?当然是用溢出啦
经试验,在 6 的地方输入 3000000000000000000
,然后在 9 的地方输入 49638230412172404
即可
6. 透明的文件
搜索 “cmd 打印 颜色”,找到了相似的内容:Python 打印带颜色的 log
在所有 [
前加 \x1B
,然后再 type
,然而并没有显示。
后来偶然间(为第 17 题装的 conda 导致环境变量有问题,错误提示恰好把前两行占掉了)发现运行命令后左边的文字有些不寻常,于是
7. 旅行照片
查阅资料意识到根据街景识别几乎不可能。起初以为地点藏在图像的 Exif 数据里,虽然我看到了“未采取隐写措施”。
题目中多次出现了 “KFC”,我一开始就查到了但当时不认为是同一个,于是开始沿着海岸线找……
后来再次按照 “KFC 沙滩 停车场” 进行搜索,确认是秦皇岛的。用百度地图查电话号码,用全景查左侧的文字。不过剩下 3 个迟迟无法确定,最后是用 pyautogui
辅助点击枚举出来的。
8. FLAG 助力大红包
点击助力按钮时,发送 POST 请求,请求内容包括 IP
,直接修改此处的 IP 只会修改前端 IP,会提示 “前后端 IP 地址不匹配”。
搜索“后端 IP”,找到了 http 请求头部的 client_ip 是如何获取的? ,其中提到 X-Forwarded-For
这个请求头。不过向目标网站发送的请求中并没有这个请求头。
而 伪造 HTTP 请求 IP 地址 中说可以追加这个请求头。经测试,增加 X-Forwarded-For
可以修改后端 ip,于是编写代码
|
|
9. Amnesia
(1) 轻度失忆
经过尝试,printf
不能用,而 putchar
可以使用。主要代码如下,完整程序见 9.cpp
|
|
官方题解里说可以直接
putchar
字符
10. 图之上的信息
发现登录时 POST 请求了 graphql 文件
在了解 GraphQL 的语法,一开始以为和 SQL 注入有关,用“sql注入 graphql” 查到了 渗透测试之 graphQL
其中提到了内省查询 __schema
。发送下面的 POST 请求可以查询到结构信息
|
|
响应内容中 GUser
有 privateEmail
字段,因此发送以下请求即可。
|
|
11. Easy RSA
首先计算 p
。x 与 y 都是素数,可以使用 威尔逊定理 $(p-1)! \equiv -1 \pmod{p}$
注意是与 -1 同余,我一开始记成 1 了
|
|
再计算 q
。$prevQ^e \equiv valueQ \pmod{n}$,而 $n= \prod value_i$,故 $prevQ^e \equiv valueQ \pmod{value_i}$
|
|
然后参考 RSA 介绍 求出原数字
|
|
最后用以下 python 代码写 flag 文件
|
|
13. 赛博厨房
(1) LEVEL 0
菜谱只会在 0, 1 之间变化,多保存几次就会刷新。参考代码:
|
|
(2) LEVEL 1
需要 73 个物品 0,而最多限制 72 行。只能使用 如果手上的物品大于等于 n 向上跳转 m 行
这条语句。
观察示例程序执行记录发现该语句是说代码跳
m
行,而不是说机器人移动多少步
|
|
14. 灯,等灯等灯
(1) LEVEL 0
完整代码见 14.wl
从网页的 js 文件中获得 target
矩阵
|
|
我一开始使用了较为复杂的方法(自行编程把变量减少到 24,因为对于这么多含
Mod
的方程,FindInstance
无法解出),后来发现加选项Modulus -> 256
就可以了。
然后使用 pyautogui
控制鼠标进行点击
17. Micro World
exe 这么大,怀疑是 python,用 IDA 查找字符串证实了这一点
使用 pyinstxtractor 可以获得 pyc 文件
用 uncompyle6 可以将 pyc 文件转换为 python 源代码,但运行时只有一个点。查阅资料后发现这是 代码混淆,pyc 中存在一些跳转指令;里面还指出可以用 dis.dis(更推荐使用 pydisasm)将 pyc 翻译成指令码。
题目描述是
粒子初始化为 flag,程序记录了一段时间之后的运动情况
观察大部分正确的 python 代码,发生的应该不是非弹性碰撞(没有出现 0.9 之类的数字)。经测试,直接修改 fps 不会影响到运动状态,所以只能把各点的速度反向。
一开始想在较高层面(指令码)修改。将指令码转成 pyc 的工具有 xasm,但这个工具无法处理列表赋值的情况。所以只能修改 pyc 字节码。
在 py 文件中修改一些数字的符号,用 python3 -m
生成 pyc 文件。发现对于正数, pyc 中某个字节由 3B
变为 FB
;而对于负数,由 FB
变为 3B
。
编写 trans.py ,主要逻辑如下,把中间间隔 8 个字符的一对 3B
/FB
换成相反的。
|
|
位置不会被改变符号可能是因为其绝对值比较大
用 check.py 检查指令码,发现多修改了一处,手动改回来。diff
确认指令码没有问题
运行,使用 VLC 录屏并逐帧查看
23. 马赛克
完整代码见 23.wl
将二维码的每个模糊的格子视为一个变量。按每个马赛克方块的灰度值列方程
|
|
对于每一个方程,将每个变量在 0, 1 范围内枚举。若有多个解,取每个解中值都相同的变量
经试验,单纯地只取有单个解的方程的解,不能做出此题
|
|
将每次确定的解代入方程,进行迭代计算。
|
|
虽然还剩余一部分没有解出,但在此 QR 码的容错范围内。
25. 密码生成器
刚做这题的时候象征性地打开了 IDA 和 x64dbg,由于我不会逆向(比赛前两天才安装)并且也不想逆向,什么都没能发现。
注意到密码生成器没有提供任何输入,且每次运行都有较长的延迟,更奇怪的是,题目中每句话都不离时间:
网页显示时间的时区改到了 Asia/Shanghai,我说怎么打印出来总是差 8 个小时。 【由用户 admin 于 2021-09-22 23:40 发布】 【由用户 admin 于 2021-09-22 23:39 发布】 于 2021-09-22 23:11 注册
怀疑生成的密码和系统时间有关。经测试,在相同的秒数会显示相同的密码。
所以将日期调整为 2021 年 9 月 22 日。编写脚本,用 time
命令调整时间(需要管理员权限)至 23:11 附近,用 pyautogui
点击密码生成器的按钮并将输出的密码粘贴到文本编辑器中。
|
|
最后用 pyautogui
输入用户名和密码并进行提交(这样提交比较有仪式感)
IDA 也就图一乐,真做逆向还得靠
pyautogui
27. JUST BE FUN
- 解题过程:读代码,写代码(建议将 python 文件中的背景字符换成空格,合理使用 Insert 键),调代码(条件断点)。
- 此题要求:写一个三维空间的程序,读入 9 以下的数字和 6 种运算符,计算结果。
- 主要思路:先读一个操作数,读入运算符,按运算符进行分类读入操作数并计算,再读下一个运算符……
调试结果为 1++
由于看了使用说明后仍然不知道如何发送超过 4096 字节的数据,我使用两层的结构把它优化到了 4096 字节以下。两层分别为 2-1 2-2
修改后的 python 文件为 be_fun+.py 由“三维代码”生成 python 输入的文件为 generate.wl
Author GWDx
LastMod 2024-06-28 (d7fee4f)