Hackergame2022 writeup(部分)
Hackergame 我真的好喜欢你啊,为了你…… 。我真的好喜欢 Hackergame 的题目脑洞,科技与人文趣味……,做起来就很对我的胃口(当然不会的还是好多)。看完官方题解的感觉是,好吧确实不会的基本都是不会了。以后多多学习吧。。
签到
随便画一画,发现很明显手画不太好弄。提交一下,观察地址栏变动,发现 result
参数就是刚刚识别的值,随手修改一下,r然后过了。
和去年的题也比较类似,其实就是只在前端限制而没有后端限制的情况下,我们直接对前端做些手脚就好了。
猫咪问答喵
考验你的信息检索能力,多搜搜就可以啦~ 由于反馈给你一共对了几个,所以可以很方便的排除。
1.中国科学技术大学 NEBULA 战队(USTC NEBULA)是于何时成立的喵?
直接搜关键词:“USTC NEBULA 成立于”
https://cybersec.ustc.edu.cn/2022/0826/c23847a565848/page.htm
2017-03
2.2022 年 9 月,中国科学技术大学学生 Linux 用户协会(LUG @ USTC)在科大校内承办了软件自由日活动。除了专注于自由撸猫的主会场之外,还有一些和技术相关的分会场(如闪电演讲 Lightning Talk)。其中在第一个闪电演讲主题里,主讲人于 slides 中展示了一张在 GNOME Wayland 下使用 Wayland 后端会出现显示问题的 KDE 程序截图,请问这个 KDE 程序的名字是什么?
一开始我想和去年类似,我们直接搜相关的新闻,会不会正好有那张 slide 呢,于是搜到了 https://lug.ustc.edu.cn/news/2022/09/SFD/ 但是并没有找到我想要的答案。
后来想到这种活动一般都是有视频的,于是在 b 站搜了下果然有:https://www.bilibili.com/video/BV11e411M7t9 ,翻了好几次才找到大概是 2:42:10 这个时间点,用力仔细听出来了是:Kdenlive
。
3.22 年坚持,小 C 仍然使用着一台他从小用到大的 Windows 2000 计算机。那么,在不变更系统配置和程序代码的前提下,Firefox 浏览器能在 Windows 2000 下运行的最后一个大版本号是多少?
还是信息检索题,非常简单,直接搜:firefox latest version windows 2000
第一个就是答案:Firefox 12.0
,当然按照答案要求省略小数点:12
。
再不济也可以用一个一个一个一个试的方法试出来,其他题确定下来的情况下。
4.你知道 PwnKit(CVE-2021-4034)喵?据可靠谣传,出题组的某位同学本来想出这样一道类似的题,但是发现 Linux 内核更新之后居然不再允许 argc 为 0 了喵!那么,请找出在 Linux 内核 master 分支(torvalds/linux.git)下,首个变动此行为的 commit 的 hash 吧喵!
直接找到 Linux 内核 的仓库 https://github.com/torvalds/linux 然后搜索 CVE-2021-4034
就可以发现对应提交:https://github.com/torvalds/linux/commit/dcd46d897adb70d63e025f175a00a89797d31a43 ,答案就是:dcd46d897adb70d63e025f175a00a89797d31a43
。
5.通过监视猫咪在键盘上看似乱踩的故意行为,不出所料发现其秘密连上了一个 ssh 服务器,终端显示 ED25519 key fingerprint is MD5:e4:ff:65:d7:be:5d:c8:44:1d:89:6b:50:f5:50:a0:ce.,你知道猫咪在连接什么域名吗?
信息检索问题,首先定位关键词:MD5:e4:ff:65:d7:be:5d:c8:44:1d:89:6b:50:f5:50:a0:ce
.
多次拆分检索后可以在 Github 以 e4:ff:65:d7:be:5d:c8:44:1d:89:6b:50:f5:50:a0:ce
为关键词搜到完全一致的值:https://github.com/zeek/zeek-docs/blob/4bd4cf0233ba4d7585ce664f686eb4aff5ccb8dc/logs/ssh.rst 。来自 zeek 的文档。然后顺着下面看,可以看到一个 ip 地址。
1 | .. literal-emph:: |
找到 205.166.94.9
后,尝试搜索相关域名,由于提示了答案中不同的字母有 6 个,所以可以依次排除各个相同结果(后面又补充了域名的注册时间,这样就更好找了,不过我没有用到。其实多试几次也能排除其他的,不过我运气比较好第一个就对了)。
最后在 https://ipinfo.io/205.166.94.9 发现 sdf.org
。
中国科学技术大学可以出校访问国内国际网络从而允许云撸猫的“网络通”定价为 20 元一个月是从哪一天正式实行的?
信息检索题,以 网络通费用
为关键词多次检索搜到若干个通知,然后从 https://ustcnet.ustc.edu.cn/2010/1210/c11109a210869/page.htm 定位到 2003 年有个文件被废了,一路往前翻翻到了:https://ustcnet.ustc.edu.cn/2003/0301/c11109a210890/page.htm 。 就找到了答案:2003-03-01
。
家目录里的秘密
VS Code
下载后用 VS Code 打开,搜索 flag 相应关键词,发现在 user/.config/Code/User/History/2f23f721/DUGV.c
内有第一个 flag。 其实就是用 VSCode 的全局搜索, 不过这也提醒我们 VSCode 的缓存文件也是有泄露隐私的风险的(
RClone
同第一问,全局搜索 flag 相应关键词,发现 rclone.conf
文件内标有 flag 相应数据,一开始我以为是要连这个服务器用密码同步文件来着,但是里面的内容是:
1 | [flag2] |
很明显 ftp.example.com
没法连,文件内也没找到其他可以连接的地址, 尝试使用 base64
之类的解密,未果。 于是目标着眼在这个密码怎么解密上来。(主要是我之前并没有用过 RClone)。
搜索 Rclone password crypt
等相关信息。发现官方文档的说明(https://rclone.org/commands/rclone_obscure/ ) 以及官方论坛的讨论(https://forum.rclone.org/t/rclone-obscure-password-what-does-it-do/12692 )。
In the rclone config file, human-readable passwords are obscured. Obscuring them is done by encrypting them and writing them out in base64. This is not a secure way of encrypting these passwords as rclone can decrypt them - it is to prevent “eyedropping”
namely someone seeing a password in the rclone config file by accident.
Many equally important things (like access tokens) are not obscured in the config file. However it is very hard to shoulder surf a 64 character hex token.
即, RClone 对配置文件中密码的“加密”,是一种可逆的编码。只是为了防止别人一不小心看到他之类的场景。
于是继续寻找如何解密的方法。 搜了官方文档不知道为什么没有提到。 搜官方源码发现: https://github.com/rclone/rclone/blob/master/cmd/reveal/reveal.go 。尝试了一下
1 | rclone reveal tqqTq4tmQRDZ0sT_leJr7-WtCiHVXSMrVN49dWELPH1uce-5DPiuDtjBUN3EI38zvewgN5JaZqAirNnLlsQ |
得到第二个 flag。 后来发现 reddit 上也有人提到了。
HeiLang
作为一个编程爱好者,我觉得实在是太酷了,很符合我对未来编程语言的想象,科技并带着趣味。
就是把数组内多个数字的或运算符操作 a[1 | 2 | 3] = 4
变成 a[1] = 4; a[2] = 4; a[3] = 4
。嫌麻烦没考虑优雅随便写了个。只处理数组部分,需要把生成的代码拼接回原来中间的位置:
1 | codes = "" |
Xcaptcha
我们需要验证您是否确实不是真实用户
需要你快速回答问题后点击回答。 这种场景感觉再用 Python 之类的东西获取网页再如何如何操作或者用 chromedriver 怎样怎样太麻烦了。我选择写了一个油猴脚本。
1 | // ==UserScript== |
原理很简单,就是把题目读取进来然后填回去。 注意一下因为数字非常大,所以要用 BigInt
接一下。 放到油猴里直接进入网页点击就做完了。
旅行照片 2.0
又一年网络迷踪。 找飞机找哭系列(
照片分析
直接打开图片的 EXIF 第一问的信息都能看见。 比较坑的是 EXIF 2.3.1 要写作 EXIF 2.31
。
社工入门
首先对外面很明显的建筑进行谷歌识图。 可以发现是日本的千叶海洋球场(ZOZO Marine Stadium)。或者直接放大图片可以看到前面这个英文,一搜就搜到了。
酒店
请写出拍照人所在地点的邮政编码
使用地图在上面地点附近搜索 hotel
关键词,根据拍摄角度位置推算。可以选出好几个备选的酒店。 例如:APA HOTEL& RESORT TOKYO BAY MAKUHARI,可以看到邮政编码为 2610021
。附近符合角度的酒店大部分都是这个编码。 其他有不同的后面我选择了使用脚本枚举。
照片窗户上反射出了拍照人的手机。那么这部手机的屏幕分辨率是多少呢?
选择从第一题的信息入手。 第一题最后一问问你手机的品牌。 可以在 EXIF 中看到是 Xiaomi SM6115 (juice)
。后面是处理器的名称。搜索 SM6115
。可以发现是 骁龙 622
。 然后搜索 小米骁龙 622
(其实上一步就可能搜到了)。只能搜到 Redmi Note 9 4G
。 直接搜索此机型分辨率,得到答案 2340x1080
。
航班
仔细观察,可以发现照片空中(白色云上方中间位置)有一架飞机。你能调查出这架飞机的信息吗?
我不能
首先我们根据前面的信息可以在地图中搜索 ZOZO Marine Stadium 附近的机场。其实目标就只有两个:羽田机场(HND,东京国际机场)、成田国际机场(NRT)。
根据照片的朝向,则大概率是羽田机场的飞机。
有了这些初步信息,我们接下来就是要确定此航班是进港还是离港了。这一步如果是接触过相关问题和视频的人可能会很直接地想到 flightradar24 之类的网站。但是关键问题就是,大部分这些网站都只提供近期的数据。而历史数据需要会员才可以浏览。(看了题解才知道有)──────当然,你也可以开一个试用,到时候取消订阅。 我并没有这么做,而是采取了更笨的方法。主要是不想再绑一次信用卡了。
我使用的是另一个相似的网站:flightaware。原因是我直接以 2022/05/14 与 HND 之类的组合关键词搜索时,搜索到了该网站当日的一部分航班的结果。这不是最重要的。
以这个航班为例:
1 | https://flightaware.com/live/flight/ANA683/history/20221026/0915Z/RJTT/RJOA |
看到链接里的日期了吗?我们假设一下,这个航班在 20220514 也飞过。
1 | https://flightaware.com/live/flight/ANA683/history/20220514/0915Z/RJTT/RJOA |
ok 可以打开。这就说明,这个航班也在那一天飞过。 也就是说,我们只要找到当天的 HND 机场在照片所示的时间范围内的航班,再确定一下他到底在 5 月 14 日有没有飞过就是了。
当然,这样是有风险的────也许这个航班只在那一天飞这么一条航线呢? 我对这方面不是很了解,但是姑且试了试,运气还不错。
当然,为了优雅的尝试,这些应该是自动化的了。 我们只需要把照片时间范围内当天从 HND 进出的航班从网站那复制过来整理一下,再逐个枚举就可以了。
起飞机场(IATA 机场编号,如 PEK)
降落机场(IATA 机场编号,如 HFE)
航班号(两个大写字母和若干个数字,如 CA1813)
CA1813
1 | from tqdm import tqdm |
简单跑一下就能得到答案了:2610021 2340x1080 HND HIJ NH683。
猜数字
和去年卖瓜很像。 应该都是数字溢出? 关键是我不会 java 啊。 于是就往大数方向一个一个试了几次。就出来了…… 运气好吧应该是。
payload: 0.5e3333
。 当然你要手动改下元素的 disable 。不然交不上去。
LaTeX 机器人
原来 $\LaTeX$ 也能注入啊.jpg。
搜索 LaTeX Injection
相关关键词。找到一篇文章:
https://zhuanlan.zhihu.com/p/455901476
第一个 flag 呼之欲出。1
\input{/flag1}
第二个 flag,根据提示:
这次,flag 花括号内的内容除了字母和数字之外,还混入了两种特殊字符:下划线(_)和井号(#)。你可能需要想些其他办法了。
所以想, 如果让 $\LaTeX$ 把这俩输入合法化呢?
以 latex \input special characters
之类的关键词,搜索,发现可以用 \catcode
转义。 处理一下即可。
1 | \catcode`\#=11 \catcode`\_=11 \input{/flag2} |
谢谢 hg 教我新知识(
Flag 的痕迹
根据提示,(题目 Dokuwiki 版本基于 2022-07-31a "Igor")
如果说指定这个版本,说不定说这个版本存在什么漏洞呢?
搜索 dokowiki reversion
之类的关键词,可以看到相关讨论:
查询关键词
https://github.com/splitbrain/dokuwiki/issues/3421
于是根据内容,访问如下地址即可:
http://202.38.93.111:15004/doku.php?id=start&do=diff
安全的在线测评
无法 AC 的题目
通过阅读源码,发现静态数据和动态数据都存储在 data
目录下。 尝试读取后直接输出。成功。 但是动态数据由于设置了 0700
权限。 无法直接绕开。 尝试了自己 chmod 一下、通过 Python 间接读取等方法后未果。只做出来第一问。
随便拼凑的代码有点烂(1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
char data_in[1000], data_out[1000], N[1000];
char path_in[1000] = "./data/static.in";
char path_out[1000] = "./data/static.out";
void readFile(char filepath[], char res[]) {
FILE *fp = fopen(filepath, "r");
int idx = 0;
while ((res[idx++] = fgetc(fp)) != EOF) {};
for (; res[idx] != '\n'; idx--) res[idx] = '\0';
res[idx] = '\0';
fclose(fp);
}
int main() {
readFile(path_in, data_in);
scanf("%s", N);
if (strcmp(N, data_in) == 0) {
readFile(path_out, data_out);
printf("%s\n", data_out);
return 0;
}
// doesn't work
for (int i = 0; i < 5; i++) {
sprintf(path_in, "./data/dynamic%d.in", i);
if (strcmp(N, data_in) == 0) {
sprintf(path_out, "./data/dynamic%d.out", i);
readFile(path_out, data_out);
printf("%s\n", data_out);
break;
}
}
return 0;
}
线路板
搜索一个在线的 gerber viewer 直接看就行了。
Flag 自动机
很有意思的一题 hhh。
点开这个程序后发现,手动点击确实是点不到那个按钮的。
坦白说,我并不会什么 binary。 所以往年来说这类题我应该是不会做的。 不过今年比较凑巧。
不过我碰巧之前研究过一点点 windows api
来操作其他窗体的相关东西。 所以就写了个小 C# 程序来帮我点击那个按钮。
1 | [ ] |
运行后发现需要使用超级管理员才能点击。 但是尝试过使用管理员运行之类的都无效。
于是开始根本不会逆向の逆向分析。 首先我用了 IDA。由于不是很熟练,所以我没弄出来什么名堂。
由于之前曾经学过 ollydbg 做过一些抓取小软件注册码和修改软件文本的坏事。就想着能不能改下什么东西呢。
结果是意外的很简单呀。凭借我有限的汇编知识。可以看到这个 je
命令跳转的地址就是点击成功的情况。 而 je
是 如果等于就跳转
。 我们不用关心他比较什么。 我们要的是后面的情况。 所以我们只需要把 je
改成 jne
就可以了。 即──如果不等于就跳转。
于是运行修改后的程序,再运行我们前面的点击器。就可以获取 flag 了。 做的有点绕了,真毕生所学hhhh。
微积分计算小练习
XSS 注入~
一开始真的认认真真做了一下题(
然后发现结果网址中 result=MDox
后面就是一个 base64 解码后可以看到:前面是你的分数,后面是你的名字。
将成绩修改为 100。提交后发现没区别。
阅读 bot.py
源码。 可以发现其实无论啥成绩都没区别。主要干了两件事:
- 进入该网站。 往 cookie 中写入 flag。
- 读入 分数 和 姓名,输出
所以我们只要想法构造一个 xss 让他读取 cookie 内容并反写回网页就可以了。
多试几回,就能找到可以注入的地方了~~
1 | s=createElement('script');body.appendChild(s);s.innerHTML = `document.querySelector('#score').innerHTML = document.cookie ` |
转为 base64,使用 img onerror 注入
1 | 123:<img src=x onerror=eval(atob('cz1jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTtib2R5LmFwcGVuZENoaWxkKHMpO3MuaW5uZXJIVE1MID0gYGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNzY29yZScpLmlubmVySFRNTCA9IGRvY3VtZW50LmNvb2tpZSBg'))> |
再整体 base64 编码放到 url 中提交,就可以看 flag 了~
杯窗鹅影
flag1
直接写了一个读文件内容的程序。 没啥问题,甚至可以改下前面安全的在线评测的代码就可以直接复用。 第二问没试出来。
1 |
|
蒙特卡罗轮盘赌
考察伪随机数种子选取的安全性问题。
只要我们能构造出来一样的种子,就可以获得一样的随机数。 所以保证时间基本一致的情况下。枚举时间差和 clock()
即可。 比较坑的是 macOS 上的生成算法可能和其他不太一样。所以前面一直没跑出来。还以为是 clock()
范围有问题。 后面开了一个 docker 环境就跑出来了。
1 |
|
光与影
WebGL。其实我不是很会。但是讨巧做出来了。
下载下来观察源文件,发现 t1 ~ t5 很复杂,也许就是关于渲染那一堆 flag 的呢?
于是下面一堆 min ,逐个去掉里面的 t1 ~ t5 ,发现 t1 是 flag ,t5 是那个墙
1 | float sceneSDF(vec3 p, out vec3 pColor) { |
然后就可以读出了 flag{SDF-i3-FuN!}
。
片上系统
引导扇区
根据提示,下载 PulseView。 打开题目文件,选择 sdcard-spi mode。
需要选择不同信号对应的类型。由于没这方面的基础,所以随便试了试,就出来了。
量子藏宝图
我竟然在学量子通讯.webp
第一章-第一幕
根据提示寻找 BB84
的相关文章。发现其实很简单。
只要匹配 制备基底
和 测量基底
中相同的地方。把对应位中的量子态输出即可。 参照这个图(来源):
于是根据这个可以简单写个代码;
1 | base = input() |
由于限制了密钥长度至少为 10,所以需要简单构造一下:
1 | +x+x+x+x+x+x+x+x+x+x+x+x+x |
第二章-第一幕
一上来放一个大的电路图真吓坏我了。 我根据他提供的文档找了下相关资料。看了一个官方的视频。大概明白了其实这个电路图对于有线的位就是 1。 其他则是 0。 所以对着图打出来,根据题意按大端来,解下就好了(眼睛好疼)。
1 |
|
企鹅拼盘
读懂题发现并不会用 math 做,所以只做了前两问。好喜欢这种 TUI 界面啊,以后一定自己写点小东西玩玩
这么简单我闭眼都可以!
由于只有 4 位,所以仅有 $2^4$ 种情况,随便试试就可以试出来 $1000$
大力当然出奇迹啦~
根据提示直接暴力。 实现一个暴力函数。
1 | async def qwq(self): |
注入到:1
2
3async def on_load(self, event: events.Load):
pass # 省略前面
qwq()
这个第一问也可以直接用的。
第二问需要跑一小会儿,就得到了答案:0010111110000110
。第三问应该是跑不出来的。 看了下题解,在理解范围之外。
火眼金睛的小 E
有手就行
确实是有手就行的题,就是有点累手。 我用的是 vbindiff
。 每次把提供的两个文件打开,先跳转到提示地址,然后全局检索另一个文件的相关内容。 找到相似的那就对了。但是容错率很低。不过多试几次都能试出来。 看了题解后发现我是笨蛋(