线下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("")
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 = ["","","","","","",""]

    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 = ''

            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

线下AWD平台搭建以及一些相关问题解决的更多相关文章

  1. CTFd平台搭建以及一些相关问题解决

    CTFd平台搭建以及一些相关问题解决 一.序言 因为想给学校工作室提高一下学习氛围,随便带学弟学妹入门,所以做了一个ctf平台,开源的平台有CTFd和FBCTF,因为学生租不起高端云主机所以只能选择占 ...

  2. 云服务器AWD平台搭建

    开学后实验室来了几个新同学,在线上CTF方面大家一直在持续学习,但AWD模式的CTF我们练习并不多,所以准备搭建一个AWD平台用于实验室成员的线下赛攻防练习. 最开始的是防灾科技大学的线下AWD靶场: ...

  3. CTF线下awd攻防文件监控脚本

    CTF线下awd攻防赛中常用一个文件监控脚本来保护文件,但是就博主对于该脚本的审计分析 发现如下的问题: 1.记录文件的路径未修改导致log暴露原文件备份文件夹:drops_JWI96TY7ZKNMQ ...

  4. awd平台搭建

    1.先是使用 https://github.com/m0xiaoxi/AWD_CTF_Platform 这个平台搭建 这个平台很好用,是python脚本自动搭建,基本不需要怎么更改,自带了四道题的源码 ...

  5. 代码审计-四叶草杯线下awd比赛源码web2

    今晚简单来看看那天比赛的源码吧,比赛的时候还是有些慌没有好好去静下心看代码. awd给的题中的漏洞,都是那种可以快速让你利用拿到权限后得到flag的那种,特别复杂利用的一般没有. 建议先黑盒去尝试,例 ...

  6. educoder SML程序设计题线下编译环境搭建

    背景 最近<串并行数据结构与算法设计>的老师在educoder上布置了一些SML程序设计题,虽然网站上有在线编译功能,但还是在线下编译调试方便,特记录编译环境过程如下(我用的GVIM,但N ...

  7. awd平台搭建及遇到的问题

    1.安装docker环境 a.使用的是ubuntu系统,通过sudo apt install docker.io进行docker得安装,此方式会自动启动docker服务. b.通过curl -s ht ...

  8. AWD平台搭建及遇到的问题分析

    1.安装docker环境 a.使用的是ubuntu系统,通过sudo apt install docker.io进行docker得安装,此方式会自动启动docker服务. b.通过curl -s ht ...

  9. Mac 下 Scala 平台搭建

    1.先要安装 JDK,下载地址: http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html ...

随机推荐

  1. ESP8266 LUA脚本语言开发: 准备工作-动手编译LUA固件

    前言 这节咱自己编译LUA固件 准备一台linux的机子 我把固件放到了git上,方便电脑用http下载 我先用这个连接linux 大家随意哈,只要是一台linux的机子就可以,不管是图形页面还是命令 ...

  2. selenium--上传文件

    前戏 在进行web自动化的时候,经常需要用到上传文件的功能,selenium可以使用send_keys()来上传文件,但是使用send_keys()上传文件有很大的局限性,只能上传input标签的,好 ...

  3. linux网络编程之用socket实现简单客户端和服务端的通信(基于UDP)

    单客户端和服务端的通信(基于UDP)   代码 服务端代码socket3.c #include<sys/types.h> #include<sys/socket.h> #inc ...

  4. [算法模版]AC自动机

    [算法模版]AC自动机 基础内容 板子不再赘述,OI-WIKI有详细讲解. \(query\)函数则是遍历文本串的所有位置,在文本串的每个位置都沿着\(fail\)跳到根,将沿途所有元素答案++.意义 ...

  5. c# 创建socket连接辅助类

    using AD.SocketForm.Model; using NLog; using System; using System.Net; using System.Net.Sockets; nam ...

  6. SpringBoot 应用篇之从 0 到 1 实现一个自定义 Bean 注册器

    191213-SpringBoot 应用篇之从 0 到 1 实现一个自定义 Bean 注册器 我们知道在 spring 中可以通过@Component,@Service, @Repository 装饰 ...

  7. JMeter工具学习(二)——获取登录 token

    备注: JMeter版本4.0 JDK版本1.8 1,新增线程组 2,添加http请求(如何添加Http请求查看详情) 3,添加正则表达式提取器(regular expression extracto ...

  8. CentOS下安装php 5.6.19

    # php安装包下载wget https://www.php.net/distributions/php-5.6.19.tar.bz2# 解压bunzip2 php-5.6.19.tar.bz2tar ...

  9. slf4j log4j logback

    最先大家写日志都用log4j,后来作者勇于创新,又搞了个logback,又为了统一江湖,来了个slf4j,所以目前在代码中进行日志输出,推荐使用slf4j,这样在运行时,你可以决定到底是用log4j还 ...

  10. CSS3移动端vw+rem不依赖JS实现响应式布局

    1.前言 (1)vw/vh介绍 在使用之前,我们先简单了解一下什么是vw和rem以及它们的作用,vw是css3出现的一个新单位,它是"view width"缩写,定义为把当前屏幕分 ...