AWD平台搭建


因為之前是被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

 

https://mp.weixin.qq.com/s?__biz=MzU1MzE3Njg2Mw==&mid=2247486325&idx=1&sn=96c04f3609a04260eabdd187fc7c38b1&chksm=fbf79105cc8018131579ad228dbf22a33bbdf0c8c71d3b8c090583b42ea21d80de53fc1efa70&scene=27&key=593393174013ce6d958e86eb764289b105cb7cea44d471bd3f9fe1a2ed76f546343dacb9b40a352e642e425b55c2a4d9698146a114ecd9680ed3262c8f96f6a206f0c78d6818ce0028c9bc75830936f0&ascene=7&uin=NTQ5ODg5NzY1&devicetype=Windows+10&version=6206061c&lang=zh_CN&pass_ticket=s3n8uD0SG7m1vojw%2F%2BN7uxdrTxvWnumzuUe%2BTLY12QY9yFKjU7n%2FNruWi9PS1sJO&winzoom=1

 

現在搭建后,還是有點問題的,數據庫連接不上。比較尷尬啊這個下去之后解決了,我再寫出來

-------------------------------------------------------------------------再次更新--------------------------------------------------------------------------

每套題里面都有writeup,里面有一套easycms猜測是其他像類似的cms也能搭建出來。選手好像不能連接本地的數據庫,但是能注入,暫時還不太清楚是怎么回事。看writeup里面好像能用curl執行得到flag的命令。

----------------------------------------------------------------2019-08-14再次補充-----------------------------------------------------------------------

看着有那么多人看我博客,還是挺喜歡的,最近又發現了一個AWD平台,有時間的話,我會搭建一下,雖然這個平台功能還能用,但是吧,有個功能好像沒實現就是不知道是誰攻擊誰,也不知道哪個隊伍分數變化最快,這就比較尷尬了。所以另尋他路,就再搭建一個試試吧。另外要搭建的,還是學長(大佬)告訴我的,哇塞,那個平台看着是真的好呀。就是學長說還有一點小bug,唉,有點可惜,不管餓了,到時候搭建個試試。對了,另外的平台是在github上面的,在github上面一搜就有了。

因為搭建的時候也是遇到很多坑,希望后來的人可以少走這些坑。所以堅持不水文


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM