第七届中科大信息安全大赛部分题解

今年再次参与了好玩有趣又能学到知识的 Hacker game 比赛,题目还是熟悉的味道,很好的延续了寓教于乐的传统。相比之下,某著名二次元宅舞站的题目就……

下面是我的部分题解:

签到

随便尝试提交后,提示需要输入整数个 flag 数量,F12 里看到是 get 传参,直接将地址栏的数字修改成 1 再提交即可。

2048

直接翻看 JS 源码,找到了游戏成功时的请求地址

if (won) {
    url = "/getflxg?my_favorite_fruit=" + ('b'+'a'+ +'a'+'a').toLowerCase();
}

尝试手工拼出 URL /getflxg?my_favorite_fruit=baaa,提交却失败了。我以为是有什么 override toLowerCase 之类的骚操作,没有在意,直接刷新页面准备重试,却发现游戏状态还在。意识到状态应该是保存到本地了。随后在 localStorage 中找到个 won 字段,直接修改成 true 后刷新页面,拿到 flag。

此时再回过头来看之前的 toLowerCase 魔法,在 js 里 eval 一下,发现 ('b'+'a'+ +'a'+'a').toLowerCase() 的输出是 banana。我才意识到原来是其它的 JS 魔法,具体可以看这里

从零开始的记账工具人

开始尝试用 Excel 本身来解决,到网上找到阿拉伯数字转大写数字的方法,但没有便捷的反向转换方式。于是将文件导出成 csv 后,自己写了个简单的 Python 脚本来转成阿拉伯数字。其中碰到一些与“拾”、“整”相关的 edge case,导致第一遍算出来结果不对。用 Excel 的阿拉伯数字转大写功能又校对了一遍才发现,修正之后拿到 flag。

超简单的世界模拟器

直接搜“生命游戏”,找到几种可以无限复制的初始状态。用一个不断向右移动的“飞船”结构解决了第一题,再加上一个不断扩大繁殖的结构解决了第二题。

自复读的复读机

一个经典的代码自举题,被称之为Quine。我到网上找到一个 C 语言的版本后,简单修改解决。

i="i=%c%s%c;print((i%%(34,i,34))[::-1],end='')";print((i%(34,i,34))[::-1],end='')

不过由于 Python 的 %r 功能,其实还有更简单的实现方式。

s='s=%r;print((s%%s)[::-1],end="")';print((s%s)[::-1],end="")

233 同学的字符串工具

第一小题:我一开始想着是有什么特殊注音字母或 Mark 字符能够躲过正则检查的同时,还能再 upper 过程中丢失。直接写了段代码尝试爆破,然而并没有结果。

for i in range(0x10FFFF):
  test(chr(i) + 'FLAG')
  test('FL%sG' % chr(i))

后来意识到会不会是一个字符变多个字符的情况,又写代码找了一番,发现了 字符的存在(注意不是 fl)。

for i in range(0x10FFFF):
  c = chr(i)
  if len(c) != len(c.upper()):
    print(c, c.upper())

提交 flag 后通过。 第二小题:先简单尝试了一下 'a'.encode('utf-7'),果然得到的还是 a(题目怎么可能这么简单嘛)。于是跑去看 UTF-7 的规范,发现它是一种类似 URL-Encoded 和 base64 的混合体。手动构造出 fl+AGE-g 后通过。

233 同学的 Docker

docker pull xxx 下来之后,用 docker inspect xxxLowerDir 的路径,直接去本机的 /var/lib/docker/overlay2 目录里对应的路径看文件内容。 所以说同学们都要多多留意 docker 的 layers 特性呀。

从零开始的 HTTP 链接

先尝试了用 curl 直接访问,果然不行呢(150分难道会白送你吗) 抄起 socat 转发端口搞定。

socat tcp-listen:8000,fork,reuseaddr tcp-connect:x.x.x.x:0

来自一教的图片

在知乎找到一篇回答,讲如何通过傅里叶变换的方式给图片加水印,参考着处理了图片后,得到答案。

超简陋的 OpenGL 小程序

真的简陋,到网上找了段 OpenGL 例子,复制过来随便改改就过了,我也还不明白怎么回事。

生活在博弈树上

很好的一道 C/C++ 指针内存安全科普题。 看到源码里的 gets 调用而非 gets_s 就知道下手点在哪了。 用反汇编工具看下栈的分布情况,input 距离 success 有 0x8F 个字节,所以输入 0x8F 个字符再加上一个 '\1' 即可覆盖掉 success。

注意要正确输入之后才会检查 success,所以输入内容的前几个字符还是要保证为正确的坐标输入格式。

来自未来的信笺

手动尝试解码了几张二维码之后,意识到可能存在 binary 内容,应该是要将所有二维码中的内容拼接成个压缩包文件。 然后尝试了N个库,终于有个 zbar 能“正常”解码出内容。发现是个损坏的 tar 文件,其中有个 repo.tar.xz 无法正常解压。对照着 xz file format 手工修复半天后,依旧无法正常解压,遂放弃。 最后看官方题解,原来 tar 文件是正常的。我用的库解码二进制内容时产生了错误,导致文件损坏……

狗狗银行

开始看到公告:

每个用户最多 1000 张卡,每张卡最多 100000 条交易

以为是并发问题,写了脚本“压测”服务器之后,并没能成功。然后注意到利息计算是存在小数的,可能和取整有关。经过计算,得出卡里余额为 167 时,效益最高。简单改了下我的“压测”脚本,创建200张卡,第一天用信用卡给每张卡转 167 元,之后每天从储蓄卡里转出1元利息还给信用卡,成功解决。

普通的身份认证器

首先题目暗示某个依赖库版本老旧存在安全问题,然后身份认证是通过 JWT 实现的,就先搜搜 JWT 的安全问题。找到这篇文章。看来下手点需要拿到网站用于签名的公钥。

通过网页代码注释可以知道后端使用的 FastAPI 框架,于是跑去看文档。发现其非常方便的提供了 /docs endpoint 来查阅 API。访问网站的文档后很明显能发现一个可以的 /debug 接口,直接尝试用页面自带的调试功能请求,拿到 public key。最后手工拼一下数据结构,用CyberChef 生成 JWT Token 解决了。

超简易的网盘服务器

开始还以为是老旧版本 h5ai 的漏洞,但通过 dockerfile 可以看出用的是当前最新版,应该是没戏了。最后发现直接访问 PHP 的话,可以绕过根目录的身份认证机制。于是直接发请求调用 h5ai 的打包下载功能,将 flag 下载回来,从而拿到 flag。

超安全的代理服务器

直接访问页面,提示已经 push 了最新的 secret key,意识到是 HTTP2 的 Server Push 功能。看了下 curl 的文档,然而并不支持 HTTP2 Server Push 功能。于是选择了 go 的 http2 库附带的 h2i 工具。

$ ~/go/bin/h2i -insecure x.x.x.x
Connecting to x.x.x.x:443 ...  
Connected to x.x.x.x:443  
Negotiated protocol "h2"  
Sending: []  
...
h2i> headers  
(as HTTP/1.1)> GET / HTTP/1.1  
(as HTTP/1.1)>  
Opening Stream-ID 1:  
:authority =  
:method = GET  
:path = /  
:scheme = https  
[FrameHeader PUSH_PROMISE flags=END_HEADERS stream=1 len=35]  
:method = "GET"  
:scheme = "https"  
:authority = ""  
:path = "/4a3fc104-33c3-440e-bbf4-a282b1ad66ec"

然后手动访问 push 的页面,拿到第一小题的 flag。 接下来看第二小题,通过页脚的链接可以猜出,管理页面需要通过代理访问远端 localhost。但域名白名单和黑名单的存在,告诉了我们需要想办法绕过 ACL。

经过简单尝试,可以发现只要域名中包含 ustc.edu.cn 即可,后面加上其他字符也不会 403。于是给自己的域名添加了一条 A 记录,让 ustc.edu.cn.example.com 指向 127.0.0.1。等待片刻,确认 DNS 记录生效后,使用上面得到的代理信息访问 ustc.edu.cn.example.com,成功获得 flag。

结果官方解就只是用 IPv6 地址……

总结

总体做下来,感觉今年的题目相比以往,稍微少了些趣味性,多了些做题感。(也可能是我太菜了,Orz)

最终排名 43,也算是不错的名次了。相比我以往的成绩掉下来不少。

个人猜测可能是因为这个比赛更加有名气了,因此吸引了更多的大佬参与吧。

这也达成了主办方宣传和培养大家的信息安全知识的诉求,成功在中国信息安全史上画下了重重的一笔(

官方题解

https://github.com/USTC-Hackergame/hackergame2020-writeups

标签:CTF

添加新评论