Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

0x01安装docker desktop

因本人尝试在kali安装docker未成功, 故最后使用傻瓜式安装的docker desktop

打开 docker官网 (访问本网站需要magic 能看到我文章的应该都会magic吧) 下载docker desktop并安装

docker官网

1.1给docker换源

将如下代码复制到docker engine中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
"builder": {
"gc": {
"defaultKeepStorage": "20GB",
"enabled": true
}
},
"experimental": false,
"features": {
"buildkit": true
},
"registry-mirrors": [
"https://docker.mirrors.ustc.edu.cn",
"https://registry.docker-cn.com",
"http://hub-mirror.c.163.com",
"https://mirror.ccs.tencentyun.com"
]
}

docker desktop

这里我换的是中科大源, 你也可以选择换别的源

注: 完成换源后docker engine可能不会马上跑起来, 将电脑重启即可

engine成功启动左下角应该如下所示:

engine running

0x02 gcc指定glibc版本编译

因为出题可能需要用到某些特定版本的glibc, 所以不能用虚拟机直接编译(除非glibc刚好一致), 所以要制作一个用于编译的docker

2.1 制作对应版本glibc的容器镜像

这步非常轻松, 让gpt给你写一个Dockerfile即可

比如我要用glibc2.23进行编译, 拷打gpt获得的Dockerfile如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 使用Ubuntu 16.04作为基础镜像
FROM ubuntu:16.04

# 换源
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 install -y \
build-essential \
gcc \
libc6-dev \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

# 设置工作目录
WORKDIR /app

# 将你的C代码复制到容器中
COPY test.c /app/

# 编译你的C代码并将编译后的二进制文件保存到/app目录中
RUN gcc -z norelro -fno-stack-protector -no-pie -z execstack -o test test.c

# 保持容器运行,以便主机访问容器内的编译结果
CMD ["sleep", "infinity"]

注: gpt生成的默认不会换源,可以加上以下两行,换个源提升下载速度:

1
2
3
# 换源
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

gcc编译

  • NX :-z execstack / -z noexecstack (关闭 / 开启) 不让执行栈上的数据,于是JMP ESP就不能用了
  • Canary :-fno-stack-protector /-fstack-protector / -fstack-protector-all (关闭 / 开启 / 全开启) 栈里插入cookie信息
  • PIE :-no-pie / -pie (关闭 / 开启) 地址随机化,另外打开后会有get_pc_thunk
  • RELRO :-z norelro / -z lazy / -z now (关闭 / 部分开启 / 完全开启) 对GOT表具有写权限
  • 编译输出: -o name(输出名为name)
1
例: gcc -z norelro -fno-stack-protector -no-pie -z execstack -o test test.c

2.2 制作gcc的容器镜像

起一个文件夹,将Dockerfile还有源代码test.c放进去,在该文件夹下执行以下代码制作镜像:

1
docker build -t name_of_docker_image .                    # 制作镜像

如图:

Snipaste 2024 08 22 11 08 07

test是复制出来的编译好的附件

2.3 将编译好的附件复制到本机

1
2
3
docker run --name name_of_container name_of_docker_image  # 启动容器
docker cp name_of_container:/app/test . # 将文件复制到本机
docker stop name_of_container && docker rm name_of_container # 关闭并删除容器

以上便获得了指定glibc版本编译的附件了

0x03 题目镜像制作

3.1CTF-Xined项目获取

1
2
3
4
#下载地址,下载完成后拷贝到任意文件夹中
https://github.com/CTF-Archives/ctf-docker-template
#或者在文件夹下使用powershell直接git获取
git clone https://github.com/CTF-Archives/ctf-docker-template

完成后效果如下图:

docker template

使用教程请查看CTF-Xined项目github的教程

我们出pwn题一般只需用到以下4个文件

Snipaste 2024 08 22 10 38 50

打开任意一个,然后将出的题目附件放到src下

Snipaste 2024 08 22 10 42 31
Snipaste 2024 08 22 10 42 52

为了图方便我直接把附件名称改成attachment了, 如果需要保留附件名称请参考README.md

例如ubuntu_16.04的README.md如下:

Snipaste 2024 08 22 10 46 49

3.2 题目镜像制作

在ubuntu版本目录下启动powershell, 执行以下命令, 制作题目镜像

1
2
#docker build -t 创建容器名字(题目名字)
docker build -t name_of_docker_image . #注意后面有个点.

注: build失败的话请使用magic并尝试

查看制作的题目镜像

1
docker images    #查看制作的镜像

如此一来便制作完容器镜像了

0x04 将容器镜像push到github

如果GZ:CTF平台没有搭在本地,则需要将容器镜像push到github以便平台访问

4.1 获取token用来往github里面传packge

打开github进行如下操作:

  1. 点击右上角头像,选择Settings
  2. 左边一列拉到最下面点击Developer settings
  3. 左边一列点开Personal access tokens选择Tokens(classic)
  4. 偏右上角点开Generate new token选择Generate new token(classic)

嫌麻烦直接访问:https://github.com/settings/tokens/new 即可完成上述步骤

然后在Note里填一个token名,在下面勾选write:oackages

Snipaste 2024 08 22 11 55 23

然后拉到最下面Generate token,会生成一个token,将它复制下来并保存好

4.2 将镜像push到github上

1
2
3
echo your_token | docker login ghcr.io --username your_id --password-stdin
docker tag name_of_package ghcr.io/your_id/app:latest
docker push ghcr.io/your_id/app:latest

将上述代码中的your_token替换成上一步获取的 token, 将your_id替换成你的 github id 注意: 后两行代码的id需全部小写

name_of_package填你想要的package名, app是镜像名(REPOSITORY), latest是版本号(TAG)

如果忘记可以在powershell执行docker images查询,如下图:

Snipaste 2024 08 22 12 09 22

例如: docker push ghcr.io/skynionkrz/babyshellcode:latest

最后随便开启一个powershell,执行以上代码即可

4.3 将package改成public 填入GZ:CTF中的容器镜像

打开github, 点击右上角头像选择Your repositories, 找到Packages

之前都没有问题的话, 应该是如图所示:

Snipaste 2024 08 22 12 20 21

你能找到刚刚上传的镜像, 点开该package, 选择Package settings

Snipaste 2024 08 22 12 22 17

扒拉到最下面选择Change visibility, 改成public

Snipaste 2024 08 22 12 28 10

最后一步!!! 把项目地址复制到容器镜像里

Snipaste 2024 08 22 12 30 06

注: 国内连不太上,把ghcr.io换成ghcr.nju.edu.cn就行了; 还有别忘了把服务端口改成9999(默认是9999)

0x05 Win!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

参考文章