ZJCTF 只做出三道半的 writeup

ZJCTF 只做出三道半的 writeup

编程那点事 随便写写 CTF 2428 字 / 5 分钟

今年的土豆不行啊

第一次参加 CTF,完全没有任何基础。原本预期的是能拿到一个 flag 就很满足了,最后是做出了两道签到题 + 一道 JavaScript 的题。(好菜啊) 只能说刚开始的体验真的很差啊,网站各种卡各种打不开。先是进不去做不了题,做了题后又提交不了 flag,能提交了验证码又迟迟刷不出来……后来是说杭电的服务器被 DDoS 了。额,今年的土豆不行啊。 刚开始页面加载不进去的时,我看到 JS 文件已经加载好了,就看了下 JS。找到了题目的接口,访问后返回的 JSON 里有题目的 URL,然后才得以开始……

那么,就来聊聊我做的那几道题的想法吧~

签到题 01.石庆数马 - 普通的 404 页面

http://sec3.hdu.edu.cn:61234/3gUrn2DpbJ

刚进入第一道的时候其实心情是很兴奋的,然后尽往难的地方想。先是翻了下页面的 CSS 文件(是的,我觉得题目很坑会把信息放在 CSS 注释里),结果没找到。之后看到两个页面上都有两张 png 图片,全部下载下来,改成 txt 打开找 flag。还是没找到。 最后心态缓和下来后,发现第二个页面底部的一大行 HTML 注释,都是在引入 jQuery 文件,引入的文件名有一个字母不同,从上往下看就是 flag。(被自己蠢哭)

然后又没有好好看规则,以为和南邮 CTF 一样是将 flag 包括大括号那些全部提交,结果发现不对。试了好几次,最后才明白是提交大括号里面的内容。(又一次被蠢哭)

签到题 02.眼疾手快

http://sec3.hdu.edu.cn:61234/blZEtvr3up

点击网页中的曲奇饼 10000 次就可以得到 flag。这题倒是蛮容易的,F12 开控制台,直接看到 JavaScript 源码。发现是判断 clicks 变量是否大于一百万次,如果大于则连带着点击的次数发送 POST 请求。我是直接在控制台中输入

clicks = 999999

回车后,再点击一次曲奇饼,就满足条件发送请求出 flag 啦~

04 - 1 你追我赶 - 玩就行了呀~^_^

http://sec.hdu.edu.cn/game/home

又是一道 JavaScript 的题,看来我好像只会做这种简单的 web 前端题了…… 进入后是 Google Chrome 中的经典 Alex 小恐龙彩蛋游戏。玩了一下,没一会儿就死了。 小恐龙的游戏的主程序是在 index.js 里面的,非常的长,很难直接辨认出哪些是 Google 的代码,哪些是后来加上去的。 然而我发现每次 Game Over 后,控制台都会输出我的分数,在 Chrome 的控制台上你可以点击右边的 index.php:881 来定位到 console.log() 函数的具体位置,也就是 881 行。 然后我就发现了这个:

 /**
* Hey man, tell me your score, I`m your god now.
*/
view: function (score) {
    console.log(score);
    // Too young to simple
    if (score < 30000) {
        return "hello kitty";
    }

    // Quickly tell me, I`m thirsty to death.
    var http = new XMLHttpRequest();
    var url = "/game/push";
    var params = "score=" + score;
    http.open("POST", url, true);

    // Send the proper header information along with the request
    http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    http.onreadystatechange = function() {
        if(http.readyState == 4 && http.status == 200) {
            // Tell u the f-l-a-g...
        }
    }
    http.send(params);
    return "hello world";
}

可以看到这里的注释还是写得十分贴心的。当 score 小于 30000 时,函数直接返回值就退出了。若大于 30000 就将 score 发送 POST 请求到 /game/push,由后端判断分数并返回 flag。 我刚开始是直接百度打开了个在线 POST 平台,发送 POST 请求后发现并不能返回正常的信息。在请求上加上了页面的 Cookies 以及一些请求头信息后发现都不行。也不是很清楚是为什么。(我后面那桌的哥们就是卡在这里然后没做出来) 之后我换了个思路,直接复制上面那段 JavaScript 到控制台,改 params 变量为 score=99999 直接回车发送请求。 这下居然就成功了!在 Connect 面板我们可以看到发送的请求以及返回的 JSON 中所包含的 flag。 果然 JavaScript 这种在本地浏览器上跑的语言就是如此的开放……

02 - 1 躲躲藏藏 - 你要在二维马中找找找找找到flag

http://sec3.hdu.edu.cn:61234/H/DDoIM5Ez.png

这道题我只能说是做出了一半…..明明 flag 就在眼前,但就是不行。就差那么一点点。哎,难受。 分类的话应该是算在 misc 里面的,直接一张二维码,手机一扫出来个 you find me,并没有什么用。 百度了一下,发现 CTF 很多题都有图片隐写。一般是一张图片里面包含了其它的文件。(或者叫做“图种”?) 百度说可以使用 binwalk 来查看图片的文件头,从而发现里面所藏的其它文件。 binwalk 是用 Python 写的。需要从 GitHub 上 clone 下来安装运行。结果那垃圾网速使得我每秒只有几 kb,怕不是比赛都结束了我还没下完。 直接 ssh 登上美国的 VPS,先在服务器上飞速 clone 再打包下回本地。30 秒就搞定了。 首先先是查看 png 图片的文件头:

binwalk DDoIM5Ez.png 

出来以下结果:


DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             PNG image, 85 x 85, 8-bit/color RGBA, non-interlaced
91            0x5B            Zlib compressed data, compressed
982           0x3D6           Zip archive data, at least v2.0 to extract, compressed size: 204819, uncompressed size: 412976, name: flag.xls
205929        0x32469         End of Zip archive, footer length: 22

说明我们这个 png 文件中其实还包含有 zip 文件在里面,二话不说,直接 binwalk 分割开来:

binwalk -e DDoIM5Ez.png 

得到的文件中有一个 flag.xls 的文件,但是它并不能用 Excel 打开。改成 txt 后查看了一下,在一堆乱码中找到了“疑似”的 flag。

flag is here zjctf{GFDGFA_GGDFFXXFFA_GGADXG_DFDGDGFAFA_GGDFFXXF}

然而提交却说错误!这就很奇怪了。翻看了下上面的一堆乱码,感觉这是个 Excel vba 程序,但是改成 exe 后又不能打开。 结束后在群里才听说 flag 中的这一串大写字母其实还是个什么鬼加密!还要再解密! 我天!比赛规则不是说 zjctf{} 中间的这一串就是 flag 了吗?你要搞加解密你别给我包在大括号里啊! 然后这题当时瞎搞了一个多小时还是没搞出来……

总结

最后一个小时里的附加题,有一道 SQL 注入的题,奈何它居然是盲注!我一个 SQL 菜鸡就一脸懵逼了。第一个文本框刚开始传了点如 1' or 1 = 1---这种,结果他说我太暴力2333。 之后忽然注意到了旁边的 UserID,传了 1,2,3,4,5 这几个数,都是返回水能载舟? 额……亦可赛艇?! 传到 6 的时候就是返回 HAHAHAHAHA 了,看来应该只有 1 - 5 这五条记录。之后就完全不知所措了。 在座位上开始划水,看排行榜上 Li4n0 学长他们队位于前三的激烈斗争。 然后我们队的排名,由最初的 18 名掉到了 40 多名……

难度的话,就我做出来的几道来看,感觉涉及的范围的不广。并且也没有什么 PHP 的代码审计啊…… 没南邮上的有意思。

嘛。第一次参加 CTF,也是抱着个玩玩的心态去的。虽然刚开始体验真的很差哈。但找到 flag 时还是真的很开心啊,提交的时候手都在抖。 下一次还有 CTF 比赛的话,我想带上我们宿舍的一个大佬,他这次因为迟迟收不到验证的短信而没来。如果他来了,我想逆向的题也应该能搞一下了。 回宿舍后把题给他看了下,那道小恐龙的题,他直接 Python 发送 POST 请求居然能返回 flag!之前我疯狂在线 POST 试了超久。他是真的强!

嗯,就这样吧,连最熟悉的 PHP 其实都可以变得这么陌生。感觉今后要学的东西还有很多啊。