線下AWD平台搭建以及一些相關問題解決


線下AWD平台搭建以及一些相關問題解決

 

 

一.前言

  文章首發於tools,因為發現了一些新問題但是沒法改,所以在博客進行補充。

  因為很多人可能沒有機會參加線下的AWD比賽,導致缺乏這方面經驗,比如我參加過五次線下AWD攻防,雖然看過許多網上的AWD打發套路,但終究都是紙上談兵,所以前幾次都是被吊錘,一來不熟悉環境,二來有點手忙腳亂,其實根本原因就是缺乏經驗,因此最近翻了翻Github,終於找到一個不錯的項目,下面便是搭建過程和一些注意事項。

二、平台搭建過程:

准備工作:需要准備一台Ubuntu虛擬機,我的版本是16.04,過程比較詳細,如果會這些的大佬挑重點看就行。
1.更新apt包索引
     $ sudo apt-get update
2.安裝git
     $ sudo apt install git
3.安裝docker
     $ sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common
     $ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
     $ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu$(lsb_release -cs) stable"
     //查看可用的docker
     $ sudo apt-cache madison docker-ce
      [attach]79574[/attach]
     //選擇要安裝的特定版本
     $ sudo apt-get install docker-ce=<VERSION>
     //比如我要安裝 18.06.3~ce~3-0~ubuntu,命令如下
     $ sudo apt-get install docker-ce=18.06.3~ce~3-0~ubuntu
4.克隆項目
     $ sudo git clone https://github.com/zhl2008/awd-platform.git
5.進入項目
     $ sudo cd awd-platform/
6.下載鏡像
     $ sudo docker pull zhl2008/web_14.04
到此環境已經搭建完畢了,接下來講一下操作方法和規則:

三、操作方法:

以root權限進入/awd-platform目錄下,以yunnan_simple鏡像為例:
鏡像已下載,直接啟動即可
1.復制鏡像
     # python batch.py web_yunnan_simple 3//復制3個web_yunnan_simple的靶機,數值可改
     # python start.py ./ 3 //啟動三個docker靶機和check服務器、flag_server服務器。數值可改
2.裁判機啟動:這里他寫的check.py有問題,是無法啟用的,所以我改了一下,根據爬取頁面關鍵字判斷網頁是否被刪除,當然也可以添加其他的頁面,比如不允許刪除admin.php,可以添加admin_check()函數,根據admin頁面關鍵字判斷是否被刪除。

#!/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)

#docker attach check_server
#python check.py

 

 

 

 

 

 

 

 

 

我稍微改了一下它的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
3.關閉環境命令:
#python stop_clean.py

四、注意事項及規則:

1.靶機端口規則:(假設服務器ip為192.168.1.1)
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
愉快的玩耍吧

五、解決的一些問題:

在一次測試中,發現在一輪的五分鍾有效時間內一直提交某個對手的正確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)

目前這個問題解決了,但是需要一點技巧,就是開啟這個腳本的時間要把握好。多調試幾次應該就差不多了。

 參考:

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


免責聲明!

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



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