0x0 Docker是什么
Docker 属于 Linux 容器的一种封装,提供简单易用的容器使用接口。它是目前最流行的 Linux 容器解决方案。
Docker 将应用程序与该程序的依赖,打包在一个文件里面。运行这个文件,就会生成一个虚拟容器。程序在这个虚拟容器里运行,就好像在真实的物理机上运行一样。有了 Docker,就不用担心环境问题。
总体来说,Docker 的接口相当简单,用户可以方便地创建和使用容器,把自己的应用放入容器。容器还可以进行版本管理、复制、分享、修改,就像管理普通的代码一样。
也体验一下docker,这里有别人已经搭好的 https://github.com/skysider/pwndocker
这里也自己搭下,体验下流程
docker官方文档
复用别人的image,真爽
下载
1 | docker pull skysider/pwndocker |
启动
1 | docker run -d --rm -h breeze --name redhat -v /mnt/hgfs/share:/ctf/work -p 23946:23946 --cap-add=SYS_PTRACE skysider/pwndocker |
- -d:后台运行
- –rm:停止后自动删除
- -h:主机名breeze
- –name:docker名字breeze
- -v:将kali的/mnt/hgfs/share挂在再docker中的/ctf/work目录(share也是kali和物理机的共享目录,三机共享)
- -p:端口映射(没啥用,这时已经不用ida远程调试了,有些题目带端口的可以用)
- –cap-add:增加一个参数,否则调试会出问题
然后就可以获取id,以后每次都用shell脚本开启就行
调试时
1 | from pwn import * |
- 第二行指定ld.so和libc
- 第三行要在tmux下运行才能出调试的那个终端
0x01 下载并启动ubuntu镜像
Docker 把应用程序及其依赖,打包在 image 文件里面。只有通过这个文件,才能生成 Docker 容器。image 文件可以看作是容器的模板。Docker 根据 image 文件生成容器的实例。同一个 image 文件,可以生成多个同时运行的容器实例。
image 是二进制文件。实际开发中,一个 image 文件往往通过继承另一个 image 文件,加上一些个性化设置而生成。举例来说,你可以在 Ubuntu 的 image 基础上,往里面加入 Apache 服务器,形成你的 image。
这里我们从官网的仓库中拉取一个ubuntu 18.04的image然后自己创建一个pwn环境的image
1 | docker pull ubuntu:18.04 |
接下来启动ubuntu镜像;
1 | $ docker run -i -t --name create_env ubuntu:18.04 bash |
-t 和 -i 这两个参数是必须的,代表的是可交互的。
0x02 安装环境
修改源
和正常的ubuntu一样,首先修改系统的源,这里使用的是清华的源:
https://mirror.tuna.tsinghua.edu.cn/help/ubuntu/
依次执行下面的命令
1 | cd /etc/apt |
安装pwntools
依次执行:
1 | apt-get install python2.7 python-pip python-dev git libssl-dev libffi-dev build-essential |
安装32位库
1 | sudo apt-get install lib32ncurses5 lib32z1 |
其它
pwngdb
解决无法ping通github
ROPGadget等工具
安装tmux
使用bash进入到docker中后只有一个命令行终端,这样很不方便,可以在该容器中安装tmux,来同时开启多个终端。
使用
apt-get install tmux来安装
启动鼠标切换界面:
1 | root@5cfd7de2e9f7:~# touch .tmux.conf |
注意:在启用鼠标切换之后如果需要选中终端中的部分内容,需要在按住Shift的情况下才可以
tmux快捷键
ctrl b + l
ctrl b + n
分别是切换到last页和next页
ctrl b + [
可以使用光标滚屏 q 退出
ctrl b + 方向键
切换split分隔的终端
0x03 将容器打包成自己的镜像
经过上面的步骤,我们已经搭建好了需要的环境,下面就将这个容器打包成镜像:
- 首先退出该容器,然后查看已经停止运行的容器:
1
2
3$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5cfd7de2e9f7 ubuntu:16.04 "bash" About an hour ago Exited (0) 13 seconds ago create_env
得到容器的id为:5cfd7de2e9f7
使用commit命令提交该容器为镜像:
1
2
3
4
5
6
7
8
9
10
11
12
13
14# 可能需要一点时间
$ docker commit -m "pwn 16.04 v2" 5cfd7de2e9f7 e3pem/dockerpwn:v2
sha256:68136e03da7b3d544fd8ece63b6fbdcbd962948e9bcdc1a390d529cb89193ea9
# 其中`-m`为提交镜像时的描述
# 5cfd7de2e9f7 为容器的id
# e3pem/dockerpwn:v2 为镜像的标签,将e3pem换成自己在dockerhub上的用户名
# 查看构造出来的镜像
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
e3pem/dockerpwn v2 68136e03da7b 2 minutes ago 956MB
e3pem/dockerpwn v1 fa2334fe2cd8 20 hours ago 1.24GB
dockerpwn v1 fa2334fe2cd8 20 hours ago 1.24GB
ubuntu 16.04 b9e15a5d1e1a 3 weeks ago 115MB可以选择将镜像push到dockerhub:
0x04 使用构建的镜像
在分析题目的时候经常需要进行调试,在docker中调试是需要权限的,因此在第一次启动镜像的时候需要添加–privileged选项
同时可以将容器中的某一个目录和主机的目录建立映射,这样就能很方便的在宿主机和容器间共享文件了,使用-v选项来设置共享目录
1 | docker run -i -t --privileged -v /home/yourhost/path/ctf:/home/docker/path/ctf e3pem/dockerpwn:v2 bash |
其中-v 后面的路径就是你自己的哪个文件夹要映射到容器里的哪个文件夹
在容器停止运行后,下次要继续在该容器中运行,可以按如下方法:
先获取到容器的id:
1 | $ docker ps -a |
获取到容器的id为:6121daf720c0
建立一个脚本,内容如下:
1 | docker container start 6121daf720c0 |
0x05 附上自己的镜像地址
2.31
1 | docker pull registry.cn-hangzhou.aliyuncs.com/cooook/dockerpwn:v1 |
2.29
1 | docker pull wood1314/19pwn:v2 |
2.27
1 | docker pull registry.cn-hangzhou.aliyuncs.com/pwndocker/pwndocker-nocbtm:1.0 |