平台的搭建
记得用桥接模式
在ubuntu上创建'GZCTF'文件夹,包含这些文件
这个ip地址貌似不能直接ifconfig得到,我忘记是怎么找到的了,如果你们搭建过程中报错可以问问ai原因
appsettings.json
{"AllowedHosts": "*","ConnectionStrings": {"Database": "Host=db:5432;Database=gzctf;Username=postgres;Password=Admin123"},"EmailConfig": {"SendMailAddress": "a@a.com","UserName": "","Password": "","Smtp": {"Host": "localhost","Port": 587}},"XorKey": "Admin123","ContainerProvider": {"Type": "Docker", "PortMappingType": "Default", "EnableTrafficCapture": false,"PublicEntry": "你的ip","DockerConfig": {"SwarmMode": false,"Uri": "unix:///var/run/docker.sock"}},"RequestLogging": false,"DisableRateLimit": true,"RegistryConfig": {"UserName": "","Password": "","ServerAddress": ""},"CaptchaConfig": {"Provider": "None", "SiteKey": "<Your SITE_KEY>","SecretKey": "admin","GoogleRecaptcha": {"VerifyAPIAddress": "https://www.recaptcha.net/recaptcha/api/siteverify","RecaptchaThreshold": "0.5"}},"ForwardedOptions": {"ForwardedHeaders": 5,"ForwardLimit": 1,"TrustedNetworks": ["你的ip/8"]}
}
docker-compose.yml
version: "3.0"
services:gzctf:image: gztime/gzctf:latestrestart: alwaysenvironment:- "LANG=zh_CN.UTF-8" - "GZCTF_ADMIN_PASSWORD=Admin123"ports:- "80:8080"volumes:- "./data/files:/app/files"- "./appsettings.json:/app/appsettings.json:ro"- "/var/run/docker.sock:/var/run/docker.sock" depends_on:- dbdb:image: postgres:alpinerestart: alwaysenvironment:- "POSTGRES_PASSWORD=Admin123"volumes:- "./data/db:/var/lib/postgresql/data"
在GZCTF文件夹下运行
docker-compose up -d
系统会在GZCTF文件夹里生成data文件夹
在win上输入你在json里写的ip,就可以进入平台
创建镜像
动态flag
docker-compose.yml
version: '3'
services:chal:build: .environment:FLAG: "flag{test_dummy}"ports:- "9999:9999"restart: unless-stopped
Dockerfile
FROM python:3.10.12-slim-bullseye# apt源换USTC
RUN sed -i 's/deb.debian.org/mirrors.ustc.edu.cn/g' /etc/apt/sources.list && \sed -i 's/security.debian.org/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
RUN apt-get update && apt-get install -y socat# 安装python依赖
RUN pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pycryptodome sympy# 创建用户
RUN useradd -m ctf
WORKDIR /home/ctf# 拷贝文件
COPY ./src/server.py /home/ctf/server.py
COPY ./service/docker-entrypoint.sh /docker-entrypoint.sh
RUN chmod +x /docker-entrypoint.sh# 入口
ENTRYPOINT ["/bin/sh","/docker-entrypoint.sh"]
service/docker-entrypoint.sh
#!/bin/sh# 获取flag优先级
if [ "$GZCTF_FLAG" ]; thenINSERT_FLAG="$GZCTF_FLAG"export GZCTF_FLAG=no_FLAG
elif [ "$FLAG" ]; thenINSERT_FLAG="$FLAG"
elseINSERT_FLAG="flag{TEST_Dynamic_FLAG}"
fi# 写入 /flag
echo $INSERT_FLAG > /flag
chmod 600 /flag# socat启动python
# 监听9999端口
socat -s TCP-LISTEN:9999,reuseaddr,fork EXEC:"python3 -u /home/ctf/server.py"
src/server.py
#!/usr/bin/env python3
from Crypto.Util.number import *
from random import getrandbits
import sympy, os, sys# 从文件读取 flag
def get_flag():try:with open("/flag","rb") as f:return f.read().strip()except:return b"GZCTF_FLAG_NOT_SET"FLAG = get_flag()
flag1 = FLAG[:len(FLAG)//2]
flag2 = FLAG[len(FLAG)//2:]# 彩色 Banner(只展示一次)
print('''
\033[91m ____ __ _ ____ __ ___ __ __ ________ ______ ______
\033[92m / __ \ / / / | / / / / / |__ \ // / / / ____/ |/ / | / ____/
\033[93m / / / / / / / |/ / / / / __/ ///_/ / / / __/ /|_/ / /| | / __/
\033[93m / /_/ / / /___/ /| / /_/ / / __/ / / / /_/ / / / / ___ |/ /___
\033[94m \___\_\/_____/_/ |_/\____/ /____/ /_/ \____/_/ /_/_/ |_/_____/
\033[0m
''')class V_cha:def __init__(self):self.P1 = getPrime(1036)self.P2 = sympy.nextprime(self.P1)assert self.P2 - self.P1 < 1000self.Q1 = getPrime(512)self.Q2 = sympy.nextprime(self.Q1)self.e1 = getPrime(1024)self.e2 = sympy.nextprime(self.e1)self.N1 = self.P1 * self.P1 * self.Q1self.N2 = self.P2 * self.P2 * self.Q2def enc(self):return self.N1, self.N2, self.e1, self.e2def encrypt_flag(self):m1 = bytes_to_long(flag1)m2 = bytes_to_long(flag2)c1 = pow(m1, self.e1, self.N1)c2 = pow(m2, self.e2, self.N2)return c1, c2def keykey():x1 = getrandbits(32)x2 = getrandbits(32)print("solve this: ", x1, "+", x2, "=?")sys.stdout.flush()try:result = int(sys.stdin.readline())except:exit(0)if result != x1 + x2:print("wrong!")exit(0)else:print("ok!")def main():print("welcome to V_Challenge")A = V_cha()coin = 5while coin > 0:print("1) verify")print("2) get ciphertext")print("3) get N & e")print("4) exit")sys.stdout.flush()choose = sys.stdin.readline().strip()if choose == "1":keykey()coin -= 1elif choose == "2":c1, c2 = A.encrypt_flag()print(f"c1 = {c1}\nc2 = {c2}")coin -= 1elif choose == "3":N1, N2, e1, e2 = A.enc()print(f"N1 = {N1}\nN2 = {N2}\ne1 = {e1}\ne2 = {e2}")coin -= 1elif choose == "4":print("bye~")# 线上比赛可以选择不输出flag,或输出完整flagtry:print(FLAG.decode())except:print(str(FLAG))breakelse:print("wrong input")sys.stdout.flush()print("奥利给!!!!!")if __name__ == "__main__":main()
在V_cha文件夹下,也就是dockerfile文件所在地址运行命令
docker build -t v_challenge .
docker run -it --rm -p 9999:9999 \-e GZCTF_FLAG="flag{TEST_DYNAMIC_LOCAL}" \v_challenge
#这个命令的好处就是暂定flag,nc检查完后直接ctrl+c就可以关闭容器了,不用一个一个删掉测试容器
然后把镜像的名字复制到题目管理下的镜像下就可以了
ps:最好让ai帮你写,不累
有什么问题多问gpt,把报错发给它,一点一点试
保证你的题目docker正确,如果不确定,最好先用已经成功了的题目docker试试,心里有个底
这里还有模版
https://github.com/CTF-Archives/ctf-docker-template