pwn出题小记
pwn出题小记
参考文章:
web和pwn题的简单动态flag实现_gzctf-CSDN博客
所使用的工具:docker、CTF-Xined
pwn题编译
1 | gcc -o pwn pwn.c |
保护
1 | NX:-z execstack / -z noexecstack (关闭 / 开启) 不让执行栈上的数据,于是JMP ESP就不能用了 |
docker的准备
因为虚拟机换源后仍然无法pull ubuntu22.04镜像,所以选择在主机上配置,主机上我是配了Linux系统的
docker换源
准备的是阿里云的加速源,这里每个人的源都不同,需要自行去阿里云官网查询:

打开docker设置

将刚获取到的源放入
1 | "registry-mirrors": [ |
点击apply应用
使用docker info查看是否换源成功,成功的话能看到刚刚换源上去的地址
正式出题
先开启主机上的Linux终端,在终端中输入wsl开启ubuntu环境方便我们测试容器可行性
接下来下载CTF-Xined
1 | git clone https://github.com/Eadom/ctf_xinetd.git |
扒下来后有这样几个文件

docker-compose.yml是我自己加的
其中bin文件夹放编译好的pwn文件和flag文件
我们主要修改ctf.xinetd、dockerfil、start.sh和bin目录下的flag
ctf.xinetd
1 | service ctf |
这里的端口指定了9999,平台上题目的端口也要是9999,不然不能正常连接环境
该文件修改了./onechance改为了pwn因为在bin目录下我的题目源文件叫pwn
dockerfile
1 | FROM ubuntu:22.04 |
注意修改ubuntu版本号,这段是支持32位程序的,目前还没考虑指定libc的情况
1 | FROM ubuntu:22.04 |
这段是64位程序的
dockerfile可以理解为是用来构建镜像的,目前的问题是容器的地址随机化关不掉,还得再研究
chroot只支持ls、cat、 cd三个操作,该dockerfile主要进行的操作就是将bin目录放到/home/ctf/目录下,并给他们可执行权限,然后添加了libc库文件,在最后以./start.sh文件为启动文件指定端口为9999
目前只能丢给人机写
start.sh
1 | #!/bin/sh |
注意我用的是GZ平台所以环境变量是$GZCTF_FLAG
flag
1 | cdusec{pwntestflag} |
注意flag要和start.sh中的一致,不然替换不上
docker-compose.yml
1 | version: '3' |
学姐搓的自动部署文件?但是没搞懂怎么用,应该不放到当前目录也是可以成功创建容器的
部署流程
因为直接构建容器不下载ubuntu镜像到本地老是获取超时,所以选择先将镜像扒下来到本地,我们构建的时候就会直接拉本地的了
1 | docker pull ubuntu:22.04 |
创建docker镜像
1 | docker build -t mintlovecate/pwn-11 . |
创建失败就可以开始调整dockerfile了,一般是libc库有问题,我还没跑出一个32位和64位都通用的dockerfile
运行该镜像
将本地9999端口转8888端口运行镜像,镜像名为mintlovecate/pwn-11容器名为pwn_test,flag环境变量为-e GZCTF_FLAG="flag{test123}"
1 | docker run -d -p 127.0.0.1:8888:9999 -e GZCTF_FLAG="flag{test123}" --name pwn_test mintlovecate/pwn-11 |
开始测试
首先看nc连接是否有回显
若nc无回显则是端口问题
nc有回显但是没有运行pwn文件:那么是chroot(沙箱)环境下pwn文件无法运行
报错如下:
也可以在容器中排查
1 | #开启容器 |
这种情况一般是dockerfile中pwn文件的libc文件缺失导致的
解决之后在容器中尝试cat flag
如果cat之后无回显,那么大概率是flag文件为空
使用ls -l flag测试flag文件是否为空

若红圈处为0则证明flag文件未写入,开始排查,flag文件是否为cdusec{pwntestflag} start.sh文件中是否有
1 | sed -i "s/cdusec{pwntestflag}/$GZCTF_FLAG/" /home/ctf/flag |
检查环境变量是否是GZCTF_FLAG
若检查无误仍然显示flag为空,看看运行时环境变量是否指定了GZCTF_FLAG,这时候部署到平台上应该是有了,只是本地没有加环境变量
这时候可以把容器推送到docker hub上了,可以用命令推也可以手动推 。
测试完后记得删除现在正在运行的容器,或已作废的镜像
1 | #删除容器 |
做题平台设置
在gz平台上,我们首先选择动态容器,接着放附件,放镜像源

如果这里拉取镜像失败的话就用xshell 连服务器直接在服务器上pull
申请一个测试容器如果显示下图那么证明动态flag设置成功了

(图片是牢出来后手机拍的有点模糊)
然后就成功了,后续还得研究如何指定libc,应该在dockerfile中修改了
docker的各种命令
概览
1 | docker build -t mintlovecate/pwn-11 . |
一、镜像管理命令
| 命令 | 功能描述 | 示例 |
|---|---|---|
docker images |
列出本地所有镜像 | docker images(查看所有镜像)docker images ubuntu(筛选 ubuntu 镜像) |
docker pull <镜像名:标签> |
从远程仓库拉取镜像 | docker pull ubuntu:22.04(拉取 Ubuntu 22.04) |
docker build -t <镜像名:标签> |
基于 Dockerfile 构建镜像 | docker build -t myapp:v1 .(当前目录构建,标签 v1) |
docker rmi <镜像ID/名称> |
删除本地镜像 | docker rmi 8c79c1a7142d(通过 ID 删除)docker rmi myapp:v1(通过名称删除) |
docker tag <原镜像> <新镜像名:标签> |
为镜像打标签(重命名) | docker tag ubuntu:22.04 myubuntu:latest |
docker push <镜像名:标签> |
推送镜像到远程仓库(需登录) | docker push username/myapp:v1 |
docker inspect <镜像名/ID> |
查看镜像详细信息(配置、层等) | docker inspect ubuntu:22.04 |
二、容器操作命令
| 命令 | 功能描述 | 示例 |
|---|---|---|
docker run [选项] <镜像名> [命令] |
创建并启动容器 | 基础启动:docker run -it ubuntu:22.04 /bin/bash(交互式进入 bash)后台运行:docker run -d --name mycontainer nginx(命名为 mycontainer,后台启动 nginx)端口映射:docker run -p 8080:80 nginx(本地 8080 映射容器 80) |
docker ps |
列出运行中的容器 | docker ps(默认显示运行中)docker ps -a(显示所有容器,包括停止的) |
docker start <容器名/ID> |
启动已停止的容器 | docker start mycontainer |
docker stop <容器名/ID> |
停止运行中的容器 | docker stop mycontainer |
docker restart <容器名/ID> |
重启容器 | docker restart mycontainer |
docker rm <容器名/ID> |
删除容器(需先停止,或加-f强制删除) |
docker rm mycontainer(删除停止的)docker rm -f mycontainer(强制删除运行中的) |
docker exec [选项] <容器名/ID> <命令> |
进入运行中的容器执行命令 | 交互式进入:docker exec -it mycontainer /bin/bash(常用!)执行单条命令:docker exec mycontainer ls /root |
docker logs <容器名/ID> |
查看容器日志 | docker logs mycontainer(查看全部)docker logs -f mycontainer(实时跟踪日志) |
docker inspect <容器名/ID> |
查看容器详细信息(IP、配置等) | docker inspect mycontainer |
docker cp <本地路径> <容器名:路径>``docker cp <容器名:路径> <本地路径> |
本地与容器间复制文件 | 本地→容器:docker cp ./flag.txt mycontainer:/home/容器→本地:docker cp mycontainer:/etc/passwd ./ |
三、网络管理命令
| 命令 | 功能描述 | 示例 |
|---|---|---|
docker network ls |
列出所有 Docker 网络 | docker network ls |
docker network create <网络名> |
创建自定义网络(默认 bridge 模式) | docker network create mynet |
docker network connect <网络名> <容器名> |
将容器连接到指定网络 | docker network connect mynet mycontainer |
docker network disconnect <网络名> <容器名> |
断开容器与网络的连接 | docker network disconnect mynet mycontainer |
docker network rm <网络名> |
删除网络 | docker network rm mynet |
四、数据卷命令(持久化存储)
| 命令 | 功能描述 | 示例 |
|---|---|---|
docker volume ls |
列出所有数据卷 | docker volume ls |
docker volume create <卷名> |
创建数据卷 | docker volume create myvol |
docker volume inspect <卷名> |
查看数据卷详情(路径等) | docker inspect myvol |
docker run -v <卷名:容器路径> ... |
挂载数据卷到容器 | docker run -d -v myvol:/data nginx(容器 /data 映射到 myvol) |
docker volume rm <卷名> |
删除数据卷 | docker volume rm myvol |
五、其他常用命令
| 命令 | 功能描述 | 示例 |
|---|---|---|
docker info |
查看 Docker 系统信息(版本、镜像数、容器数等) | docker info |
docker version |
查看 Docker 客户端和服务器版本 | docker version |
docker login / docker logout |
登录 / 退出 Docker 远程仓库(如 Docker Hub) | docker login(输入用户名密码) |
docker system df |
查看 Docker 磁盘使用情况(镜像、容器、卷占用) | docker system df |
docker system prune |
清理无用资源(停止的容器、未使用的 | docker system prune -a(加-a删除所有未使用镜像) |

