Sukka's Blog

童话只美在真实却从不续写

Hackergame 2019(中科大信安赛)write up

Sukka's Avatar 2019-10-22 技术向

  1. 1. 签到题
  2. 2. 白与夜
  3. 3. 信息安全 2077
  4. 4. 宇宙终极问题
  5. 5. 网页读取器
  6. 6. 达拉崩吧大冒险
  7. 7. Happy LUG
  8. 8. 正则验证器
  9. 9. 不同寻常的 Python 考试
  10. 10. 我想要个家

这应该算苏卡卡第一次打 CTF(之前帮朋友测试用 ctfd 搭建的平台不算)。Hackergame 对于苏卡卡这种 CS 零基础、信安零基础、CTF 零基础这种菜鸡来说很友好,玩的还是很开心的(除了苏卡卡发现自己还是太菜了以外)。

签到题

签到题就在这里~

hacklug-2019/1.png

看到按钮被禁用了,下意识就会 F12 去把按钮的 disabled 属性去掉。

hacklug-2019/2.png

甚至可以看到出题人的贴心小提示呢,可能是给 No JavaScript 和 curl 玩家的(所以签到题都用了 Webpack 了为什么还在用 HTML4 时代的 hidden 属性隐藏元素,可能是因为赛博朋克吧

白与夜

这是一个关于白猫,嗯不对,关于黑猫的故事。

直接「Open image in new tab」就可以发现,白猫的图片变成了黑猫,甚至出现了 flag。

可以发现这是一张半透明的图片,在不同的背景下会变成不同的样子。我在这里直接演示一下。

<div style="margin: 0px; background: #ffffff; max-width: 100%">
<img style="-webkit-user-select: none;margin: auto;background-color: transparent" src="https://ae01.alicdn.com/kf/Hdbfeb2cd92fc436380c2398792ff65fd3.png">
</div>

<div style="margin: 0px; background: #0e0e0e; max-width: 100%">
<img style="-webkit-user-select: none;margin: auto;background-color: transparent" src="https://ae01.alicdn.com/kf/Hdbfeb2cd92fc436380c2398792ff65fd3.png">
</div>

<div style="margin: 0px; background: #0000ff; max-width: 100%">
<img style="-webkit-user-select: none;margin: auto;background-color: transparent" src="https://ae01.alicdn.com/kf/Hdbfeb2cd92fc436380c2398792ff65fd3.png">
</div>

Chrome 的图片查看页面其实就是一个拥有暗色背景的网页(代码如下所示),所以这道题其实不离开浏览器就能做:

<html>
<head>
<meta name="viewport" content="width=device-width, minimum-scale=0.1">
<title>Filename (Resolution)</title>
</head>
<body style="margin: 0px; background: #0e0e0e;">
<img style="-webkit-user-select: none;margin: auto;"
src="/path/to/image">
</body>
</html>

信息安全 2077

2077 年很快到来了。此时正值祖国 128 周年华诞,中国科学技术大学也因其王牌专业信息安全,走出国门,成为了世界一流大学。作为向信息安全专业输送人才的重要渠道,第 64 届信息安全大赛也正在如火如荼地开展着。
千里之行,始于足下。作为一名渴望进入信息安全专业的学生,你的第一个任务是拿到第 64 届信息安全大赛的签到题的 flag。我们已经为你找到了签到题的入口[1],你只需要把 flag.txt 的内容读出来就可以了。
注:为了照顾到使用黑曜石浏览器的用户,第 64 届信息安全大赛的签到题决定沿袭之前 63 届信息安全大赛的惯例,仍然基于 HTTP 1.x。当然了,使用其他浏览器也是可以顺利完成任务的。

(嘿阔浏览器(黑曜石浏览器)的梗可能真的可以玩到 2077 年,不过「国产红芯浏览器」那时候又会在哪里呢?)

打开题可以看到 Loading... 一会就变成了 Not yet! The competition will start after 21163 days and 50894 seconds.
这是怎么回事呢?Ctri + U 一下看网页源码,发现是一个使用 Fetch 发的 POST 请求、带着嘿阔浏览器的 UA 和 If-Unmodified-Since 请求头。

网页源码备份

有趣,F12 一下去 Network Panel 看看有什么请求是怎么回事。

hacklug-2019/4.png

一个响应码为 412 PRECONDITION FAILED 的发给 flag.txt 的 POST 请求,还可以看到响应头 Last-Modified: Fri, 01 Oct 2077 00:00:00 GMT

在请求上右键,Copy -> Copy as cURL(bash),然后在终端里粘贴、把 If-Unmodified-Since 改成 2077 年以后的日期即可:

curl  'http://202.38.93.241:2077/flag.txt' -X POST -H 'Origin: http://202.38.93.241:2077' -H 'Accep
t-Encoding: gzip, deflate' -H 'If-Unmodified-Since: Tue, 22 Oct 2077 09:54:38 GMT' -H 'User-Agent: M
ozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120
Safari/537.36' -H 'Cache-Control: max-age=0' -H 'Referer: http://202.38.93.241:2077/' --compressed
--insecure

既然题目说了,不要求使用 黑曜石浏览器 发起请求(没有校验 User-Agent),所以这道题也可以不离开浏览器完成。直接在 console 里重发一个 Fetch 请求就行:

fetch('flag.txt', {method: 'POST', headers: {'If-Unmodified-Since': "Tue, 15 Oct 2078 23:41:20 GMT"}}).then((res) => {
if (res.ok) {
res.text().then((text) => {
console.log(text)
})
}
})

补充一下,在 Fetch 里指定 User-Agent 本来就不是合法的做法。虽然你可以在 https://mdn.io/fetch 是可以看到 Fetch 中指定 User-Agent 的样例代码,但是实际上你可以在 F12 的 Network Panel 里看到,请求头中 User-Agent 是不会变化的。

宇宙终极问题

天何所杳, 十二焉分?
日月安属, 列星安陈?
浩瀚宇宙的一个寻常星系里, 弥漫六合的暗物质晕中, 远古的诗歌在狄拉克海上无声回荡.
史诗般的超级计算机 Deep Thought , 寒冷星空下的百万亿场效应管, 人类终得以一窥这个宇宙最深层的奥秘.
没错, 就是 42, 对于生命, 对于宇宙, 对于世间万物的答案.

第一小题是个 Meme:请给出一组 x y z,使得 x^3 + y^3 + z^3 = 42。我在 Twitter、Telegram 上看到了很多次。所以这道题本质上还是一个考察如何使用搜索引擎的题,所以这道题拿来做签到题多好

hacklug-2019/5.png

第二小题是给定 n = random_prime(2^256) * random_prime(2^256) ,请给出一组 a b c d i j k l,使得 a^3 + b^3 + c^3 + d^3 = i^2 + j^2 + k^2 + l^2 = n;第三小题是给定 n = randint(2^256) ,请给出一组 p q,使得 p^2 + q^2 = n

后面这两道题其实是一个平方求和和立方求和问题,好好学数学吧。后来看到 Coxxs 大佬写的 Write Up 说他用搜索引擎找到了两个在线求解网站:四平方 四立方果然苏卡卡还是太菜了

网页读取器

今年,刚刚学会网络编程的小 T 花了一点时间,写了一个非常简单的网站:输入一个 URL,返回对应的内容。
不过小 T 想对用户访问的站点进行一些限制,所以他决定自己来解析 URL,阻止不满足要求的请求。这样也顺便解决了 SSRF(Server-Side Request Forgery, 服务器端请求伪造)的问题。
想象很美好,但小 T 真的彻底解决了问题吗?

网页存档

hacklug-2019/6.png

从网页中下载 源代码,可以看到 check_hostname 函数自己实现了一个 URL 检查。简单一看就发现,小 T 将 @ 之前的内容全部视为用户名、将第二个出现的 :/ 之间的全部内容视为了端口。看来自己造轮子就是不靠谱(

构建一个 URL 以拿到 Flag:

http://web1/flag?hen+hen+hen+aaaaaaaaaaa@example.com:1145141919810

其实没有必要这么长的但是苏卡卡就是忍不住

刚好几天前在和 curbeng 重构 Hexo 的 encodeURL()、涉及到对 URL 的处理(hexojs/hexo-util#83hexojs/hexo-util#85 (comment)),所以去读了 NodeJS 的 URL API,在做题中算帮上了不少忙。

苏卡卡写这篇 Write Up 的时候,NodeJS 13 刚好发布;年底时 NodeJS 8 的 LTS 周期就会结束,NodeJS 的 Legacy URL API 将会被正式弃用、并需要迁移到 WHATWG URL API。
WHAT WG URL API 有一个挺烦人的「Feature」就是当 协议为 ftp、gopher、http/ws、https/wss、且没有指定其他端口时,url.port 会默认为空字符串(因为这些协议有默认端口 21、70、80、443)。也许 WHATWG URL API 这个特性未来也会成为某一道题呢。

达拉崩吧大冒险

某一天,C 同学做了一个神奇的梦。在梦中,他来到了蒙达鲁克硫斯伯古比奇巴勒城……

hacklug-2019/7.png

这道题取材自教主 ilem 的「达拉崩吧」,教主的又一首梗曲。

在料理市场这里,买入鲜美香脆可口甘甜现炸童子鸡可提升攻击力。通过解析网页的 JS 代码发现,数据提交直接读的 option.value 属性:

hacklug-2019/8.png

经过尝试,通过 F12 大法修改 value,你甚至可以买入负数只鸡。接下来做法就和去年的「猫咪银行」那道题一样了,设法让买入鸡的数量溢出(-MaxInt64 = -9223372036854775808)使攻击力变成非常小的负数,然后再买入 -1 只鸡让攻击力溢出爆表。接下来就可以直接干掉恶龙啦。

hacklug-2019/9.png

其实这道题还有一个彩蛋,如果在错误的地方修改了错误的 value

hacklug-2019/10.png

果然是「罪恶的一生」(

Happy LUG

在今年信安大赛命题组的内部聊天记录中,出现次数最多的 emoji 是什么?
答案是:「😂」(喜极而泣的表情,Face with Tears of Joy)。这是大家最喜欢使用的 emoji 之一。
或许是因为这个原因,最近几天,命题组某位同学收到了一张神秘的字条。
看起来是一个域名,但里面怎么会有 😂 这个 emoji?而且,虽然浏览器访问不了,但这个域名确实是存在着的。
你能解开其中隐藏着的信息吗?

hacklug-2019/11.png

这道题考察的是 Punycode,将 Unicode 字符转换为 ASCII 字符。什么「中国自主」的中文域名和 Emoji 域名原理都是这个。浏览器地址栏就是最好的转换工具,将 😂.hack.ustclug.org 复制到地址栏、再复制出来就能得到 xn--g28h.hack.ustclug.org

浏览器打不开网址并不意味着这个子域名不存在。让我们 dig 一下看看:

$ dig xn--g28h.hack.ustclug.org
dig: 'xn--g28h.hack.ustclug.org.' is not a legal IDNA2008 name (string contains a disallowed character), use +noidnout

$ dig xn--g28h.hack.ustclug.org +noidnout
; <<>> DiG 9.11.5-P4-5.1+b1-Debian <<>> xn--g28h.hack.ustclug.org +noidnout
;; [redacted]
;; QUESTION SECTION:
;xn--g28h.hack.ustclug.org. IN A
;; AUTHORITY SECTION:
ustclug.org. 120 IN SOA ns-a.ustclug.org. lug.ustc.edu.cn. 2017042791 3600 600 3600 120 ;; Query time: 681 msec
;; [redacted]

$ dig xn--g28h.hack.ustclug.org +noidnout AAAA
; <<>> DiG 9.11.5-P4-5.1+b1-Debian <<>> xn--g28h.hack.ustclug.org +noidnout
;; [redacted]
;; QUESTION SECTION:
;xn--g28h.hack.ustclug.org. IN AAAA
;; AUTHORITY SECTION:
ustclug.org. 120 IN SOA ns-a.ustclug.org. lug.ustc.edu.cn. 2017042791 3600 600 3600 120 ;; Query time: 681 msec
;; [redacted]

原来既没有 A 记录也没有 AAAA 记录,别说浏览器打不开了,curl、nc、nmap 都是没法用的。

那么换一个记录类型呢?我们知道 TUNA 和 USTCLUG 的 Telegram 群加群链接都是藏在某个 TXT 解析记录里的,所以在这里也试一试 TXT 呢?

$ dig xn--g28h.hack.ustclug.org +noidnout TXT
; <<>> DiG 9.11.5-P4-5.1+b1-Debian <<>> xn--g28h.hack.ustclug.org +noidnout TXT
;; [redacted]
;; QUESTION SECTION:
;xn--g28h.hack.ustclug.org. IN TXT
;; ANSWER SECTION:
xn--g28h.hack.ustclug.org. 60 IN TXT "flag{DN5_C4N_H4VE_em0ji_haha}"
;; [redacted]

Bingo!

其实可能很多人不知道,根据 RFC 1035 规定,有一种非常规的记录类型 ANY 可以返回当前 域名/子域名 下所有的记录:

$ dig xn--g28h.hack.ustclug.org +noidnout ANY @[redacted]
; <<>> DiG 9.11.5-P4-5.1+b1-Debian <<>> xn--g28h.hack.ustclug.org +noidnout ANY @[redacted]
;; [redacted]
;; QUESTION SECTION:
;xn--g28h.hack.ustclug.org. IN ANY
;; ANSWER SECTION:
xn--g28h.hack.ustclug.org. 60 IN TXT "flag{DN5_C4N_H4VE_em0ji_haha}"
;; Query time: 4976 msec
;; [redacted]

但是 ANY 这种类型非常危险,因为包含了所有的解析记录、返回的结果可能会非常长,iana.org,非常易于提升 DNS 反射放大攻击的效果,所以在 RFC 8482 中,ANY 终于被弃用。目前主流权威 DNS 和 公共 DNS 如 DNS Flag Day 成员都已经不再响应 ANY 请求。但是国内 ISP 的递归 DNS 并没有及时跟进,所以(

正则验证器

小 F 是一位狂热的正则表达式爱好者。今天,他写了一个在线的正则验证服务:服务器会运行你的正则,返回匹配结果。
小 F 还说,如果有人能卡住服务器(运行时间超过 1 秒),他就会送出自己的 flag。
当然,为了避免太容易拿到 flag,小 F 限制了正则和字符串的长度,具体内容请查看源代码。

这道题一看就是受了今年 Cloudflare 全球大范围 502 故障事件的启发(TL;DR 由于 Cloudflare WAF 工程师编写的一条错误的正则表达式会引发大量回溯、导致 Cloudflare 全球数据中心的 CPU 算力耗尽),详细事故报告可以查看 Cloudflare 的博客原文 或者 我的中文翻译。Cloudflare 那条正则表达式的核心是 .*(?:.*=.*),去除捕获组后可以简化为 .*.*=.*

题目说「限制了正则和字符串的长度」,根据题目提供的 源代码 可以发现限制正则表达式不超过 6 个字符、匹配字符串不超过 24 个字符。

所以这道题就变成了如何在 6 个字符长度的限制内构造一个会回溯的正则表达式。分析简化后的正则表达式 .*.*=.* 可以发现关键在于两个相邻的任意匹配。
使用非捕获组进行分段以后可以构造出下述正则表达式和字符串:

Regex: (s+)*b
String: sssssssssssssssssssssssk

苏卡卡之前在为 Hexo 4.0 优化生成性能时,很重要的一部分就是用正则表达式代替 cheerio 解析 HTML:hexojs/hexo#3680hexojs/hexo#3685hexojs/hexo#3697。那时候恶补了不少正则表达式,这次也派上了一些用场。

不同寻常的 Python 考试

「第一节:听下面 5 段代码,每段代码后有一个小题,请根据题目补全代码,并写在答题卡的相应位置。听完每段代码后,你都有 10 秒钟的时间来回答有关小题和阅读下一小题。每段代码仅读一遍。」
小 Q 突然从梦中惊醒,心想,这又是什么奇怪的梦,一定是因为最近的学习压力太大了。
虽然已经无法回忆起梦里自己为什么要参加这样的考试,但广播里字正腔圆读代码的声音一直在小 Q 耳边萦绕,挥之不去。
「If……空格……a……点……count……左括号……b……右括号……等于等于……」
小 Q 冷静下来,把 20 道 Python 补全题都记了下来。但她发现,梦里的考试,自己竟然连 60 分都做不到。

题目可以看 这里。做这道题时感觉整个人都不好了,从此再也不敢说自己会 Python。

这道题就不一一解析了,苏卡卡只拿到了第一个 flag(果然还是太菜了)。这里推荐大家去阅读 wtfpython,看完后绝对会眼界大开。苏卡卡相信出题人肯定也读的这个(

我想要个家

有一天,C 同学做了一个梦,他竟然搬进了大房子,只是似乎有些地方 C 同学不太满意……
注意:
此题考察的是对于 Linux 基础知识的掌握。尽管可以,但不建议使用逆向工程的方式完成。
在根目录(/)下的文件夹对 Linux 系统的运行十分重要,请不要为了完成此题目删除自己的 /usr, /bin 等文件夹!

下载文件

啥?题目说不建议逆向?好,IDA Pro,启动!
(然后啥也看不懂)(苏卡卡太菜了)

好吧,既然题目都说了,那肯定不能拿自己的系统乱来了。你看在线的 Container、Web IDE、REPL 还蛮多的,可以在上面玩,玩坏了就直接 destroy 掉重建,没问题的

苏卡卡用的是哈佛提供的 CS50 IDE(Powered by Cloud9),开了一个 Blank 的 Ubuntu Container,修改 root 用户的密码、进入 root shell、下载文件、chmod +x、运行文件一气呵成:

hacklug-2019/12.png

一开始让我在根目录建几个文件夹,但接着就要我删除根目录下所有系统目录。这还不容易,sudo rm -rf / --no-preserve-root

正确的姿势是尽量使用 mv 命令,mv 不了的比如 /proc 目录用 mount

# mkdir /0
# mount --move /proc /0

接下来的要求基本不难,除了要注意 /bin 目录被移动掉以后、使用二进制要用新的绝对路径;始终能够获得当前的北京时间的文件可以写个用 while true 搭配 datetee 的脚本解决(苏卡卡直接复制了一份自己 为 KoolClash 写的那个 watchdog,改了改就拿来用了)。

拿到 flag 以后,直接关闭浏览器标签页中断与 Container 的连接,耶!(

hacklug-2019/13.png


像苏卡卡这种菜鸡还能拿 1650 分,Hackergame 的确能算是一个「新手友好的 CTF」(别说了,苏卡卡菜就对了)。最后跟苏卡卡一起大喊:废理兴工~~!

本文作者 : Sukka
本文采用 CC BY-NC-SA 4.0 许可协议。转载和引用时请注意遵守协议!
本文链接 : https://blog.skk.moe/post/hackergame-2019-write-up/

本文最后更新于 天前,文中所描述的信息可能已发生改变