一個隊伍有三個人,比賽環境中每個隊伍有兩臺靶機,兩臺靶機上有兩個web。
比賽一共三個小時,前30分鐘爲修復時間,後兩個半小時爲對抗時間,每個靶機上都有一個flag,flag半小時刷新一輪。
根據以往的線下賽的經驗,在加固階段要做的有:
1.備份源碼
兩臺靶機,一個人進行備份已經足夠,windows平臺上使用scp就行,十分方便,比賽給的兩個web都是php寫的。
2.佈置抓取流量的waf
線下賽佈置waf很重要,能夠第一時間反應過來自己是怎麼被打的,waf 用的是下面這一款,能夠記錄詳細的攻擊流量,並且對於一些常見的攻擊也能夠阻擋,具體的佈置方法就是找web目錄下所有文件都會包含的config.php或者對於框架性web來說直接找入口文件index.php,然後只需在index.php或config.php中對waf進行包含就可以了,一般放在文件的最前面,包含結束以後,因爲waf會進行寫日誌文件,所以需要給waf寫文件的權限,一般靶機的權限是能夠給waf chmod寫權限的
https://github.com/dr0op/k4l0ng_WAF
3.掃後門,找洞
按照出題人的一般套路,總會在web目錄下的某個文件下留個後門,所以可以使用提前準備好的D盾對之前已經備份下來的web源碼進行後門掃面,web1是用原生的php寫的,在掃面後檢測到web1的目錄中發現了n多後門,所以此時應該迅速把所有預留的後門註釋掉,並且記下相應的路徑,放在批量腳本中。web2是一個框架應用,只存在一個後門,在用D盾掃過後發現後門直接註釋即可,除了後門以外就需要手工找洞了。
4.寫批量腳本
此次比賽本科組一共有44個隊伍,因此手動提交flag肯定很慢,因此批量提交flag的腳本需要提前準備好,我們比賽中使用的是學弟寫的腳本,腳本會自動讀取flags.txt中的flag,其中的格式必須是“ip+----+flag”,flags.txt的flag是批量攻擊腳本中寫入的
import requests ips = [] flags = [] def submit_flag_auto(ip,flag): url = "http://192.168.80.1/lms/portal/sp/hz_flag.php" headers = { "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36", "Referer": "http://192.168.80.1/lms/portal/sp/hz_flag.php", "Cookie": "SSCSum=11; zlms-sid=hqfg26bm4766uanj9vm3fel9f7; webcs_test_cookie=lms_cookie_checker; lms_login_name=302-13" } data = { "melee_ip":ip, "melee_flag":flag } response = requests.post(url,headers=headers,data=data) print(response.text) with open("flags.txt","r",encoding="utf-8")as f: for line in f.readlines(): line = line.strip() line = line.split("----") ip = line[0] flag = line[1] ips.append(ip) flags.append(line) for i1,i2 in zip(ips,flags): submit_flag_auto(i1,i2)
在攻擊階段要做的是:1.利用已有的exp打;2.挖新的洞:3.權限維持
web2是ashop,也是基於mvc的形式,目錄結構如下所示
index.php也就是入口文件,static和view通常是一些靜態文件,config是配置文件,data是數據庫文件,model是和數據庫交互的文件,那麼就需要審計controller文件夾和core文件夾,因爲邏輯都在這兩個文件夾中,我們在比賽中主要找到了兩個web2的洞,一個任意文件讀取,一個反序列話漏洞。
反序列化漏洞:
在index.class.php文件中可以發現這一句,爲客戶端設置了一個cookie值,並且在login.class.php中進行解序列化,所以我們只需要將payload替換了原始的AshopToken,然後訪問login.php就可以觸發反序列化漏洞。
所以我們只需要在客戶端替換AshopToken值就可以讀取flag文件了.
任意文件讀取:
在index.class.php中存在這樣一個show_pic()函數,可以看到最終會調用file_get_contents函數讀取$pic變量,那麼$pic變量又是調用get函數以後的返回值,在這裏我們跟蹤get函數,在core文件夾下面存在init.php文件,裏面存在如下代碼:
get函數會對超全局數組GET進行transcribe函數,並且檢測$_GET[$str]變量是否存在,若存在則返回此變量的值,那麼transcribe函數又是進行了什麼操作?
transscribe函數實際上會對GET函數消毒處理,但是對於任意文件讀取漏洞並不起作用,所以我們只要訪問show_pic.php?file=../../../../../../../flag.txt就能訪問到flag文件了。
比賽中的不足:
雖然提前準備了不死馬,但是並沒有利用漏洞佈置上去,所以下次比賽中應該手速快一點,先利用漏洞佈置不死馬維持好權限,接下來再批量拿flag。