中科大第五届信息安全大赛
Contents
翻译
本文另有 英文版本。
签到题
Chrome 按 F12 打开开发者工具,可以看到输入框处的属性:
| |
将 maxlength 属性删除再填入 hackergame2018 即可。
flag: flag{Hackergame2018_Have_Fun!}
猫咪问答
普通的问题,Google 一下就可以找到答案:
| |
提交后获得 flag。(说出来我都不信,这题我是在手机上做的,还把视频看了一遍……)
flag: flag{G00G1E-is-always-YOUR-FRIEND}
游园会的集章卡片
用 PS 拼好就行了(我就是懒得拼最后的块了

flag: flag{H4PPY_1M4GE_PR0CE551NG}
猫咪和键盘
据说是只要拼好一行然后照着这行的顺序就能拼好别的行,然而我这种菜鸡没这么机智,只会一行一行拼好,坑爹的是 ABC、BAC、CAB 三个宏的定义处也要调整,在这里卡了半天……最后的部分如下。拼好后直接 g++ 编译运行即可。
| |
flag: flag{FfQ47if9Zxw9jXE68VtGAJDk6Y6Xc88UrUtpK3iF8p7BMs4y2gzdG8Ao2gv6aiJ125typed_printf95}
Word文档
地球人都知道 Word 文档是 zip 压缩文件……强行改名解压,里面有 flag.txt:
| |
flag: flag{xlsx,pptx,docx_are_just_zip_files}
黑曜石浏览器
要求用黑曜石浏览器访问,HEICORE 暗指的是哪个价值 2 个亿的 Chrome 皮肤大家都知道吧……先试了 HEICORE 做 UA 发现不行,上网找了一下还真有个官网,官网上注册的时候提示要用黑曜石浏览器注册,从网页反应时间来看这里的 UA 判断是在本地的,那么 JS 代码里肯定有 HEICORE 的 UA,打开开发者工具,竟然有反调……到嘴的鸭子怎么能就这么飞了呢,在 network 选项卡查看之前的 index.html:

有了 UA 之后当然是 curl 大法好:
| |
flag: flag{H3ic0re_49.1.2623.213_sai_kou}
回到过去
瞎试了几次试对了……开始的 q ed 是退出之后又进了 ed,进了 ed 后直接按键盘记录输一遍,在最后一个 q 之前加一句 w flag 保存起来,再查看 flag,注意因为输入了一个 Esc+C,会有个清屏,忽略之即可。
flag: flag{t4a2b8c44039f93345a3d9b2}
我是谁::哲学思考
打开开发者工具可以看到返回的状态码是 418 I'M A TEAPOT,这个状态码是在一个经典的愚人节恶搞 RFC 中定义的,用 HTTP 协议控制咖啡壶和茶壶,脑洞开的真大……所以对方是一个 teapot,填上去即得 flag。
flag: flag{i_canN0t_BReW_c0ffEE!}
我是谁::Can I help me?
RFC7168 中定义了请求茶壶时可用的方法——POST 和 BREW,肯定不是 POST 这么普通的方法,发一个 BREW 请求过去:
| |
发现这个茶壶只能煮红茶,给请求的路径加一个 black_tea,再发一次即得 flag。
flag: flag{delivering_tea_to_DaLa0}
猫咪遥控器
别人怎么都那么高端会用 canvas 画图……本菜鸡只会用 Python 拼出字符画,再用微软爸爸的编辑器 VSCode 打开,按 Ctrl+- 缩小再目测:

flag: flag{MeowMeow}
她的诗
真够坑的……在解码出来的诗里面找了半天有没有什么隐写。原有的 poem.txt 编码方式为 uuencode,特点是每行的第一个字符用来表示本行编码前的长度,此处的长度字符被故意设置为比原文稍短,Python 解码出来的数据行末被截短,flag 也就没了。用其他的 uuencode 解码实现来解码可以看到被截短的部分:

flag: flag{STegAn0grAPhy_w1tH_uUeNc0DE_I5_50_fun}
猫咪克星
就是把发过来的算式直接 eval,注意要把一些乱七八糟的坑爹表达式换掉(还好没发过来个 __import__('os').system('rm -rf ~') 啥的……我的 pwntools 是 Python 2 的,不过换掉 print 之后就没问题了,最后报错出来的信息就是 flag)。
| |
flag: flag{'Life_1s_sh0rt_use_PYTH0N'*1000}
猫咪电路
红石电路,从信标的那一端直接反推即可,做完题目之后不小心陷入其中,玩了 1 个多小时……
flag: flag{0110101000111100101111111111111111111010}
FLXG 的秘密::来自未来的漂流瓶
看了半天的剧情……脑洞是真的大。卦的顺序众说纷纭,试了好几种终于找到对的了:
| |
flag 就在文件最后,出来的文件再用 tar 解包,可惜后面没逆出来那一堆 lock……
flag: flxg{Power_of_the_Hexagram}
FLXG 的秘密::难以参悟的秘密
没做出来,别看了,丢人。
C 语言作业
IDA 打开后可以看到 __err 函数可以执行一条不含 sh 的命令,而且 __err 还被注册成了好几个信号的处理函数。需要设法产生某种信号,输入 -2147483648/-1(-0x8000000/-1),结果是 2147483648(0x80000000),并不能被存储在 int 中(天秀啊),就会产生 SIGFPE 信号,进入 __err 后执行 vim,在 vim 里执行 :! cat /flag 发现 flag 在 - 里,再执行 :! cat /-,找到 flag:

flag: flag{816484e67b21efd5de8f1661d180a007}
加密算法和解密算法
简单的 brainfuck 解析器(src 是那段 brainfuck 代码):
| |
代码大致分为前面的输入处理和最后的输出,将输入处理部分按 10 次 getchar() 分开,可以看到每次输入一个字符,会进行两个 while 循环,以第一次的两个 while 循环为例:
| |
读入字符时存储在 a[0],仔细观察第一个循环,每圈执行完后指针总会回到 a[0] 处,因此可以将循环简化:
| |
后面的循环同样一圈执行完成后指针位置不会变,同样可以简化(注意两个循环之间指针由 a[0] 移至 a[1]):
| |
随后指针返回 a[0] 读入下一个输入,执行 2 个循环,直至 10 个字符全部读入……最后的输出部分为从 a[2] 开始输出至 a[11],可以看出 a[2] 到 a[11] 是关于 10 个输入的线性组合(说的高端一点这叫希尔密码),写脚本提取出系数矩阵(脚本太烂就不贴了),问题即为解线性同余方程组 Ax===b(mod 64),注意 256 是 64 的倍数,因此直接模 64 即可(瞎猜的,将来 flag 出了偏差我不负责任的)。
可惜我这种菜鸡不会用 z3,只能用高斯消去法求逆矩阵,(此处省略 10 分钟回忆线代知识)将系数矩阵 A 和单位矩阵 E 并排放好,通过行变换把 A 变为单位矩阵,旁边的 E 就变成了 A 的逆矩阵,即 [A|E]->…->…->…->[E|A^-1]。(看官方的 Writeup 还求行列式和伴随矩阵是认真的吗 hhh)。对于求模 64 的逆矩阵,将高斯消去法中的除以某数换成乘以这个数的模 64 乘法逆元即可,求得逆矩阵后用逆矩阵乘以密文向量就解出了明文向量,注意输出部分最后所加的常量:
| |
(小声 bibi:ZJU School Bus 上某题和这个解法一毛一样
flag: flag{h1ll-c1ph3r-w1th-10x10-r3v3rs1bl3-matr1x}
她的礼物
看题目意思是输进去第 10 行就能算出 flag,IDA 打开可以看到主函数内的 sleep(2u) 和 system("echo -en '\a' > /dev/tty5") 都是对于计算没有影响的,直接强行修改汇编指令,把 call _system 和 call _sleep 分别换成 5 个 nop,运行魔改过的程序,过了 10 秒又停了,这回是 sub_401260 里的 alarm(0xAu) 引发的闹钟所致,如法炮制把 call _alarm 也换掉,再运行就直接得到了 flag(我就是懒得删掉输出歌词的部分了):
| |
flag: flag{HowEVER,_Somedaj,_sOMe0NE_wILl_FiND_it.}
困惑的 flxg 小程序
Windows 逆向是真的迷……IDA 打开之后发现主函数根本就是假的,在 .rdata 段中的几个输出的字符串下方 .rdata:00000001400054D8 处,有一堆明显疑似 flag 的数据,查一下引用,发现 sub_140004980 用到了这里,逆向一番可以看到,此函数将输入进行 base64 编码,strrev 反过来,再依次异或 0,1,2……最后和刚才那堆数据比较,上述过程反过来即可得到 flag(这 flag 看着跟假的似的):
| |
flag: flxg{Congratulations_U_FiNd_the_trUe_flXg}
一些宇宙真理
要验证 80 个证明……看一下 fork 的源仓库,里面的示例程序是通过调用 verify_proof(keypair.vk, *proof, h2_bv, h1_bv, x_bv) 来验证证明的。那我就有 young 学 young,写一个验证程序(写的贼烂,求轻喷):
| |
这破程序怎么有这么多依赖库……git clone 总是玄学失联,害得我还得一个一个去下载,怪不得做的人这么少……直接在原来的 Makefile 里加上两行,让 make 自动编译即可。
| |
| |
题目给的 proof 居然只有 79 个……运行完之后发现 flag 里 0 只有 39 个,所以第 80 个 proof 是 0,加在 flag 后面即可。
flag: flag{10100100000101100110000001111011110101100101000011111111101000100100110100101110}
总结
我好菜啊……