<span id="7ztzv"></span>
<sub id="7ztzv"></sub>

<span id="7ztzv"></span><form id="7ztzv"></form>

<span id="7ztzv"></span>

        <address id="7ztzv"></address>

            原文地址:http://drops.wooyun.org/tips/9405

            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和資料:

            <span id="7ztzv"></span>
            <sub id="7ztzv"></sub>

            <span id="7ztzv"></span><form id="7ztzv"></form>

            <span id="7ztzv"></span>

                  <address id="7ztzv"></address>

                      亚洲欧美在线