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应该比较短, 因为如果$m < p_1 \times p_2$, 则$m \equiv c^d \pmod n \equiv c^d \pmod{p_1 \times p_2} $. 于是枚举所有400种$p_1 \times p_2$, 计算$m$的值, 但毫无发现.

结束后才知道, 题目给的c,d,n是只用1个内部素数加密的结果! 至少2个素数的限制是后来出题人觉得太简单才添加的, 因此只有拿$c^d$对一个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