From 73d1ec73176b492731db1ffddfc3378e869241b4 Mon Sep 17 00:00:00 2001 From: clxhzg <2285278532@qq.com> Date: Mon, 1 Dec 2025 17:21:55 +0800 Subject: [PATCH] commit --- .gitea/workflows/docker.yml | 34 ++++++++++++++++++++++ Dockerfile | 55 +++++++++++++++++++++++++++++++++++ README.md | 32 ++++++++++++++++++++ config/ctf.xinetd | 21 +++++++++++++ docker/docker-compose.yml | 11 +++++++ service/docker-entrypoint.sh | 30 +++++++++++++++++++ src/pwn | Bin 0 -> 12864 bytes src/pwn.c | 16 ++++++++++ 8 files changed, 199 insertions(+) create mode 100644 .gitea/workflows/docker.yml create mode 100644 Dockerfile create mode 100644 README.md create mode 100644 config/ctf.xinetd create mode 100644 docker/docker-compose.yml create mode 100644 service/docker-entrypoint.sh create mode 100644 src/pwn create mode 100644 src/pwn.c diff --git a/.gitea/workflows/docker.yml b/.gitea/workflows/docker.yml new file mode 100644 index 0000000..8c9be1c --- /dev/null +++ b/.gitea/workflows/docker.yml @@ -0,0 +1,34 @@ +name: Build to Gitea Registry + +on: [push] + +jobs: + build-push: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + # 登录到 Gitea 内置仓库 + - name: Login to Gitea Registry + uses: docker/login-action@v3 + with: + registry: ${{ vars.REGISTRY_ADDR }} # 要上传的仓库地址: gitea.guetsec.cn + username: ${{ secrets.REGISTRY_USERNAME }} # Gitea 用户名 + password: ${{ secrets.REGISTRY_TOKEN }} # Gitea 有package读写权限的访问令牌 + + # 设置动态标签 + - name: Set image tags + id: tags + run: | + SHORT_SHA=$(echo ${GITEA_SHA} | cut -c1-8) + echo "tags=${{ vars.REGISTRY_ADDR }}/${{ gitea.repository }}:${SHORT_SHA}" >> $GITHUB_OUTPUT + echo "tags=${{ vars.REGISTRY_ADDR }}/${{ gitea.repository }}:latest" >> $GITHUB_OUTPUT + + # 构建并推送 + - name: Build and push + uses: docker/build-push-action@v5 + with: + context: . + push: true + tags: ${{ steps.tags.outputs.tags }} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..02151c4 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,55 @@ +FROM ubuntu:22.04 + +# 制作者信息 +LABEL auther_template="CTF-Archives" + +# apt更换镜像源,并安装相关依赖 +RUN sed -i 's@//.*archive.ubuntu.com@//mirrors.ustc.edu.cn@g' /etc/apt/sources.list && \ + sed -i 's@//.*security.ubuntu.com@//mirrors.ustc.edu.cn@g' /etc/apt/sources.list +RUN apt-get update && apt-get -y dist-upgrade && \ + apt-get install -y lib32z1 xinetd + +# 新建用户,并进行账户改变 +RUN useradd -m ctf +WORKDIR /home/ctf + +# 复制相关lib,并处理环境 +RUN cp -R /usr/lib* /home/ctf + +# 配置特殊管道映射 +RUN mkdir /home/ctf/dev && \ + mknod /home/ctf/dev/null c 1 3 && \ + mknod /home/ctf/dev/zero c 1 5 && \ + mknod /home/ctf/dev/random c 1 8 && \ + mknod /home/ctf/dev/urandom c 1 9 && \ + chmod 666 /home/ctf/dev/* + +# 设置xinetd启动之后,chroot限制能使用的bin程序 +RUN mkdir /home/ctf/bin && \ + cp /bin/sh /home/ctf/bin && \ + cp /bin/ls /home/ctf/bin && \ + cp /bin/cat /home/ctf/bin && \ + cp /usr/bin/timeout /home/ctf/bin + +# 部署xinetd服务 +COPY ./config/ctf.xinetd /etc/xinetd.d/ctf +RUN echo "Blocked by ctf_xinetd" > /etc/banner_fail + +# 复制容器启动脚本 +COPY ./service/docker-entrypoint.sh / +RUN chmod +x /docker-entrypoint.sh + +# 部署程序 +COPY ./src/pwn /home/ctf/pwn + +# 初始化flag +RUN chown -R root:ctf /home/ctf && \ + chmod -R 750 /home/ctf && \ + touch /home/ctf/flag && \ + chmod 744 /home/ctf/flag + +# [可选]指定对外暴露端口,对于GZCTF等平台,强制EXPOSE可能会造成非预期端口泄露,请酌情启用 +# EXPOSE 9999 + +# 指定容器入口点 +ENTRYPOINT ["/bin/bash","/docker-entrypoint.sh"] diff --git a/README.md b/README.md new file mode 100644 index 0000000..8f3249a --- /dev/null +++ b/README.md @@ -0,0 +1,32 @@ +# pwn-ubuntu_22.04 + +## 环境说明 + +提供 `Ubuntu 22.04 GLIBC 2.35` 的基础环境,并已经添加 `lib32z1` + `xinetd` 软件包,并基于 `xinetd` 实现服务转发,默认暴露端口位于9999 + +实现:当选手连接到对应端口(默认为9999端口,默认选手使用 `netcat` )的时候,运行 `程序文件`,并将会话转发至选手的连接 + +镜像做到: +- 选手通过端口连接到容器/靶机 +- xinted服务检测到连接,启动一个 `chroot` 会话 +- `chroot` 通过参数 `--userspec=1000:1000 /home/ctf` 限制了程序运行时的账户权限,并更改了程序运行时的root根目录环境位置为 `/home/ctf` ,然后在限制环境中启动程序 +- `xinted` 将程序会话转发给选手的连接 + +## 如何使用 + +将程序文件放入 `./src` 目录即可,文件名请修改为 `attachment` 作为文件名,便于镜像定位程序位置 + +如果需要更改为自己的文件名,需要在 `./config/ctf.xinetd`、`./Dockerfile` 和 `./service/docker-entrypoint.sh` 中进行修改 + +程序放置进 `./src` 目录之后,执行 +```shell +docker build . +``` +即可开始编译镜像 + +也可以在安放好程序文件之后,直接使用 `./docker/docker-compose.yml` 内的 `docker-compose` 文件实现一键启动测试容器 + +```shell +cd ./docker +docker-compose up -d +``` \ No newline at end of file diff --git a/config/ctf.xinetd b/config/ctf.xinetd new file mode 100644 index 0000000..83fae83 --- /dev/null +++ b/config/ctf.xinetd @@ -0,0 +1,21 @@ +service ctf +{ + disable = no + socket_type = stream + protocol = tcp + wait = no + user = root + type = UNLISTED + port = 9999 + bind = 0.0.0.0 + # 设置xinetd连接启动后的服务程序 + server = /usr/sbin/chroot + # 设置chroot的相关参数 + server_args = --userspec=1000:1000 /home/ctf ./pwn + banner_fail = /etc/banner_fail + # safety options + per_source = 10 # the maximum instances of this service per source IP address + rlimit_cpu = 20 # the maximum number of CPU seconds that the service may use + #rlimit_as = 1024M # the Address Space resource limit for the service + #access_times = 2:00-9:00 12:00-24:00 +} diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml new file mode 100644 index 0000000..a19ef47 --- /dev/null +++ b/docker/docker-compose.yml @@ -0,0 +1,11 @@ +version: '3' +services: + test: + build: ../ + environment: + # 仅为测试用flag + FLAG: "flag{a63b4d37-7681-4850-b6a7-0d7109febb19}" + ports: + # 设置了暴露端口 + - 9999:9999 + restart: unless-stopped diff --git a/service/docker-entrypoint.sh b/service/docker-entrypoint.sh new file mode 100644 index 0000000..cc90f90 --- /dev/null +++ b/service/docker-entrypoint.sh @@ -0,0 +1,30 @@ +#!/bin/sh + +# Get the user +user=$(ls /home) + +# Check the environment variables for the flag and assign to INSERT_FLAG +if [ "$DASFLAG" ]; then + INSERT_FLAG="$DASFLAG" + export DASFLAG=no_FLAG + DASFLAG=no_FLAG +elif [ "$FLAG" ]; then + INSERT_FLAG="$FLAG" + export FLAG=no_FLAG + FLAG=no_FLAG +elif [ "$GZCTF_FLAG" ]; then + INSERT_FLAG="$GZCTF_FLAG" + export GZCTF_FLAG=no_FLAG + GZCTF_FLAG=no_FLAG +else + INSERT_FLAG="flag{TEST_Dynamic_FLAG}" +fi + +# 将FLAG写入文件 请根据需要修改 +echo $INSERT_FLAG | tee /home/$user/flag + +# 赋予程序运行权限 +chmod 711 /home/ctf/pwn + +/etc/init.d/xinetd start; +sleep infinity; diff --git a/src/pwn b/src/pwn new file mode 100644 index 0000000000000000000000000000000000000000..938f74c91c17805561bcc03f5b2c455c1d8f47a9 GIT binary patch literal 12864 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 literal 0 HcmV?d00001 diff --git a/src/pwn.c b/src/pwn.c new file mode 100644 index 0000000..0417395 --- /dev/null +++ b/src/pwn.c @@ -0,0 +1,16 @@ +#include + +void init() +{ + setvbuf(stdout, 0LL, 2, 0LL); + setvbuf(stdin, 0LL, 2, 0LL); + setvbuf(stderr, 0LL, 2, 0LL); +} +int main() { + + init(); + printf("give you the shell, give me the flag\n"); + system("/bin/sh"); + + return 0; +} \ No newline at end of file