BiliBili CTF writeup

开篇废话

怎么说的 bilibili 的这个 ctf 完全就是个脑筋急转弯活动,并没有看到什么船新的套路感觉被骗了一样
不过,即使是这样说,我依然有做不出来的题目
为什么这么说呢,请看下面的 writeup
另外 flag 都是以 uuid 形式提供。

题目

1 页面的背后是什么?

第一题就是个签到题,没有什么东西(F12看 dom 或者 network 都能找到 flag)

flag1_result_dom
flag1_result_network

2 真正的秘密只有特殊的设备才能看到

低仿黑曜石浏览器,,, 一开始我还搜索了一下,以为是和前年一样,在**浏览器官网找到UA,然后再填,结果就是我错了。 flag2_result
flag2_web_history

这里再吐槽一下,官方也没说 flag 是 uuid,害得一开始我还对着 404 的图片开艹了 flag2_files

3 密码是啥?

这个不说什么了,对着字典艹肯定跑不出答案的,,,
ustclug 群里一位人提供了密码(

username: admin
password: bilibili

另外 flag 默认是 alert 方式提供的,所以先提前开好 F12 network 比较好

flag3_result

4 对不起,权限不足~

这道题倒是一看就知道要改 cookie
先看看现在的 cookie
这里很明显多了个 role

session=eyJ1aWQiOiIzMTg1NTYwIn0.X5WjuQ.lSile6CrouYiiABH8eDEizBWdKc; role=ee11cbb19052e40b07aac0ca060c23ee

那么这个 ee11cbb19052e40b07aac0ca060c23ee 是什么呢? 一搜索就可以知道是 md5 后的 user

于是我们就可以把 role 改成 超级管理员 也就是 superadmin 就可以获取 flag 了
看到这是不是 很 简 单 ?
试的过程很蛋疼,,,
一开始我测试了 superadmin root admin administrator 甚至是中文的 管理员 之类的,都不行

然后测试了 Administrator 然后就ok了(艹 flag4_chat
微软的登录都不考虑大小写 直接用 administrator 都行,为何不再多个判断让大家大半夜猜这猜那呢

flag4_result

做完这题后就睡觉了,第二天我甚至 mac 都掉地板上了 没被我压爆真是万幸

5 别人的秘密

这题一开始以为会是sql注入的, 扔 sqlmap 跑了下并没有什么软用,然后看了下源代码(甚至tag还没闭合,,,)
出现了个 100336889 可能是个社工题目
flag4_uid
于是我访问了这个用户的b站空间,并没有什么东西
https://space.bilibili.com/100336889
然后又搜索了下,同样没有什么结果
甚至 QQ / Wechat 上也搜索了,没有东西
尝试把 uid 改成 1 2 甚至陈睿的也没啥用,,,
然后偷窥了下群里,原来这玩意是个穷举题(艹) 大草原,,, 明明可以成为个好的社工题目的,怎么变成这么弱智的玩意了

const axios = require('axios')
async function run(id = 100336000){
    let d = (await axios({
        url: 'http://120.92.217.120/api/ctf/5?uid=' + id,
        headers:{
            'Cookie': 'session=eyJ1aWQiOiIzMTg1NTYwIn0.X5WjuQ.lSile6CrouYiiABH8eDEizBWdKc',
        },
        json: true
    })).data
    if(d.code !== '403'){
        console.log('ok',id)
        console.table(d)
    }else{
        console.log('不太行',id)
        setTimeout(()=>{
            run(id + 1)
        },30)
    }
}
run()

随手撸的穷举代码,参考一下。

flag5_result

6(不会)结束亦是开始

这道题不会做 不过基本可以认为是 sql 题,,,
通过 single.php 的源代码可以知道 b 站 抄袭了 MyBlog-php 的源码,并改了改
另外在扫目录的时候扫到了第十题的题目(草)
更多精彩内容可以看这个 issue
不止我一个人是这样((((

7 NULL

第七题以后都是盲题,需要自己找题目,这时候我们就要扫端口 扫目录 还有运气了

8 Redis

接上,这题是盲题,扫到了 redis 端口(6379)
redis 在以前出了个大事件,无密码 + 端口开放在公网,然后就是变成了全网删库 全网 getshell(草),有兴趣的可以搜索下
这个倒是还算 ok 连上去后直接输入 get flag8 就好了 // 另外这个 redis server 是个蜜罐

flag8_result

9 NULL

¿ 如第六题一样

10 审计代码 + cat 图片

接第六题,在扫目录中找到了 test.php 一看就知道是 jsfuck,我们随便找个 decoder 或者 F12 扔 console

var str1 = "\u7a0b\u5e8f\u5458\u6700\u591a\u7684\u5730\u65b9";
# "程序员最多的地方"
var str2 = "bilibili1024havefun";
# 这里肯定就是关键词了
console.log()

然后根据关键词 程序员最多的地方最大的同性交友网站啊什么的 搜索关键词代码 bilibili1024havefun

找到了个 end.php 审计代码题目嘛,我们来分析这几行 php 代码都判断了什么。

<?php
$bilibili = "bilibili1024havefun";
# str 用 intval 变成整数(
$str = intval($_GET['id']);
# 正则 拿来匹配数字)
$reg = preg_match('/\d/is', $_GET['id']);
# 这里判断 get -> id 不能为数字
# 正则匹配到的 get[id] 要 == 1
# intval 的 get[id] 不能 == 1
if(!is_numeric($_GET['id']) and $reg !== 1 and $str === 1){
    # 一开始我还在想是不是构建个 phar 之类的 结果我错了,,,
    # 下面基本不是他们比赛线上的代码,改了很多,请求 /.*/flag.txt 就差不多
    $content = file_get_contents($_GET['url']);
    //文件路径猜解(官方注释)
    if (false){
        echo "还差一点点啦~";
    }else{
        echo $flag;
    }
}else{
    echo "你想要的不在这儿~";
}

这显而易见,传入 get[id] 传入个数组就能绕过判断了,参考我之前做的 Google ctf
于是现在就可以构建 payload 了

http://120.92.151.189/blog/end.php?id[0]=1&url=/flag.txt

顺利获取到了图片。 我们直接 cat 这个文件

> cat Downloads/bilibili_224a634752448def6c0ec064e49fe797_havefun.jpg
?????DF(省略)
{{flag10:2ebd3b08-47ffc478-b49a5f9d-f6099d65}}

顺利拿到第十题的 flag

这里再吐槽下,,,
出题的就 echo ‘{{flag10: xxxx}}’ » xxx.jpg 要我出题我至少会 base64 一下

后记

我不想做脑筋急转弯,麻烦搞点正常点的题目