这里我以easycms的镜像为基础镜像:
下载地址:
https://github.com/Medicean/VulApps/tree/master/c/cmseasy/1
这个是一个不错的开源项目,我们可以在它的基础上改进~。
docker pull medicean/vulapps:c_cmseasy_1
我们都知道 Git 的tag功能是为了将代码的某个状态打上一个戳,通过tag我们可以很轻易的找到对应的提交版本。
Docker 的tag似乎更加灵活,Docker 将文件等信息的变动抽象为一次次的commit,每一次commit以后可能走向不同的分支,当我们完成Docker file的构建后,会生成一串无规则的字符串代表此次生成的ID,此时,tag的作用就是为他创建一个友好的名称,方便我们对镜像库的管理。
以这个为例,这个是名称vulapps,标签是cmseasy_1
重命名的语句是:docker tag old-image[:old-tag] new-image[:new-tag]
我们运行: docker tag vulapps:c_cmseasy_1 pentest:v1就可以了。
ps.记住,tag中不能再包含:(冒号)了!还有就是pentest不能有大写的字母。
有冒号会造成tag识别紊乱,然后报错如下:
Error parsing reference: "pentest:v7:v6" is not a valid repository/tag: invalid reference format
至于不能有大写字母,这个是规定吧。写了就报错如下:
Error parsing reference: "Pentest:v7" is not a valid repository/tag: invalid reference format: repository name must be lowercase
我们运行:docker run -dit pentest:v1
看一下ip:
eth0 Link encap:Ethernet HWaddr 02:42:ac:11:00:03
inet addr:172.17.0.3 Bcast:0.0.0.0 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
访问的时候出现这种情况,说明,apache没有启动。
基础镜像包根目录发现有一个start.sh
root@ec744607ca02:/# cat start.sh
#!/bin/bash
/etc/init.d/mysql restart
/etc/init.d/apache2 restart
/usr/bin/tail -f /dev/null
root@ec744607ca02:/#
查看下服务,这里发现apache和mysql都是停止的。
root@ec744607ca02:/# service --status-all
[ - ] apache2
[ ? ] console-setup
[ + ] cron
[ ? ] killprocs
[ ? ] kmod
[ ? ] mysql
[ ? ] networking
[ ? ] ondemand
[ - ] procps
[ ? ] rc.local
运行这个脚本重启web容器就可以正常访问了
当然我们要做的是把它拉下来运行成功这么简单的。
我们要在这个基础上构造我们新的镜像,然后运行其他cms。
构建镜像的两种方法:
使用Docker commit 命令
使用Docker build命令和Docker file 文件
这里我都用~Docker file的书写需要一定的shell脚本基础
关于Docker file的编写可以看下面这篇文章:
http://www.zioer.org/2016/05/16/Docker-file-write/?utm_source=tuicool&utm_medium=referral
我们首先用比较简单的commit命令。
要做其他的cms靶场,我们可以cmseasy的源码删除掉,然后再把我们的另一台cms拷贝进去。
我这里用maccms8,最近在看这个cms,不为什么,看到有人发审计的分析觉得有趣,就分析下复现了。
要从物理机把文件拷贝进去也是有两种方法的~
第一个方法是官方比较推荐的,其实和最后那种方法实现是一样的。docker cp的方法实现也是把文件推到容器里的aufs文件系统里:
什么是aufs系统,它全名叫做:Union File System,就是把不同物理位置的目录挂载在同一个目录下,深入了解和实验可以看下:
http://www.open-open.com/lib/view/open1440483391763.html
好了,题外话多了~
他实现的命令为:docker cp <containerId>:/ path/file /host/path/file
这个是从容器拷贝到物理机的,同理反过来即可。
但是有一点要提的,拷贝的时候如果从物理机拷贝到docker中,docker不存在某个文件会自动新建一个文件或者文件夹。而反过来的话,docker拷贝到物理机,如果docker不存在某个文件会报错如下:
Error response from daemon: lstat /var/lib/docker/aufs/mnt/c6e8f37e91d6dec2a0c14c7be7704b88443720c04eec5ac03493dae306f993fb/var/www/html/test: no such file or directory
其实不存在文件都会报错,但是为什么要提到这个呢?
因为这样就把docker在物理机的路径爆出了,这样你肯定理解所谓文件推到容器里的aufs文件系统是什么样的概念了吧。
你可以切换到root权限,然后进入这个路径:
其实可以直接用cp命令了~
但是我们直接用 docker的命令,一步到位:docker cp maccms8_mfb/. ec744607ca02:/var/www/html
第二种方法,需要你docker run 创建容器的时候,就需要指定挂载的目录:
docker run -v /path/dir $container
我们运行:
docker run -itdv /~Desktop/test pentest:v5
然后用docker exec进入,这样你在系统中就可以看到然后外挂在里的目录了,直接copy就可以了。
小tips:
有时候attach会卡死,那是因为如果运行了docker,自启动不是以bin/bash为COMMAND会出现这种情况。如下:v6用attach会卡死的。
attach与deatch配对使用,默认使用Ctrl + p, Ctrl + q再次detach。然后我们运行docker exec –it /bin/bash 就可以了。
我们已经弄完cms
安装后commit即可。
但是我们每此都要自己启动apache服务很麻烦,这个时候我么那就要写一个shell脚本或者其他方法让web服务自己启动。
在ubuntu中有两种方法可以让系统自启动一些服务。
1、方法一,编辑rc.loacl脚本
Ubuntu开机之后会执行/etc/rc.local文件中的脚本, 所以我们可以直接在/etc/rc.local中添加启动脚本。 当然要添加到语句:exit 0 前面才行。
2、方法二,添加一个Ubuntu的开机启动服务
如果要添加为开机启动执行的脚本文件, 可先将脚本复制或者软连接到/etc/init.d/目录下, 然后用:update-rc.d xxx defaults NN命令(NN为启动顺序), 将脚本添加到初始化执行的队列中去。 注意如果脚本需要用到网络,则NN需设置一个比较大的数字,如99。 1) 将你的启动脚本复制到 /etc/init.d目录下 以下假设你的脚本文件名为 test。 2) 设置脚本文件的权限
remove
/etc/init.d/mysql restart
/etc/init.d/apache2 restart
/usr/bin/tail -f /dev/null
我试了之后都失败了,后面一个docker很6的同事告诉我说,在docker中自启动需要编写dockerfile。还记得我们之前说过:
一个运行态容器(running container)被定义为一个可读写的统一文件系统加上隔离的进程空间和包含其中的进程。
所以在容器里设置自启动是没有走到那边的服务的~
我们新建一个Dockerfile 只需要在里面写上简单帅气的两条指令~
FROM pentest:v7
ENTRYPOINT ["/start.sh"]
然后用docker build就可以生成了~
这样一个新的靶场就完成了~