BCTF 2017 Web writeup

算是第一次跟着Lilac从头到尾打一场CTF,暴露出了很多的问题,实力不够,思维江化。

Baby SQLi & Kitty Shop

两道题是一个页面,作为吃瓜群众旁观大佬队友们在开赛一小时的时候拿到了Kitty Shop的一血,先膜一发。

打开是一个登录页面,扫目录发现有/.viminfo

# This viminfo file was generated by Vim 7.4.
# You may edit it if you’re careful!

# Value of ‘encoding’ when this file was written
*encoding=utf-8

# File marks:
‘0 1 0 ~/.viminfo
‘1 99 0 ~/app/encrypt0p@ssword/password

用户名1’=0#可以登陆,进去后是一个shop页面,显示有 4 items in stock,but one is available。manual处可以下载得到:

Welcome to the shop! Your balance is $10, have fun~

(a) hello kitty $10
(b) flag of hello kitty $10
(c) flag of dummy shop $999

开始以为要竞争买c拿flag,后来知道c是逆向题目的flag,发现有提示是4 items,于是买东西时抓包改成买d拿到flag。

然后是kitty shop:

manual处可以读到任意文件,但是不能读php

读 ../../encrypt0p@ssword/password

../../../../../..//backup/client.zip

拿到文件发现是二进制,交给二进制大佬很快就做出来了。

Paint

拿到kittyshop的一血以后开开心心吃了饭回来发现了这道题,然后就是噩梦,直到最后也没做出这道题,灵性不够,一直在SSRF和文件上传上绕,文件上传估计是白名单检测文件名,上传图片后nginx的解析漏洞都用不了,远程图片插入只接收HTTP协议并且不能用302跳转,如果url合法则先curl然后检测文件格式是否是图片,不是则抛出not image。在这种情况下不应该继续纠结这两方面是否是有漏掉的可以利用的trick。因为VPS接收到用的是curl所以想到过curl的命令注入,但是并没有深入考虑并且直觉无法绕过url合法的检测。直到第二天后面已经没有动力再做了。

看大佬的WP是通过curl {1, 2}来拼接多个访问的内容,为了绕过图片格式的检测选择把flag.php插入两张图片中间,payload类似curl http://127.0.0.2/uplaods{1.gif, flag,php, 2.gif},这道题没做出来应该是最不应该的了,因为中途也考虑过curl的trick,但是没有深入探究,很可惜。

Signature

这道题也卡了很久,其实应该很快就能做完的。

进入网页发现是CI框架,发现session很特殊,队友很快找到http://wps2015.org/drops/drops/Codeigniter%20%E5%88%A9%E7%94%A8%E5%8A%A0%E5%AF%86Key%EF%BC%88%E5%AF%86%E9%92%A5%EF%BC%89%E7%9A%84%E5%AF%B9%E8%B1%A1%E6%B3%A8%E5%85%A5%E6%BC%8F%E6%B4%9E.html

扫目录发现题目也是2.1的CI框架,基本就是这个套路没跑了,队友又找到https://github.com/Dionach/CodeIgniterXor(膜队友),发现可以直接利用,解密登陆页面的cookie得到:

把logged in 改成yes成功登陆,登陆后只有一个框,用类似1’or(1=1)#的payload可以盲注,于是开始盲注,脚本:

跑完了所有的数据也没找到flag,很尴尬,于是这里陷入了僵局。后面灵性输入index.php/payment发现一个查询payment的页面,要用到之前数据库里查询到的东西,但是多了一个signature字段,数据库里的bankname,billno,md5_key等如果输入错误会显示hacker go out,输入正确但是signature错误会显示U are so smart,but wrong,因为不知道signature生成的逻辑,于是再次陷入了僵局。后面直到第二天中午才又灵性找到了github,拿到了生成signature的源码:

把之前数据库里的东西代入进去提交就拿到flag了。

Alice and Bob

三血,很显然的sql注入,开始发现提交 ‘=1=’ 可以查询成功,于是想用if或者case when盲注,发现都被过滤,用’=(database() like ‘bctf’)=’也被过滤,然后发现’=(database() like ‘bctf%’)#可以返回成功,返回 Alice is a good girl. 则语句为假,返回Nobody named ”=(database() like ‘bct%’)#’则语句为真,于是用这个方法构造Payload,猜测列名表名都为flag然后爆破。

最后拿到flag的payload:

Diary

https://whitton.io/articles/uber-turning-self-xss-into-good-xss/ 其实是和这篇文章一样的套路。

admin only

进入通过邮箱找回密码的页面,找回密码后页面有一个隐藏的md5,解密后是admin的密码,用admin进去发现提示:

we love open source
we share our code
at the biggest warehouse in the world
you are admin, you know what I’m talking about

加上题目提示的github很重要,于是开始了找源码之旅,在github上找了一下没找到,发现页面有一个set-cookie: identity=,是一个md5,解密后是user,改成admin的md5后拿到github地址,发现是安卓:

给出了密文密钥加密模式,解开拿到flag。

 

总之,实力不济, 整个过程都是被大佬队友带着飞,很惭愧。

总结一下现状,两个大方向:SQL方面,注入点fuzz的时候很僵硬,自动化程度不够,各种payload的理解不够深入,不能有效的组合再利用,找到能用的注入paylaod后,脚本自动化程度不足,都是手动跑出表名列名再写脚本跑字段;XSS,基本功为零,探测向量理解不足,自动化fuzz能力为零,javascript功力低下,就是渣。其他方面,对每个姿势的理解不全,不能理解全部利用方法和上下限,例如这次的paint题目,在得到只接受http协议并且不能302跳转的时候,在没有明显以前的0day提示的情况下应该果断放弃SSRF的利用,而不是猜测是否有自己没有了解到的其他姿势。然后基础的东西理解不足,就像curl的基本姿势都没有理解全。