bctf的壯丁

被抓壯丁

4月18號晚上接近24點的時候,Kelwin突然在Hangouts上ping我說「bctf平台求开发」、「只有前端」。
原因是bctf官網的開發者maskray跑去玩超算沒有時間了。然後本着有補助爲何不拿的心態就答應了下來。

前期開發

簡單瞭解了一下需求,是接受實時的pwn信息然後在屏幕上的battlefield繪製一些動畫來展示。由於實時性的要求就選擇了socket.io做爲前後端通信手段。
在剛搞完框架之後,Kelwin又突然提出說把提交和更新flag的服務器也讓我做。瞬間需求就變化了,於是將battlefield移到一個子目錄,主repo寫服務器。
express做http服務器,mongodb存儲數據,socket.io和前端通信。

最開始作爲版本控選用了最新的express 4,結果發現bodyParser不能解析JSON格式的POST請求,試圖hack之無果之後不得不退到成熟的express 3進行開發。
剛搞到能跑的時候(其實flag的有效性都沒做複雜驗證,爲了調試方便),突然Kelwin又告訴我說需要加一個積分榜。瞬間我又需要寫算分的代碼了,同時還有維護所有回合的信息。
這時又有一個需求是要求斷電也要能迅速重啓,於是將一些實時性的數據每次修改時放入redis,啓動時如果redis中存在對應記錄便從中恢復。

七搞八搞之後似乎可以正常工作了,於是交由zTrix完善flag的驗證程序,據說他被coffeescript坑了不少下。

最後在4月29號來到南京繼續開發,由於錯誤估計了南京的氣溫和風速,只帶了短袖短褲。幸虧來的時候穿的牛仔褲,要不然肯定是出師未捷被凍死的節奏。
和maskray以及cbmixx抵達之後吃了頓戰鬥飯,直接奔赴江寧區的會場。

經過兩天的開發,又增加了pwning wall的功能。在maskray的建議以及被初賽的70G/h的攻擊流量嚇到之後又將server拆分,一部分僅接受和處理POST請求,另一部分向前端推送實時信息。
兩者直接使用redis的pub/sub機制通信。藉由此機制maskray又在bctf.cn上配置了一個redis-slave與推送服務器,這樣公網的流量將不會對場內服務器產生影響。
同時maskray也利用這個推送系統增加了trend榜,繪製了每個隊伍的得分曲線。

比賽前夜又臨時增加了暫停輪的功能,結果由於修改了schema導致連鎖反應,Kelwin和zTrix幫我修到晚上3點才修好。

決賽現場

雖然經過了前一天的模擬運行沒有發現bug,但還是提心吊膽地盯着大屏幕兩天。大屏幕是3072x768的,分成三個部分,分別展示scoreboard,battlefield和pwning wall三個實時信息頁。
運行到一個小時的時候就發現回合切換的時候會發生明顯的卡頓,但是自己本機開的頁面沒有問題。經過估計大約是非專業顯卡很難帶動如此大的屏幕,於是我的重型前端battlefield就赫然成了顯卡殺手。
最終的解決方案是兩小時刷新一次,因爲實在是找不到好顯卡。

不過還好的是服務一直在穩定運行着,直到第一天比賽暫停的時候發現最後一輪的單回合得分沒有清零就直接累加了,幸而經檢查發現不會對總分有影響。

第二天中午離比賽結束還有4小時的時候突然告訴我最後一小時要封scoreboard(以便於黑箱操作「大誤」),於是又臨時增加邏輯使得不會推送得分信息。
重啓服務的時候手都是抖的,因爲僅僅在本地進行了簡單的測試,如果最後一小時出錯了真的有晚節不保的感覺。

萬幸的是,雖然做爲顯卡殺手讓大屏幕不得不2小時刷新一次,但兩天的高頻訪問與一些選手的攻擊下並沒有出現有影響的bug,在倒計時結束的時候真的松了口氣。

賽後

賽後總結的時候來自臺灣的冠軍隊HITCON 217的領隊還專門來諮詢展示頁面的作者,於是和maskray一起受到了表揚,也算是對前端狗的一種肯定吧。
據說CTF的頂級賽事DEF CON的信息展示比較次,然後戲言之雲「DEF CON可以請我去做前端了」。
慶功自然是blue-lotus傳統的海底撈,成功搶得食物無數。

後來

大約就是去找了一下在NJU的小學同學,受到了熱心接待,並成功騙得毛衣一件,襪子兩雙,終於結束了涼鞋+短袖的凍成狗的日子。