BCTF Write-up

受人蛊惑拉拢, 3 月 8 号 8 点至 10 号 8 点, 我参加了首届「百度杯」全国网络安全技术对抗赛 (BCTF) 资格赛. 大家全都是第一次参加 CTF, 发觉自己实在各种弱, 不过长了很多见识.. 也遇到很多好玩的题目.

我们工具都不太专业, 尤其是二进制能力比较差, 之前从来都没用过 IDA, 没配过 gdb, Reverse/PWN 的题都只做出了最简单的. Web 题方面也没什么经验, 有提示的题能跟着线索做, 其余的都茫然了. Day1 和 Day2 上午我们队都曾到过 leaderboard top1. 不过慢慢被追上来了. CRYPTO500 如果不被坑的话早点做出来可能还有进决赛的希望..

随便说几个题好了..

Misc 100

搞笑题. 在微博上关注并 @一个账号, 它会发给你第一题的 flag.

Misc 200

题目给出两个 DNS 查询, telnet 入口处询问四个服务器的 IP. 因此理应对题目给出的 DNS 服务器进行查询得到 IP.

不过题目的 DNS 服务器貌似一直挂着, 到了晚上才能查询. 而且 blahgeek 发现貌似只有用 TCP 方式才能查询到正确的 IP. 后来教授告诉我, 其实是查询的时候, 返回的都是加了一个偏移量的结果, 但是出题者忘了对 TCP 查询做相同的处理.

此题我们队第一个解出.

Misc 300

题目只有一张图. 图片本身和注释里都没有藏任何信息, 但是把图片下下来打开时会发现 libpng 的 warning: IDAT: too much image data

这里非常可疑, 于是开哥研究了一下 png 的格式标准, 把图片中多余的一部分数据拿了出来, file 了一下:

$ file extra
extra: Gameboy ROM: "PAINT", [ROM ONLY], ROM: 256Kbit

下了一个 GBA 模拟器, 发现怎么也打不开.. 然后 blahgeek 神发现, 说只要文件扩展名设为.gb 就能打开了.

打开之后屏幕上只有 "Contra 30" 字样. blahgeek 神操作直接开始敲 "上上下下左右左右 BA"... 我 google 了一下发现 Contra 是魂斗罗.."上上下下左右左右 BA" 是魂斗罗的 30 条命秘籍.. 于是把键盘映射调对, 敲了秘籍拿到 flag 过关. 我们队也是第一个解出

CRYPTO 100

题目一个 python 程序部署在 telnet 上, 源码公开, 内容是向用户询问四个加密函数, 对一个输入数字进行加密, 要求与一个已知数字的加密结果相同.

看了一下可选的函数, 发现只有一个 zlib.decompress 是多对一的, 因为压缩时可选不同的 level. 于是在这里做做文章, 再把其余函数全部取反函数就通关了.

CRYPTO 200

题目给了一段对话, 对话前有提示用 Tupper 发明的方法. 对话后面全是超长的数字.

google 发现其指的应该是 Tupper's Self-reference Formula, 遂网上搜了搜画图代码, 将数字代入, 就能够将几个超长数字翻译成图片了.

对话的最后两个关键数字翻译失败, 仔细研究前面的对话, 发现他们商量到替换公式里的参数, 把 17 换成了 61, 由于前面的图片质量太差了我们看了好久才发现这一点. 换了参数之后就能把 flag 画出来了. 这一题我们也是第一个解出.

CRYPTO 300

题目描述给了一个比特币地址, 要求发送一封用此地址签名的邮件来取回 flag. 因而关键在于获得比特币私钥.

根据题目背景描述, 此地址应该是用 warpwallet 生成的, 且很可能利用了给的邮箱作为 salt. 因此需要猜出 passphrase.

考虑到题目中的那个眼睛上的 22:39 很莫名其妙, 且题干中说 "猜秘钥, 不要偷窥", 猜想 passphrase 是一个时间. 于是我下了开源的 warpwallet, day1 晚上枚举了所有的时间, 早上起来发现 passphrase 是 20:20. 后发送邮件得到 flag. 这一题我们也第一个解出.

PPC 400

题目 telnet 上之后首先要求在几秒内解出 sha1 (A + x) = B 中的字符串 x, 其中 A,B 为已知. 猜想 x 不会很长于是枚举. python 速度不够于是用 C++ 连 socket 再解.

解出后会给一道算法题, 是一道求最小操作次数题, 简单 BFS 模拟即可, 要跑 100 个数据点. 主要困难在于 socket 交互上, 因为服务发回的数据格式不是很一致, 很多描述性提示性信息发的比较乱, 导致 tim 的程序一直超时或提前发送答案, 我调了很久才跑对. 最后第二个才解出这题.

CRYPTO 500

题目给了一个 RSA 加密系统, 每次用 5 个素数的积生成 n, 其余都与正常的 RSA 一样. 生成 n 时的素数可以手动提供, 但要求至少有 2 个是系统的内部大素数. 目标是根据一个部分的截图, 恢复加密的信息 m. 截图中有一个外部素数的后一部分, n 的前一部分, 及完整的 c 和 d. 这些数字的文本直接从图片的注释中就能拿到.

开哥猜想系统中的素数个数有限, 限制至少有 2 个内部素数就是为了防止素数被偷走. 因此写了一个程序不断获得 n, 反复求 gcd, 很快拿到了系统中的所有 20 个大素数.

然后我猜想 m 应该比较短, 因为如果 , 则 . 于是枚举所有 400 种 , 计算 的值, 但毫无发现.

结束后才知道, 题目给的 c,d,n 是只用 1 个内部素数加密的结果! 至少 2 个素数的限制是后来出题人觉得太简单才添加的, 因此只有拿 对一个 p 取模才能拿到 flag.

我们就这么被题目坑了. 因为对两个素数的积取模显然是各种意义上都更优的策略, 因此我们根本没有考虑对一个素数取模的事情, 后面的时间开哥都在想如何利用 n 的前一半和 p 的后一半. 这题完全 stuck.

PWN 100

IDA 发现题目读入字符串之后会从其特定位置开始执行, 因此要写 shellcode 弄进去拿 shell. 开哥写了之后总是 exploit 失败, 后 blahgeek 再次神发现开哥发送的时候少发了一个 '\n'. 拿到 shell 之后直接 cat flag.txt 就拿到 flag 了.

REVERSE 100

一个 win32 二进制, 读 IDA 的反汇编结果, 发现程序在做很复杂的数学运算, 并且在循环内层会不断弹阻塞的 messagebox. 于是对照着重写了程序, 把阻塞语句删去, 就算出了结果.

WEB100

题目要求找 Alice, 页面上有 4 个人名链接, 每个人的 URL 是一个 md5 字符串. 我们一直没反查出这些 md5 串, 因此一直没有任何线索. 后来 gj 找了一个好的 md5 反查网站, 发现原串是人名 + 三位数字的形式. 因此枚举所有的一千个 Alice + 数字, 就找到了一个与众不同的页面.

for i in {0..1000} ; wget http://x.x.x.x/$(printf Alice%03d $i | md5sum | cut -d ' ' -f 1).html -O $i.html

页面上是 backtrack linux 的 logo, 注释里写着 "POST [flag=OUR MOTTO]", 我们尝试了很久, 发现需要 post 大写的, backtrack linux 的 MOTTO, 就能拿到信息.

拿到的是一个 flag-in-config.php.bak 文件, 里面只有一副暴漫. 猜想 flag 在 config.php.bak 文件中, 访问之发现果然有! config.php.bak 里面是一个用 [(!~)] 写的 js 代码, 在浏览器里运行即可拿到 flag.

WEB200

blahgeek 在题目出现后一下就做完了.. 大家都还没看题. 于是也是第一个做出来的.

WEB400

给了一个比特币交易市场 (其实使用的是 testcoin), 任务一是赚到 200 个比特币. 我们不知道从哪入手找漏洞, 结果 byvoid 用合法手段转进来 100 多个币...orz 用的是 testcoin faucet. 随后找了大神華教授帮我们线上交易, 不一会账号里就有了 1000 万爆了数值的上限. 虽然最后还是没找到可用 web 漏洞因此没做出来, 不过目睹了華教授超凡的交易能力...

Comments