5月14日举行了TSCTF线下决赛。凭着线上初赛第4的名次,感谢北邮“天枢”战队给了这次机会,有幸能参加这次线下决赛。第一次参加这次攻防性质的线下赛,不免有些不知所措,比赛的时候也是走一步看一步。

首先说明一下这次线下赛的比赛规则。这次线下赛共有16支队伍参加,其中校内队有6支初赛队和2支大一新生队,校外队邀请了6支高校队伍参加。比赛共有5道题目,2道Web,2道Pwn和1道逆向。其中逆向题由赞助方“深思数盾”提供,逆向题在比赛前2天放出,比赛时提交flag可以多获得3000分初始分。另外4道题都是攻防形式给出,各队可以给自己的题目打补丁防御其它队伍的攻击,flag每个5分钟更换一次,每轮被攻击后减20分,每轮check程序检测服务异常减40分。大致规则就是这样。

这次比赛感觉有很大的运气成分在里面,比赛结束后居然拿到了第2的名次,比赛结束后的榜单如下:

榜单

队伍 Nu1L 真的很强,不仅做出了逆向,而且全程无懈可击。

由于自己队伍里没有PWN的选手,比赛之前就打算放弃逆向和PWN。给自己队伍定的目标也是不要太难看,能进前10就可以了。所以之前对于提前放出来的逆向题目也没有太关注,感觉挺对不起主办方,毕竟人家给题目放了那么多水。

比赛当天,上午公布1道Web题和2道Pwn题,下午公布最后一道Web题。比赛开始后,先去服务器上将自己的代码备份一下,并开始Review自己Web。第一道Web题是主办方用thinkphp自己编写的博客系统,目标是防止获取admin权限从而拿到flag。zoolsher刚上来就发现了一个后台未校验权限的漏洞,导致任何登陆用户都可以进入后台。看到这个漏洞后,zoolsher抓紧写自动化脚本,提交其它队的flag,我和另一个队友就手动注册用户记录cookie,并手动抓取几个flag提交一下。上午的时间就是一边使用脚本抓取flag,一边查看其它队伍怎么修补的漏洞,试着改进抓取脚本。有的队伍返回了一个假的flag,被检查程序check down了;有的队伍发现新注册用户就立即删除,于是我们改进每次都新建用户直接登陆抓取;还有些队伍修补了漏洞,这样子就没办法了。

上午3个小时很快就过去了,中午主办方发了盒饭,很好吃。

下午大部分队伍修补了漏洞,这个漏洞价值下降,考虑应该使用新的漏洞了。下午一开始就放出了另一道Web题,是一个cms系统 Drupal,版本是 7.54。搜索了几个漏洞,感觉都利用不上,考虑了一下暂时放弃了。这时候主办方提到了上传问题,查看了一下可以上传头像放置在 public/uploads/images/ 文件夹内。没有校验上传文件的类型,上传文件保存的格式为 <md5>.<上传文件扩展名>.html,接下来就是查找利用位置。找了一圈,在个人主页发现了问题,个人主页渲染使用的模板名是数据库里的值,而数据库里的值可以通过前端表单修改,虽然前端使用列表框限定选定的值,但是后台却没有对这个值进行过滤,这就有了利用的机会。

先在自己的服务器上实验一下,thinkphp的模板支持执行php代码,于是构造了一个上传文件

1
2
3
{php}
echo file_get_contents('/var/www/flag');
{/php}

渲染的模板不能有其它扩展名,于是这个上传文件不能有扩展名,需要上传的文件存为 avatar ,这样上传后的文件就变成了 <md5>..html,正好可以进行渲染。

总体的步骤如下:

  1. 注册用户
  2. 登陆,修改上传修改个人头像
  3. 获取当前用户ID和上传头像的文件名
  4. 修改个人主页的模板为上传的头像位置 ../../../../../public/uploads/images/<头像名>,不带.html
  5. 根据用户ID访问个人主页,拿到flag
  6. 将flag上传
  7. 将模板修改为 default ,防止在数据库里太明显(太坏了)

一切都测试好之后才开始正式使用,除了第一的 Nu1L ,真是打的其它队一个措手不及。靠着这个漏洞又赚了一波分数。

下午5个小时就研究了一下这个漏洞。

比赛总体下来,我们的Pwn次次被打,而且还down过几次,打了也没办法,down只好乖乖把备份传上去整好。真是别人去你家偷东西你还不能还手,门搞坏了也要默默弄好让别人下次接着偷👿。下午还发现了一个内存马,杀掉除root以外的apache进程就可以了,sudo -u www-data kill -9 <进程号>,不过杀了一次后他们没有攻第二次,看来他们的洞利用起来有些麻烦,估计是手动的。

整个比赛下来收获很多,一方面见识了一下强队的风采,另一方面也加深了对CTF的了解。真的感谢 Nu1L 队没有与我们争 Web1 的分数,不然总分肯定会下降不少😂。最后感谢TSCTF2017主办方“天枢”战队和赞助方“深思数盾”。