因為之前是被AWD比賽坑過,所以想着自己搭建一下啦。這樣方便可以本校和某高校,兩個學校的人進行相互交流,共同進步。
搭建前提:
ubuntu16.04鏡像,這個最好放到虛擬機里面進行加載。(附:Ubuntu的源可以換成阿里雲的,這樣的話下載速度就會比較快,這里我是給出別人的博客,我是換成阿里雲的源
https://blog.csdn.net/lym152898/article/details/79100507
在虛擬機里面啟動好之后,然后再加載docker容器,這個容器可以存放我們比賽時候的ctf環境。啟動比賽環境還是挺容易的,就是模板的問題,下面是搭建的步驟。
1.安裝docker環境:
正常ubuntu里面是沒有docker環境的,這樣我們就需要下載一個docker環境。因為是linux系統,所以還是命令行下載。不過我就不演示了,直接放出別人的博客吧。如果博客失效了,大家還可以是百度下ubuntu系統安裝docker環境。
https://www.cnblogs.com/jiyang2008/p/9014960.html
2.下一步就是克隆項目
sudo git clone https://github.com/zhl2008/awd-platform.git
3.進入項目
sudo cd awd-platform/
4.下載鏡像,木有鏡像等於白搭
sudo docker pull zhl2008/web_14
5.要以root權限的用戶,進入到這個目錄里面,如果是root權限的話會是一個 # 而不是一個 $ 。切換用戶的指令是 su 用戶
6.啟動鏡像
# python batch.py web_yunnan_simple 3//復制3個web_yunnan_simple的靶機,數值可改
# python start.py ./ 3 //啟動三個docker靶機和check服務器、flag_server服務器。數值可改
7.在當前目錄下,連接裁判機
docker attach check_server
python check.py
項目的check.py是有問題的,比如無法正常啟動,還有check的也是不怎么規范,所以還是修改一下,這里是宕的別人的。
#!/usr/bin/env python # -*- coding:utf8 -*- ''' ''' import hashlib import base64 sleep_time = 300 debug = True headers = {"User-Agent":"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36"} import time import httplib import urllib2 import ssl my_time = 'AAAA' __doc__ = 'http(method,host,port,url,data,headers)' flag_server = '172.17.0.1' key = '744def038f39652db118a68ab34895dc' hosts = open('host.lists','r').readlines() user_id = [host.split(':')[0] for host in hosts] hosts = [host.split(':')[1] for host in hosts] port = 80 def http(method,host,port,url,data,headers): con=httplib.HTTPConnection(host,port,timeout=2) if method=='post' or method=='POST': headers['Content-Length']=len(data) headers['Content-Type']='application/x-www-form-urlencoded' con.request("POST",url,data,headers=headers) else: headers['Content-Length'] = 0 con.request("GET",url,headers=headers) res = con.getresponse() if res.getheader('set-cookie'): #headers['Cookie'] = res.getheader('set-cookie') pass if res.getheader('Location'): print "Your 302 direct is: "+res.getheader('Location') a = res.read() con.close() return a def https(method,host,port,url,data,headers): url = 'https://' + host + ":" + str(port) + url req = urllib2.Request(url,data,headers) response = urllib2.urlopen(req) return response.read() def get_score(): res = http('get',flag_server,8080,'/score.php?key=%s'%key,'',headers) print res user_scores = res.split('|') print "******************************************************************" res = '' print res print "******************************************************************" return user_scores def write_score(scores): scores = '|'.join(scores) res = http('get',flag_server,8080,'/score.php?key=%s&write=1&score=%s'%(key,scores),'',headers) if res == "success": return True else: print res raise ValueError class check(): def index_check(self): res = http('get',host,port,'/index.php?file=%s'%str(my_time),'',headers) if 'perspi' in res: return True if debug: print "[fail!] index_fail" return False def server_check(): try: a = check() if not a.index_check(): return False return True except Exception,e: print e return False game_round = 0 while True: scores = get_score() scores = [] print "--------------------------- round %d -------------------------------"%game_round for host in hosts: print "---------------------------------------------------------------" host = host[:-1] if server_check(): print "Host: "+host+" seems ok" scores.append("0") else: print "Host: "+host+" seems down" scores.append("-10") game_round += 1 write_score(scores) time.sleep(sleep_time)
啟動check.py之后,環境應該是這樣的。至此,環境基本上就已經搭建完成了。后面還有一些東西可以看看
8.事項及規則:
1.靶機端口規則:(假設虛擬機的ip為192.168.1.1 , 虛擬機要和真實機要在同一個C段,如果是實驗室用的話,可以在vm里面設置一個橋接模式)
Team1:192.168.1.1:8801
Team2:192.168.1.1:8802
Team3:192.168.1.1:8803
……
以此類推
2.各個靶機的ssh密碼可以在項目的文件夾下的pass.txt文件中,開始比賽時告知各個選手ssh密碼。
SSH的端口規則為:(假設服務器ip為192.168.1.1)
Team1:192.168.1.1:2201
Team2:192.168.1.1:2202
Team3:192.168.1.1:2203
……
以此類推
3.提交flag方法:(假設服務器ip為192.168.1.1)
http://192.168.1.1:8080/flag_file.php?token=teamX&flag=xxxx
(teamX中的X為自己隊伍號,flag為其他隊伍的flag)
4.記分牌:查看實時分數情況,沒做到實時刷新一下(假設服務器ip為192.168.1.1)
http://192.168.1.1:8080
5.攻擊情況:(假設服務器ip為192.168.1.1)
http://192.168.1.1:8080/result.txt
9.這里有個異常就是可以無限提交flag,先放出別人的
在一次測試中,發現在一輪的五分鍾有效時間內一直提交某個對手的正確flag可以無限加分,在審計一波代碼后發現,關鍵點在這里
config.php:
<?php $team_number = 3; $user_list = []; $token_list = array(); $ip_list = array(); for ($i=1; $i <= $team_number; $i++) { array_push($user_list,'team'.$i); $token_list['team'.$i] = $i - 1; $ip_list['172.17.0.'.($i+1)] = $i - 1; } $key = '744def038f39652db118a68ab34895dc'; $time_file = './time.txt'; $min_time_span = 120; $record = './score.txt';
flag_file.php:
require 'config.php'; $now_time = time(); $flag_file = 'xxxxxxxx_flag'; function check_time($attack_uid,$victim_uid){ global $time_file; global $min_time_span; global $now_time; global $team_number; $old_times = explode('|' , file_get_contents($time_file)); //print $now_time; $id = $attack_uid * $team_number + $victim_uid; //print $old_times[$id]; if ($now_time - $old_times[$id] < $min_time_span){ die("error: submit too quick ". ($min_time_span + $old_times[$id] - $now_time). " seconds left"); }else{ return True; } }
這邊的flag_file.php包含了config.php的配置,即變量$min_time_span和變量$time_file,通過$now_time記錄當前時間戳,然后通過與$time_file記錄的時間戳節點進行相減,如果符合小於預設的時間差(即一輪多長時間)這一條件則當前時間段無法再次提交flag。
然而 ,$time_file = './time.txt'; 中的time.txt是這樣的
哈哈 ,為了辨別每一支隊伍代表的格子,將其寫為0|1|2|3|4......,然后將變量$old_times輸出,經過對比后得出team對應的位置(我這里只找了三個)
此時只需要寫一個腳本將五分鍾為周期的時間戳更新到time.txt中即可
腳本如下,在啟動docker之前五分鍾運行,或者后五分鍾也可以,改一下腳本內的配置即可,這個腳本是按照某一個時間整點的00 05 10 15 進行記錄時間戳的,按自己需要也可以改為其他的
#!/usr/bin/env python #coding:UTF-8 import time import os print int(time.time()) Unix_time = int(time.time()) print time.ctime(Unix_time) while True: time_his = [] time_list = ["00","05","10","15","20","25","30"] for i in time_list: dt = "2019-04-28 10:"+str(i)+":00" time_his.append(dt) a = time_his[0] b = time_his[1] c = time_his[2] d = time_his[3] e = time_his[4] f = time_his[5] g = time_his[6] time_stamp = [a,b,c,d,e,f,g] for k in time_stamp: h = open("time.txt", 'w+') timeArray = time.strptime(k, "%Y-%m-%d %H:%M:%S") timestamp = time.mktime(timeArray) print (int(timestamp)) data = (int(timestamp)) separated = '|' zero = '0' print >>h,(zero),(separated),(data),(separated),(zero),(separated),(data),(separated),(zero),(separated),(zero),(separated),(data),(separated),(zero),(separated),(zero), # 0|data|0|data|0|0|data|0|0 h.close() time.sleep(300)
目前這個問題解決了,但是需要一點技巧,就是開啟這個腳本的時間要把握好。多調試幾次應該就差不多了。
10.感覺這個頁面太丑的話,可以換一個頁面,這里是夜莫離大佬做的頁面
計分板文件拷貝至awd-platform下的flag_server文件夾下。要注意將文件score.txt與result.txt文件權限調至777,這樣才能刷新出分值。
還需將scorecard.php文件中的resul變量中的ip地址更改為虛擬機(因為我剛剛已經被坑過了。所以前來補充,不能改成0.0.0.0或者127.0.0.1)的ip地址。
近期更新:這套系統里面不用掃端口,是直接的內網映射到外網。這套系統是找flag的,相當於成功植入webshell之后在受害者的服務器根目錄能看到flag,然后把flag進行提交就可以了。每一個容器只有一個flag,並且flag是會變的,這就保證了一個隊伍不會被多次攻擊的(要是大佬拿到比自己還高的權限,那。。。哭泣泣)。如果想要變動時間,那么就需要check時間和flag刷新時間,因為原版兩分鍾一次,太快了,所以我把它改為了5分鍾。具體修改方法只要將/awd-platform/check_server/gen_flag.py 的time_span 變量設置為5*60即可,也可以改成其他的,同理還有/awd-platform/flag_server/config.php 的 min_time_span變量設置為300、/awd-platform/flag.py 變量time_span設置為5*60。
這套系統里面還有每個docker容器里面連不上數據庫的問題,其他基本上都已經解決了,大佬解決的話,給我留言下下,萌新去學習學習。不懂的小伙伴可以留言,我看到后就會回復的。
訪問ip:8080/scorecard.php來查看各隊得分情況。
計分板源碼打包:https://pan.baidu.com/s/18KlIeluaTtm-kT3KuXHseQ
提取碼:cvdn
11.玩累了關閉環境的命令
python stop_clean.py
12.參考鏈接
https://www.heibai.org/post/1468.html
https://blog.csdn.net/huanghelouzi/article/details/90204325
現在搭建后,還是有點問題的,數據庫連接不上。比較尷尬啊這個下去之后解決了,我再寫出來
-------------------------------------------------------------------------再次更新--------------------------------------------------------------------------
每套題里面都有writeup,里面有一套easycms猜測是其他像類似的cms也能搭建出來。選手好像不能連接本地的數據庫,但是能注入,暫時還不太清楚是怎么回事。看writeup里面好像能用curl執行得到flag的命令。
----------------------------------------------------------------2019-08-14再次補充-----------------------------------------------------------------------
看着有那么多人看我博客,還是挺喜歡的,最近又發現了一個AWD平台,有時間的話,我會搭建一下,雖然這個平台功能還能用,但是吧,有個功能好像沒實現就是不知道是誰攻擊誰,也不知道哪個隊伍分數變化最快,這就比較尷尬了。所以另尋他路,就再搭建一個試試吧。另外要搭建的,還是學長(大佬)告訴我的,哇塞,那個平台看着是真的好呀。就是學長說還有一點小bug,唉,有點可惜,不管餓了,到時候搭建個試試。對了,另外的平台是在github上面的,在github上面一搜就有了。
因為搭建的時候也是遇到很多坑,希望后來的人可以少走這些坑。所以堅持不水文