前置工具安装
Docker Desktop // 靶机容器搭建
Cardinal // AWD 平台工具
Docker Desktop
Docker Desktop 相关百度网盘链接可到Track社区 bbs.zkaq.cn 获取~
安装完毕后运行如下命令检查
docker --version
docker-compose --version
Cardinal
cardinal相关百度网盘链接可到Track社区 bbs.zkaq.cn 获取~
找到你想安装的目录,解压后首先在本地运行 mysql 环境,然后在 mysql 里创建一个 cardinal 库
create database cardinal;
打开 cmd 窗口运行
cardinal.exe
然后根据提示填入内容即可
填完之后, 访问
https://127.0.0.1:19999
出现以下界面就是搭建好了
平台的管理地址如下
http://127.0.0.1:19999/manager/#/
Docker 镜像建立
这一步是为了建立我们比赛时使用的靶机镜像
首先是搭建docker容器
我们这里以搭建一个有 ssh
, mysql
, web
的靶机为例
-
1. 权限分层:root权限保留给防御方维护,user权限开放攻击面
-
2. 漏洞植入:
-
• SSH爆破漏洞(user弱口令)
-
• MySQL弱密码漏洞
-
-
1. 服务暴露:开放22/80/3306
dockerfile 如下
# 使用 ubuntu:14.04 基础镜像
FROM ubuntu:14.04
# 替换为旧版存档源(因官方源已关闭)
RUN sed -i 's/http:\/\/archive.ubuntu.com\/ubuntu\//http:\/\/mirrors.aliyun.com\/ubuntu\//g' /etc/apt/sources.list && \
sed -i '/security/d' /etc/apt/sources.list
# 安装必要工具
# openssh-server ssh服务器
# mysql-server mysql服务器
# apache2 web中间件
# libapache2-mod-php5, 用于 apache2 解析 php
# dos2unix 用于转换 Windows 换行符, 让sh脚本copy进去之后能正常用
# vim 文本编辑器
RUN apt-get update && apt-get install -y \
openssh-server mysql-server apache2 libapache2-mod-php5 dos2unix vim \
&& rm -rf /var/lib/apt/lists/*
# 配置 SSH 服务
RUN mkdir /var/run/sshd
# 配置ssh root远程登录
# 当前目录下保存一个所需配置的ssdh_config的配置文件
COPY sshd_config /etc/ssh/ssh_config
# 更改root密码, 为保证flag不被更改, root密码不公布
RUN echo "root:aB4dEFQ52874Acdd" | chpasswd
# 创建普通用户 user(密码 123456)给选手用的账户
RUN useradd -m -s /bin/bash user \
&& echo "user:123456" | chpasswd
# 将 /var/www/html 的所有权设置为 user 用户
# 让选手可以去修改web目录下的文件进行防御配置
RUN chown -R user:user /var/www/html
# 赋予 user 用户对 /var/www/html 的写入权限
RUN chmod -R 755 /var/www/html/*
# 配置 Apache, ServerName localhost 用于设置 FQDN
COPY html/ /var/www/html/
RUN apache2ctl start
# RUN chown -R www-data:www-data /var/www/html
RUN echo "ServerName localhost" >> /etc/apache2/apache2.conf
# 启动脚本(处理权限和服务启动)
COPY startup.sh /startup.sh
RUN chmod +x /startup.sh
# 使用 dos2unix 转换换行符
RUN dos2unix /startup.sh
# 配置mysql, 使其可读flag(任意)文件
# 同上面ssh配置文件
COPY my.cnf /etc/mysql/my.cnf
RUN dos2unix /etc/mysql/my.cnf
RUN dos2unix /etc/ssh/ssh_config
# 随便写个flag方便测试
RUN echo "GKD{123123123123}" > /flag
# 暴露端口
# 该靶机存在 ssh , mysql弱口令 与web漏洞,
EXPOSE22803306
# 启动时执行的命令
CMD ["bash", "/startup.sh"]
startup.sh
#!/bin/bash
# 配置 MySQL
# 修改 MySQL 配置,允许远程访问
sed -i 's/127.0.0.1/0.0.0.0/g' /etc/mysql/my.cnf
echo "innodb_use_native_aio = 0" >> /etc/mysql/my.cnf # 解决 Docker 兼容性问题
# 启动 MySQL 服务
service mysql start
# 配置 MySQL 允许空密码登录并设置密码
# 如果需要对数据库进行初始化, 比如创建库表字段等也可以在这里写
mysql -uroot <<EOF
SET PASSWORD FOR 'root'@'localhost' = PASSWORD('1234567');
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '1234567' WITH GRANT OPTION;
FLUSH PRIVILEGES;
EOF
# 修复 MySQL 文件权限
chown -R mysql:mysql /var/lib/mysql
# 启动其他服务
service apache2 start
/usr/sbin/sshd -D -f /etc/ssh/ssh_config
ping.php
以及 有一个 html 目录
html 目录中存放着你的 web 文件
这里给出一个 带有 命令执行漏洞的 ping 站点为例
<!DOCTYPE html>
<html>
<head>
<title>Ping 测试</title>
<meta charset="utf-8">
</head>
<body>
<div style="width: 600px; margin: 0 auto; margin-transform: translateY( 50px;">
<h1>Ping 测试工具</h1>
<form method="post" action="">
<label for="ip_address">请输入目标 IP 地址或域名:</label>
<input type="text" name="ip_address" id="ip_address" style="width: 300px; height:30px; margin-top:20px; padding: 5px; font-size:16px;">
<button type="submit" style="height:30px; margin-top:20px; padding: 5px 15px; font-size:16px;">Ping</button>
</form>
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// 获取用户输入
$ip = $_POST["ip_address"];
// 检查输入是否为空
if (em)pty($ip)) {
echo"<p style='color: red; margin-transform: translateY(20px;'>请输入一个有效的 IP 地址或域名!</p>";
}
else {
// 执行 ping 命令(Windows 系统下,使用 -n 指定发送 4 个数据包)
$ping_command = "ping -c 4 $ip";
// 执行命令并获取输出
$output = shell_exec($ping_command); // shell_exec 会将参数作为系统命令执行
echo"<pre style='margin-top:20px; padding: 10px; background-color: #f5f5f5; border: 1px solid #ddd;'>";
echo$output;
echo"</pre>";
}
}
?>
</div>
</body>
</html>
my.cnf
mysql 的配置文件, 这里主要配置了 mysql 最大的登录次数限制(为了给出来一个 mysql 爆破漏洞)
#
# The MySQL database server configuration file.
#
# You can copy this to one of:
# - "/etc/mysql/my.cnf" to set global options,
# - "~/.my.cnf" to set user-specific options.
#
# One can use all long options that the program supports.
# Run program with --help to get a list of available options and with
# --print-defaults to see which it would actually understand and use.
#
# For explanations see
# http://dev.mysql.com/doc/mysql/en/server-system-variables.html
# This will be passed to all mysql clients
# It has been reported that passwords should be enclosed with ticks/quotes
# escpecially if they contain "#" chars...
# Remember to edit /etc/mysql/debian.cnf when changing the socket location.
[client]
port = 3306
socket = /var/run/mysqld/mysqld.sock
# Here is entries for some specific programs
# The following values assume you have at least 32M ram
# This was formally known as [safe_mysqld]. Both versions are currently parsed.
[mysqld_safe]
socket = /var/run/mysqld/mysqld.sock
nice = 0
[mysqld]
#
# * Basic Settings
secure_file_priv=#
user = mysql
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
port = 3306
basedir = /usr
datadir = /var/lib/mysql
tmpdir = /tmp
lc-messages-dir = /usr/share/mysql
skip-external-locking
#
# Instead of skip-networking the default is now to listen only on
# localhost which is more compatible and is not less secure.
bind-address = 0.0.0.0
#
# * Fine Tuning
#
key_buffer = 16M
max_allowed_packet = 16M
thread_stack = 192K
thread_cache_size = 8
# This replaces the startup script and checks MyISAM tables if needed
# the first time they are touched
myisam-recover = BACKUP
max_connect_errors = 10000000
#max_connections = 13
#table_cache = 64
#thread_concurrency = 10
#
# * Query Cache Configuration
#
query_cache_limit = 1M
query_cache_size = 16M
#
# * Logging and Replication
#
# Both location gets rotated by the cronjob.
# Be aware that this log type is a performance killer.
# As of 5.1 you can enable the log at runtime!
#general_log_file = /var/log/mysql/mysql.log
#general_log = 1
#
# Error log - should be very few entries.
#
log_error = /var/log/mysql/error.log
#
# Here you can see queries with especially long duration
#log_slow_queries = /var/log/mysql/mysql-slow.log
#long_query_time = 2
#log-queries-not-using-indexes
#
# The following can be used as easy to replay backup logs or for replication.
# note: if you are setting up a replication slave, see README.Debian about
# other settings you may need to change.
#server-id = 1
#log_bin = /var/log/mysql/mysql-bin.log
expire_logs_days = 10
max_binlog_size = 100M
#binlog_do_db = include_database_name
#binlog_ignore_db = include_database_name
#
# * InnoDB
#
# InnoDB is enabled by default with a 10MB datafile in /var/lib/mysql/.
# Read the manual for more InnoDB related options. There are many!
#
# * Security Features
#
# Read the manual, too, if you want chroot!
# chroot = /var/lib/mysql/
#
# For generating SSL certificates I recommend the OpenSSL GUI "tinyca".
#
# ssl-ca=/etc/mysql/cacert.pem
# ssl-cert=/etc/mysql/server-cert.pem
# ssl-key=/etc/mysql/server-key.pem
[mysqldump]
quick
quote-names
max_allowed_packet = 16M
[mysql]
#no-auto-rehash # faster start of mysql but no tab completition
[isamchk]
key_buffer = 16M
#
# * IMPORTANT: Additional settings that can override those from this file!
# The files must end with '.cnf', otherwise they'll be ignored.
#
!includedir /etc/mysql/conf.d/
innodb_use_native_aio = 0
sshd_config
这里允许 root 用户远程登录
为了方便
# Package generated configuration file
# See the sshd_config(5) manpage for details
# What ports, IPs and protocols we listen for
Port 22
# Use these options to restrict which interfaces/protocols sshd will bind to
#ListenAddress ::
#ListenAddress 0.0.0.0
Protocol 2
# HostKeys for protocol version 2
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_dsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
#Privilege Separation is turned on for security
UsePrivilegeSeparation yes
# Lifetime and size of ephemeral version 1 server key
KeyRegenerationInterval 3600
ServerKeyBits 1024
# Logging
SyslogFacility AUTH
LogLevel INFO
# Authentication:
LoginGraceTime 120
PermitRootLogin yes
StrictModes yes
RSAAuthentication yes
PubkeyAuthentication yes
#AuthorizedKeysFile %h/.ssh/authorized_keys
# Don't read the user's ~/.rhosts and ~/.shosts files
IgnoreRhosts yes
# For this to work you will also need host keys in /etc/ssh_known_hosts
RhostsRSAAuthentication no
# similar for protocol version 2
HostbasedAuthentication no
# Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication
#IgnoreUserKnownHosts yes
# To enable empty passwords, change to yes (NOT RECOMMENDED)
PermitEmptyPasswords no
# Change to yes to enable challenge-response passwords (beware issues with
# some PAM modules and threads)
ChallengeResponseAuthentication no
# Change to no to disable tunnelled clear text passwords
#PasswordAuthentication yes
# Kerberos options
#KerberosAuthentication no
#KerberosGetAFSToken no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes
# GSSAPI options
#GSSAPIAuthentication no
#GSSAPICleanupCredentials yes
X11Forwarding yes
X11DisplayOffset 10
PrintMotd no
PrintLastLog yes
TCPKeepAlive yes
#UseLogin no
#MaxStartups 10:30:60
#Banner /etc/issue.net
# Allow client to pass locale environment variables
AcceptEnv LANG LC_*
Subsystem sftp /usr/lib/openssh/sftp-server
# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the ChallengeResponseAuthentication and
# PasswordAuthentication. Depending on your PAM configuration,
# PAM authentication via ChallengeResponseAuthentication may bypass
# the setting of "PermitRootLogin without-password".
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and ChallengeResponseAuthentication to 'no'.
docker-compose.yml
用于批量启动靶机
这里有 13 个, 可以根据自己的需求添加或者减少
后面会给出 py 脚本根据镜像名, 映射端口, 主机数生成 docker-compose.yml 脚本
version: '3.8'
services:
target1:
image:awd-server-1:latest
ports:
-"2200:22"
-"8000:80"
-"33060:3306"
target2:
image:awd-server-1:latest
ports:
-"2201:22"
-"8001:80"
-"33061:3306"
target3:
image:awd-server-1:latest
ports:
-"2202:22"
-"8002:80"
-"33062:3306"
target4:
image:awd-server-1:latest
ports:
-"2203:22"
-"8003:80"
-"33063:3306"
target5:
image:awd-server-1:latest
ports:
-"2204:22"
-"8004:80"
-"33064:3306"
target6:
image:awd-server-1:latest
ports:
-"2205:22"
-"8005:80"
-"33065:3306"
target7:
image:awd-server-1:latest
ports:
-"2206:22"
-"8006:80"
-"33066:3306"
target8:
image:awd-server-1:latest
ports:
-"2207:22"
-"8007:80"
-"33067:3306"
target9:
image:awd-server-1:latest
ports:
-"2208:22"
-"8008:80"
-"33068:3306"
target10:
image:awd-server-1:latest
ports:
-"2209:22"
-"8009:80"
-"33069:3306"
target11:
image:awd-server-1:latest
ports:
-"2210:22"
-"8010:80"
-"33070:3306"
target12:
image:awd-server-1:latest
ports:
-"2211:22"
-"8011:80"
-"33071:3306"
target13:
image:awd-server-1:latest
ports:
-"2212:22"
-"8012:80"
- "33072:3306"
docker-compose.yml 生成脚本
import yaml
import re
defgenerate_docker_compose(num_targets, image_name, ports):
defquoted_port_representer(dumper, data):
"""自定义YAML字符串表示器,为端口格式添加双引号"""
if re.match(r'^\d+:\d+$', data):
return dumper.represent_scalar('tag:yaml.org,2002:str', data, style='"')
return dumper.represent_str(data)
# 注册自定义表示器
yaml.add_representer(str, quoted_port_representer)
"""生成Docker Compose数据结构"""
return {
'version': '3.8',
'services': {
f"target{i+1}": {
'image': image_name,
'ports': [
f"{j* 100 + i}:{j}" # SSH端口
for j in ports ]
} for i inrange(num_targets)
}
}
if __name__ == '__main__':
# 用户输入 修改下面三个变量即可
num_targets = 13
image_name = "awd-server-1:latest"
open_port = [22, 80, 3306]
# 生成数据并写入文件
withopen('docker-compose.yml', 'w') as f:
yaml.dump(
generate_docker_compose(num_targets, image_name, open_port),
f,
default_flow_style=False, # 禁用流式格式
sort_keys=False, # 保持键的顺序
indent=2, # 设置缩进
width=1000 # 避免自动换行
)
print("docker-compose.yml 文件已生成!")
目录结构
此时, 目录结构应该如下
然后打开 CMD 窗口
拉取 ubuntu:14.04 镜像
首先把我们要用到的 ubuntu:14.04 的镜像拉取到本地
如果可以科学上网, 直接拉取即可
不行的话参考这篇文章换源Docker Desktop国内镜像源
docker pull ubuntu:14.04
构建靶机镜像
awd-server-1 是镜像名称
latest 的位置需要填入的是版本号, 默认是 latest, 也可以改成 1.0, 2.0, 2.1 这样的
每次的 latest 会覆盖上一次的 latest, 如果想要保留以前版本, 就用数字做版本号不要一直默认
最后的点是路径, 指当前目录
运行
docker build -t awd-server-1:latest .
如果出现以下报错, 是因为你的 docker-Desktop 没有启动
运行结果如下
构建成功后, 正常流程
启动容器测试
先起一个容器, 测测功能都对不对
下面的 target1 是起来的容器名, -p 是端口映射, 将容器的 22 端口映射到本机的 2222 端口上
访问 127.0.0.1:2222 就是在访问容器的 22 端口
内网中, 访问本机 ip:2222 端口即可访问到容器的 22 端口
docker run -d -p 81:80 -p 2222:22 -p 30006:3306 --name target1 awd-server-1:latest
部署好之后我们可以在docker-desktop
中看到部署好的容器
然后按照我们刚刚映射的端口逐一对漏洞进行测试
测试无误后
将测试容器删除
然后就可以利用 docker-compose.yml 批量启动了
使用 docker-compose.yml 批量启动靶机
docker-compose up -d
平台部署
首先登录后台
添加队伍
这里如果不显示添加队伍按钮, 调整一下浏览器的缩放比例即可
一个一个手动添加太累, 这里给出一个 python 脚本
token 在账号管理处获取
# coding=utf-8
import json
import requests
defadd_team(team_num):
team_name = [str(i) for i inrange(1, team_num + 1)] # 用1-13命名
# team_name = [input(f"队名{_}:") for _ in range(1, team_num)] # 手动input命名 如果要手动命名队伍名就取消这里的注释, 把上面那句注释掉
token = "your-token"
url = "http://127.0.0.1:19999/api/manager/teams"
headers = {"Authorization" : token}
json_data = [
{"Name" : name,
"Login": ''} for name in team_name
]
res = requests.post(url, json=json_data, headers=headers)
reponse = json.loads(res.content.decode())
if reponse['msg'] == "Duplicated Team Found!":
print("有已经存在的用户名")
exit()
user_pass = reponse['data']
for i in user_pass:
print(i)
if __name__ == '__main__':
team_num = 3# 添加队伍的数量
add_team(team_num)
生成题目
然后生成题目, 比如我这里叫 Server1, 记得勾选自动更新 flag
添加靶机
本环节需将Docker容器实例配置至系统
但在多人协同或大规模部署场景下手工逐个配置效率较低。
为此这里提供一个自动化解决方案:通过 Python 预置脚本自动生成符合规范的批量JSON配置模板。
import copy
import json
# lis是第一个样例, 后面会根据lis生成其他的
lis = [{ "ChallengeID": 1, "TeamID": 1, "IP": "192.168.2.113", "Port": "2200,8000,33060", "SSHPort": "2200", "SSHUser": "root", "SSHPassword": "aB4dEFQ52874Acdd", "Description": "ssh,web,mysql" },]
for i inrange(2,8):# 这里是8, 那最后就是7个靶机,
a = copy.copy(lis[0])
# a['ChallengeID'] = i
a['TeamID'] = i
a['SSHPort'] = str(int(a['SSHPort'] ) + i -1)
s = a['Port']
s = list(map(int,s.split(',')))
# 像是如果端口数量有变化, 就照着多加几行 s[3], s[4], 或者删除几行
s[0] += i-1
s[1] += i-1#这里取出来port中的第二个
s[2] += i-1# 第三个
a['Port'] = str(s).strip('[').strip(']')
lis.append(a)
print(json.dumps(lis))
生成的 json 字符串如下
[
{
"ChallengeID": 1,
"TeamID": 1,
"IP": "192.168.2.113",
"Port": "2200,8000,33060",
"SSHPort": "2200",
"SSHUser": "root",
"SSHPassword": "aB4dEFQ52874Acdd",
"Description": "ssh,web,mysql"
},
{
"ChallengeID": 1,
"TeamID": 2,
"IP": "192.168.2.113",
"Port": "2201, 8001, 33061",
"SSHPort": "2201",
"SSHUser": "root",
"SSHPassword": "aB4dEFQ52874Acdd",
"Description": "ssh,web,mysql"
},
{"ChallengeID": 1,
"TeamID": 3,
"IP": "192.168.2.113",
"Port": "2202, 8002, 33062",
"SSHPort": "2202", "SSHUser": "root",
"SSHPassword": "aB4dEFQ52874Acdd",
"Description": "ssh,web,mysql"
}
点击批量添加 ,将字符串复制进去即可
注意: 如果一直跟着我上面操作, 到这一步会报错提示队伍不存在, 因为队伍那里我生成了三个, 用脚本生成时靶机这里导入的是 7 个, 数量对不上, 但如果你是直接复制的上例的 json 字符串就不会存在这个问题
添加完成之后如下
点击测试 ssh 链接
测试成功即可
到了这里, 最重要的几个步骤就完成了
队伍有了, 题目有了, 靶机有了
接下来介绍一下其他的一些选项
check 服务
用来检查目标靶机的服务是否宕机
宕机的话会扣掉宕机分数
创建 check 账号
然后用 python 脚本构建 check 逻辑
这里给出 ping 网页的 check 逻辑
ping 网页按理来说, 要能够 ping ip ping 域名
但是为了方便我就写了个 ping ip
记得填写上自己的 check 账号的 token
import requests
import time
# Check 判断逻辑
'''
注意, 我这里的team_id实际上是端口号
像是队伍1的端口是8000
所以要找到team_1,就要让team_id加1
'''
defping_check(team_id):
port = 8000 + team_id
data = {"ip_address" : "127.0.0.1"} # post数据
res = requests.post(f"http://localhost:{port}/ping.php", data)
if"icmp_seq=1"in res.content.decode():
print(f"{team_id} ping Success")
else:
check_down(team_id)
print(f"{team_id} ping down!!!")
defcheck_down(team_id):
GameBoxID = team_id + 1
# 发送 CheckDown 信息到平台
TOKEN = 'you-check-token'# Check Token
# TOKEN = 1
resp = requests.post('http://localhost:19999/api/manager/checkDown',
json={'GameBoxID': GameBoxID},
headers={'Authorization': TOKEN}).json()
if resp['error'] != 0:
print(resp['msg'])
while1:
for i inrange(8):
try:
print(f"Team {i}")
ping_check(i)
print("--------")
except:
check_down(i) # 如果报错就是压根请求不到, 直接check扣分
print("---------------------------")
time.sleep(180) # 每三分钟检查一次
比赛开始后运行开脚本就可以
修改 flag 格式
在配置管理这里可以修改比赛名称和 flag 格式
记得勾选队伍靶机相互可见
赛后重置
不知道是不是我环境的原因
不管是这里的刷新队伍状态
还是这里的重置靶机分数, 都没作用
这里给出一个解决方案
每次比赛结束后
删除数据库
然后重新创建
docker 容器组删除
删除后再启动一次 docker-compose.yml 启动容器组
打开平台配置文件, 修改开始和结束时间即可
但每次这样手动太麻烦了, 还是创建几个 python 脚本来辅助运行
1 数据库重置
先把平台运行停了
把账号密码改成自己的数据库账号密码
import mysql.connector
from mysql.connector import Error
defdatabase_operations():
try:
# 建立管理员连接(无需指定数据库)
connection = mysql.connector.connect(
host='localhost',
user='root',
password='your_password'
)
cursor = connection.cursor()
# 配置参数
db_name = "cardinal"
# 删除数据库(如果存在)
cursor.execute(f"DROP DATABASE IF EXISTS {db_name}")
print(f"数据库 {db_name} 已删除")
# 创建新数据库
cursor.execute(f"CREATE DATABASE {db_name} CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci")
print(f"数据库 {db_name} 已创建")
except Error as e:
print(f"数据库操作失败: {e}")
finally:
if connection.is_connected():
cursor.close()
connection.close()
if __name__ == "__main__":
database_operations()
2 比赛时间重置
# coding=utf-8
import toml
# 配置文件的相对路径是 conf\\Cardinal.toml 这里改成你配置文件的绝对路径, 用 \ 表示路径时要注意转义, 用\\
config_path = "前置路径\\conf\\Cardinal.toml"
config = toml.load(config_path)
print("时间样例: 2022-03-03T08:00:00")
config['base']['BeginTime'] = input("请输入开始时间: ") + "+08:00"
config['base']['EndTime'] = input("请输入结束时间: ") + "+08:00"
with open(config_path, 'w') as file:
toml.dump(config, file)
3 队伍添加
到这一步就把平台开起来
记得改队伍数和 token, 这里一定要用 cmd 运行,或者 pycharm 运行, 因为需要保存每个账号的密码
记得改 token
# coding=utf-8
import json
import requests
defadd_team(team_num):
team_name = [str(i) for i inrange(1, team_num + 1)] # 用1-13命名
# team_name = [input(f"队名{_}:") for _ in range(1, team_num)] # 手动input命名
token = "you-token"
url = "http://127.0.0.1:19999/api/manager/teams"
headers = {"Authorization" : token}
json_data = [
{"Name" : name,
"Login": ''} for name in team_name
]
res = requests.post(url, json=json_data, headers=headers)
reponse = json.loads(res.content.decode())
if reponse['msg'] == "Duplicated Team Found!":
print("有已经存在的用户名")
exit()
user_pass = reponse['data']
for i in user_pass:
print(i)
if __name__ == '__main__':
team_num = 3
add_team(team_num)
4 题目添加
题目添加不是很麻烦
手动加就行了
5 靶机导入
这里如果用以前的靶机, 直接在那个目录运行, 把容器起来就行
docker-compose up -d
新靶机的话就用上面的 docker-compose.yml 生成脚本生成后再起
然后运行靶机批量导入脚本生成 json 字符串到平台导入
这里记得改 ssh 的 root 链接密码 和你的 内网 IP, 端口和描述看需求更改
这里用 2,14 生成 13 个靶机作为示例, 因为上面是生成了 13 个队伍
# coding=utf-8
import copy
import json
lis = [{ "ChallengeID": 1, "TeamID": 1, "IP": "你的内网Ip", "Port": "2200,8000,33060", "SSHPort": "2200", "SSHUser": "root", "SSHPassword": "aB4dEFQ52874Acdd", "Description": "ssh,web,mysql" },]
for i inrange(2,14): # 2,8 是需要导入7个靶机的场景,
a = copy.copy(lis[0])
# a['ChallengeID'] = i
a['TeamID'] = i
a['SSHPort'] = str(int(a['SSHPort'] ) + i -1)
s = a['Port']
s = list(map(int,s.split(',')))
s[0] += i-1
s[1] += i-1
s[2] += i-1
a['Port'] = str(s).strip('[').strip(']')
lis.append(a)
print(json.dumps(lis))
导入后测试 ssh 链接
测试成功后就是看改比赛名和 flag 格式这两个
根据需求判断是否需要勾选靶机互相可见
随后等待比赛开始即可
文章总结
本文系统阐述了基于 Docker容器化技术 在Windows环境下搭建AWD攻防平台的完整技术方案
覆盖环境搭建→漏洞集成→批量部署→平台运维全流程。
致谢与资源
-
• 感谢Cardinal开源项目提供核心平台支持。
-
• 本文代码仓库与工具包已开源 [https://github.com/Junt184/Cardinal-Replace],欢迎社区协作优化。