CTF主辦方指南之對抗攪屎棍

wyzsk發表於2020-08-19
作者: phith0n · 2015/10/08 14:57

0x00 背景


XDCTF2015是我覺得很給力的一次CTF,題目難度適中,也沒出什麼亂子,圓滿結束了。

向來CTF是很容易出亂子的,有時候亂子來自於自身,比如某年的XDCTF因為學校機房停電導致初賽停頓了幾個小時。當然,更多的亂子來自於“駭客”。因為CTF是安全相關的競賽,自然會吸引很多安全研究者的目光。這裡的“駭客”就是指透過各種手段讓其他選手沒法正常做題的人。

這樣的選手一般自稱“攪屎棍”~嘿。當然我沒有譴責他們的意思,比賽就是和他人競爭的過程,透過各種手段阻止對手拿分我覺得也是一種能力。但是作為主辦方,我們需要儘量讓所有選手正常比賽,以保證一定的公平。所以我寫這份文件,記錄這次比賽我的處理方法。

0x01 保證題目質量


這是一切防禦手段的本源。

題目需要難度適中。如果太刁鑽,容易讓人放棄,併產生報復心理,放棄過後餘下的時間就是給你搗蛋的時間。也不能太白痴,太白痴的題目被人分分鐘秒了,餘下的時間也是用來搗蛋的。

感覺題目難度要讓人有這種感覺:這題我會,應該這樣做,但好像有個坑,我想想怎麼繞過……在一段時間的辛苦後,把題目做出來;或者題目在規定時間沒有做出來,看了writeup後恍然大悟。

這樣的題目,才會讓大家有成就感、學到東西、感激主辦方。這樣下來,就能減少很多麻煩,一是大家不願再給主辦方添麻煩,二是做題很累也沒工夫想別的。

0x02 防禦第一招——程式碼層


有些許可權限制,在程式碼上防禦就可以了。

比如這次的web2-100,是一個任意使用者密碼修改的漏洞。選手在挖掘出漏洞併成功修改前臺管理員的密碼後,登入進去就能看到flag。Flag是儲存在使用者檔案中的,正常情況下xdsec-cms允許自己刪除自己的檔案。那麼,如果第一個做出這個題目的同學拿到flag後,隨手把檔案一刪,那就沒有第二個了。

所以我在刪除的程式碼中,加了個判斷:

如果是管理員使用者,就直接返回false,不允許其刪除。增刪改查四個操作,刪、改都要加這個判斷。當然,好事者可以寫個指令碼,增加999999個假檔案,flag樣式都類似,誰也不知道哪個是真flag,也很影響接下來的選手做題。所以嚴格來說,“增”的地方也需要加這個判斷。

攪屎棍還有一個常用的手段,就是“暴力競爭法”。

比如某個題目需要兩個步驟,第一步修改使用者名稱為xxx,第二步觸發二次注入獲得注入結果。那麼我寫一個指令碼,用50個執行緒不停去修改使用者名稱為一個不相關的名字,這樣其他使用者就沒法正常執行第二個步驟了。(第一個步驟剛完成又被別人改沒了)這樣的情況下,其他參賽者一般會認為是自己的操作方法錯了,直接導致做題的方向偏離。即使參賽者發現是有人在攪屎,也只能去同樣寫一個指令碼,用100個執行緒跑,才有可能繼續做題。

我覺得這樣的BUG在出題的時候就可以避免。就拿我舉得這個例子來說,我們完全可以出一個多使用者的環境,不同使用者只能操作自己的使用者名稱,這樣就完全避免了上述問題。如果這一點做不到,那麼我們就應該按照12306對付刷票產業的方法對付“競爭派攪屎棍”——使用驗證碼。這樣將給競爭指令碼的編寫帶來很大難度,一般也就可以避免這種問題了。

0x03防禦第二招——服務許可權層


PWN暫時不說,WEB肯定會涉及一些系統服務:web服務、資料庫服務、快取服務等。其中,Web服務又涉及中介軟體許可權和指令碼許可權。我這裡以nginx+php為例,資料庫以mysql為例。

在很多ctf初賽中,web題目因為都比較“小”,所以經常是一臺伺服器放多個web題目。這種情況下許可權設定就極為重要。如果一個比賽因為許可權沒有設定好,導致選手用一個題目的任意檔案讀取漏洞,或者一個root注入+load_file直接讀取到所有題目的原始檔。結果好好一個ctf就瞬間變成程式碼審計比賽了。

所以沙盒環境是這類ctf必不可少的了,沙盒可以是近幾年的docker,前幾年的“虛擬主機”,或者只是簡陋的open_basedir,有總比沒有強。Linux沙盒具體怎麼佈置可以看我的文章:https://www.leavesongs.com/PENETRATION/nginx-safe-dir.html,我就不再贅述了。建議就是,一個題目放在一個獨立的虛擬主機裡。

在同一個題目中,服務許可權設定也是極為重要。

比如一個題目是將flag藏在後臺管理員密碼位置,那麼你可以用0x02裡說的法方法,這樣防範攪屎棍:

  1. 管理員不能修改密碼
  2. 不能刪除管理員
  3. 不能增加管理員

一旦有忘記的就悲劇了。那麼,不妨從根本上解決這個問題:直接去除當前資料庫使用者對於管理員表的“增”、“刪”、“改”許可權。在mysql裡就是類似GRANT select ON db.admin [email protected],只給予select許可權。當然,具體情況具體分析,可以制定出更細緻的許可權規劃。

在pwn中,也有同樣的問題。我們遇到了一個需要使用者執行命令的題目,在選手成功完成執行命令的目標以後,順手寫了個迴圈kill,將pwn自己的服務殺掉了,導致其他隊伍不能繼續做題。這確實是個棘手的問題,因為pwn fork出的程式許可權正常情況下是和pwn一樣的,那麼不管你再怎麼給pwn降權,你也避免不了使用者直接kill掉pwn程式。

我能想到的有這樣三種解決方法:

  1. 重新命名或刪掉kill、pkill、skill之類的可執行程式
  2. 將/usr/bin、/bin、/usr/local/bin等目錄的other許可權設定為0
  3. 使用selinux ,設定security context

法1最簡單,但可能考慮不周的,畢竟linux命令那麼多。法2比較粗暴,可能導致正常的操作都執行不了。法3應該是最合適的,但配置起來也最麻煩。這個需要看個人能力與ctf的複雜程度、重要性。

0x04防禦第三招——檔案許可權層


如果ctf涉及到檔案操作(讀取、上傳、刪除、修改、重新命名)的話,就得合理設定檔案許可權了。

首先,要先了解自己的題目對於檔案的操作具體可以允許到怎樣的程度:是讀取、還是修改,是否允許getshell。這裡有個勸告,CTF初賽魚龍混扎,儘量不要允許選手getshell。Getshell以後,攪屎棍就有無數種方法讓你的遊戲沒法繼續進行。

但有時候,題目的考點就是檔案上傳漏洞,或者任意檔案操作漏洞,不getshell怎麼驗證選手是否達到要求?我這裡以此次的web2為例子:web2-400的最終目的是使用者getshell,利用的是一個任意檔案重新命名漏洞,將正常檔案重新命名為.php後getshell。實際上我這題,最終要檢測的是“選手是否成功將檔案重新命名成.php字尾”。

所以實際上是可以不允許選手真正getshell的,我的做法是:

  1. 整站,只有指向index.php和th3r315adm1n.php兩個檔案的請求才會傳送給fastcgi執行:

    這樣就有效的保證了任意其他php檔案都無法執行,這一步主要是為了保證伺服器的安全。

  2. 所有其他以.php為字尾的請求,如果該檔案存在,我就認為使用者成功getshell了。這時就將請求rewrite到flag文字檔案裡,使用者得到flag:

    因為我這個環境,原本整個web目錄只有兩個php檔案,如果發現存在第三個php檔案,那麼就肯定是使用者的webshell了。

  3. 所有請求為“flag-”開頭,以“.txt”結尾的,全部返回403。這是為了防止有人直接猜到flag檔名:

    這三步下來,就完成了一個“getshell”漏洞的配置,模擬了getshell的情況,卻並不真正getshell。

那麼,一個檔案操作造成的getshell,除了防止選手真正getshell,還需要防範什麼?

當然是防範攪屎棍。攪屎棍有一千種方式可以讓遊戲玩不了:刪除/覆蓋/重新命名正常檔案、將正常檔案mv走,甚至是“幫助”主辦方修改flag,或者修改漏洞檔案。對付起來也很簡單,我將所有已存在的檔案(正常檔案)的許可權全部改成755,所有者改成root:

這樣即使有任意檔案操作漏洞,也沒許可權修改正常檔案了。

但大多數cms都會涉及快取、上傳目錄、備份目錄等等需要寫的目錄,如果也設定成不可寫,cms就執行不了了。比如這次題目,後臺有個靜態檔案下載功能,我不得不將css、js、img等目錄的所有者設定為www,使靜態目錄可寫。

熟悉linux許可權的同學應該知道,一個檔案是否允許被刪除,是要看其所在目錄的許可權。如果我對他所在的目錄有寫許可權,我就可以將其刪掉,即使這個檔案不屬於我。所以,透過後臺的刪除功能,攪屎棍可以將網站靜態檔案“刪光光”,直接影響後面的選手做題體驗。

這種情況怎麼辦?Linux下的檔案有一些“隱藏屬性”,我們可以透過lsattr來檢視,chattr來修改:

如上圖,這是我配置的js目錄檔案的隱藏許可權。

我將所有已存在的js檔案全部加上了i標誌(chattr +i *),i的意思就是,不允許對檔案進行任何修改(包括刪除)。

這時候我們可以試試rm:

如圖,root使用者也沒法刪除flag檔案了。

這就有效地保證了網站檔案的安全,攪屎棍沒法破壞網站結構與正常功能。巧妙地利用這些系統自帶的許可權控制能力,就能有效地防範攪屎棍啦!

0x05防禦第四招——對抗報復社會型攪屎棍


這類攪屎棍就是真正的“壞人”了,損人不利己,是直接來搗蛋的。比如自己拿下了flag,然後就把flag透過官方QQ群、IRC等渠道告訴所有人,直接破壞遊戲的可玩性與公平性。還有比賽的時候DDOS比賽伺服器的人。(那是跟你有多大仇)對於這類人,我覺得也沒什麼好說,該封號的封號,該拉黑的拉黑,儘量讓他無法接觸參賽選手。同時,伺服器的日誌要多看看,異常狀態可以及時發覺。推薦一個實時日誌檢視工具——ngxtop:

原始碼和使用方法可以github上搜。

如果主辦方保持一個好的態度,對參賽選手有足夠的尊重與耐心,一般是不會出現這類攪屎棍的。歸根到底,CTF是一個玩耍與學習的活動,不管是主辦方還是參賽者,都可以透過比賽學到很多東西。保持一個良好的心態處理問題,慢慢積累經驗,收穫都會大大的。

XDCTF2015的一些writeup和資料:

本文章來源於烏雲知識庫,此映象為了方便大家學習研究,文章版權歸烏雲知識庫!

相關文章