对于第一次pwn的出题小记

个人第一次的出题记录

前言:本篇文章将讲述出题的全过程,从编写题目,到环境搭建以及搭建过程中我遇到的一些问题,现在让我们开始吧。

出题

编写题目

首先,让我们打开虚拟机,来进行源代码的编写,编写完的题目奉上:

#include <stdio.h>
#include <stdlib.h> 
#include <unistd.h>  
void backdoor()
{
    system("/bin/sh");
}

void vulnerable_function() 
{
    char buf[0x10];
    read(0,buf,0x100);
}

int main() 
{
    printf("Welcome to pwn world!\n");
    printf("try to resolve pwn's hello world,the most easy ret2text challenge!\n");
    vulnerable_function();
    return 0;
}

一道最简单的ret2text

编译题目

使用gcc对源代码进行编译

gcc -no-pie -fno-stack-protector -z execstack -o ret2text ret2text.c

这个命令规定了使用gcc编译,并关闭了PIE,栈保护,并允许栈可执行,同时将·ret2text.c文件编译成了ret2text文件,那么题目编写就告一段落。接下来进行环境的配置

docker 搭建

docker 的介绍:

Docker实际上是将文件和其依赖进行打包为一个文件,当运行时就会生成一个容器环境,程序在此处运行,如同真实的物理机

docker的安装:

sudo apt-get update
sudo apt-get install docker.io #安装docker
docker version #检查是否安装成功

常用docker指令

docker info     #docker基本信息
docker images   #docker镜像信息
docker build    #构建
docker run      #运行
docker stop     #停止
docker kill     #强制停止
docker rm       #删除容器

dockerfile 介绍

Dockerfile 是用来构建镜像的文本文件,包含了一条条构建镜像所需的指令和说明。 其中有1.FROM:(开篇第一个非注释行),后续的指令运行于此基准镜像所提供的运行环境。 2.COPY:用于从 Docker主机复制文件 3.RUN:用于指定 docker build过程中运行的程序 4.CMD:为启动的容器指定默认要运行的程序,运行结束后容器终止

把我的相关设置奉上
FROM ubuntu:22.04
# 设置时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 更换为清华源(按需更改)
RUN sed -i 's@http://archive.ubuntu.com/@http://mirrors.tuna.tsinghua.edu.cn/@g' /etc/apt/sources.list && \
    sed -i 's@http://security.ubuntu.com/@http://mirrors.tuna.tsinghua.edu.cn/@g' /etc/apt/sources.list   
# 更新并安装必要软件
RUN apt-get update && \
    apt-get install -y xinetd && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
# 创建CTF用户
RUN useradd -m ctf
# 设置工作目录
WORKDIR /home/ctf
# 复制必要的文件
COPY ./ctf.xinetd /etc/xinetd.d/ctf
COPY ./bin/ret2text /home/ctf/
# 重要:将flag复制到根目录
COPY ./bin/flag /
# 重要:设置正确的权限
RUN chown -R ctf:ctf /home/ctf && \
    chmod 755 /home/ctf && \
    chmod 750 /home/ctf/ret2text && \
    chmod 444 /flag && \          # 根目录的flag设置为所有用户可读
    chmod 440 /etc/xinetd.d/ctf
# 暴露端口
EXPOSE 9999
# 启动命令
CMD ["/usr/sbin/xinetd", "-dontfork"]

配置docker国内镜像源

sudo nano /etc/docker/daemon.json
{
  "registry-mirrors": [
    "https://docker.m.daocloud.io",
    "https://docker.imgdb.de",
    "https://docker-0.unsee.tech",
    "https://docker.hlmirror.com"
  ]
}

之后执行

sudo systemctl daemon-reload
sudo systemctl restart docker

运行以下命令,查看配置的镜像源是否已成功列出:

docker info | grep -A 1 "Registry Mirrors"

如果是清华源,则修改start.sh

#!/bin/bash
# 设置环境变量
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# 启动xinetd服务
service xinetd start
# 保持容器运行
sleep infinity

安装docker-compose:

sudo apt install docker-compose

ctf_xinetd:

# 下载项目
git clone https://github.com/Eadom/ctf_xinetd
# 把flag和二进制程序放入bin目录中,并且按照readme修改ctf.xinetd
docker build -t "pwn" . #注意最后有点
docker run -d -p "0.0.0.0:pub_port:9999" -h "pwn" --name="pwn" pwn
# -d 让容器在后台运行
# -p 设置端口映射规则 宿主ip:宿主机端口:容器端口
# -h 容器内部看到的主机名字
# --name="pwn"为容器创立一个名称,不设置系统会随机起
# 最后一个pwn是镜像名称
# 可以将pub_port更改

ctf.xinetd 配置文件

service ctf
{
    disable = no
    socket_type = stream
    protocol    = tcp
    wait        = no
    user        = ctf
    type        = UNLISTED
    port        = 9999
    bind        = 0.0.0.0
    # 直接运行程序,不使用stdbuf
    server      = /home/ctf/ret2text
    # 安全限制
    rlimit_cpu  = 20
    per_source  = 10
    instances   = 20
    # 设置工作目录
    server_args = /home/ctf/
}

着手运行我们的docker

开始之前,我们需要先解决Docker权限问题 当时主播这里出现了问题 所以我们需要将当前用户添加到docker组:

sudo usermod -aG docker $USER

接下来reboot重启系统 重新运行后执行

docker info | grep -A 1 "Registry Mirrors"

准备就绪,可以开始部署了

注意注意,一定要!!!!回到ctf_xinetd文件夹中去执行以下命令,当时主播这里也出现了问题

docker build -t pwn-tuna . #构建镜像
docker run -d -p "0.0.0.0:8090:9999" --name="pwn-challenge" pwn-tuna #运行容器
docker ps #检查容器状态

一切完成后,测试连接

nc localhost 8090
#或
nc 127.0.0.1 8090

............小记到此结束 ..................主播水平有限,如有错误,敬请谅解