因为我这个出题搭建的是一个不需要数据库的 php+Apache环境,所以我就以这个为例进行说明了

基本的一些概念

docker build -t 是利用Dockerfile 构建镜像,这个时候可以使用 –name 来给自己的镜像命名
docker run 是利用依据这个镜像构建容器,这个时候可以使用 –name 命名你的容器
如果容器需要修改配置文件,我们可以选择挂载/挂载数据卷的方式,也可以直接COPY/ADD来覆盖

踩过的一些坑:

1.不要直接用 php:5.6-apache 这个环境,这个环境的“特色”就是没有php.ini 文件,,如果你出题不需要修改这个这一点可以直接忽略

2.COPY 的源路径一定是相对路径(./),是相对于镜像构建上下文的路径(默认是Dockerfile的路径),目的地址是容器的绝对路径

3.容器运行的第一命令,RUN 的第一条指令一定是

apt-get update
apt-get -y ugrade

这个容器的源早就不能用了,其中特别要注意下面这条命令的 -y 选项

apt-get -y upgrade 

别以为 uprade 的时候和update 一样会一直进行下去,其实这中间还有要你输入Y的地方,不加这个选项在Dockerfile中就会出问题。

4.容器在安装东西的时候一定要仔细检查这个安装过程是不是需要人工输入 y/n 的,如果需要,在安装的时候就一定要 -y 否则肯定会失败

5..htaccess 导致访问出现500错误 ,在修改了配置文件以后 使用下面的命令开启URL重写

a2enmod rewrite 
service apache2 restart    

6.网站直接访问出现400 错误 是因为 apache 有一个实例页面在 www 目录下,我们需要修改配置文件,设置网站的默认根路径是 /var/www/html

7.php header()不能跳转清理缓存ob_start();

8.出现下面的这个错误要在Dockerfile 里面

debconf: unable to initialize frontend: Dialog
debconf: (TERM is not set, so the dialog frontend is not usable.)
debconf: falling back to frontend: Readline
debconf: unable to initialize frontend: Readline
debconf: (This frontend requires a controlling tty.)
debconf: falling back to frontend: Teletype
invoke-rc.d: policy-rc.d denied execution of stop.
invoke-rc.d: policy-rc.d denied execution of start.

在Dockerfile的最后添加

ARG DEBIAN_FRONTED=noninteractive

9.容器就是一个进程,依赖于命令,命令结束之后容器就会关闭,我们一般选择使用 docker run 来维持这个容器,或者就是使用 exec 外加循环程序外加 -d 后台执行来维持

10.一直听网上说的什么docker 容器没法保存状态,我居然就信以为真了,我以为docker容器一旦退出或者停止里面的东西就会全部消失,之前配置的都没了,于是我就拼命地写dockerfile,梦想着有一天能直接一键生成我的题目,但是由于我的题目需要配置各种权限,以及修改各种配置文件,导致我在运行dockerfile 的时候出现了各种各样奇奇怪怪的问题,结果我实在是配置不好了,就打算直接手动配置docker,于是我一测试,发现所谓的配置消失的情况并没有出现,容器一旦创建只要你不销毁,那么里面的东西是不会消失的,你做的所有的设置也不会,他们所说的配置消失只是针对你利用 dockerfile再次生成新的容器的时候不会存在你在现有容器中出现的配置而已,那还不好办,到时候我直接

exit
docker exec -d  xxxx bash service apache2 start 

让他后台运行就行了

11.镜像构建好之后,我们查看镜像可能会不只有一个,这是因为我们的镜像是搭建在别人的基础镜像之上的,所以显示的时候基础镜像也会显示到时候run 的时候不要run错了

12.不管是生成镜像还是生成容器,我们都最好制定一个名字,这样方便我们定位,方法都是一样的使用 –name 名字

好用的命令

停止并删除所有的容器

docker stop $(docker ps -q) & docker rm $(docker ps -aq)

删除所有的镜像

docker rmi $(docker images -q)

如何搭建CTF getshell的环境

一直做CTF getshell 的题目,自己也想过这个问题:“师傅们的权限是怎么配置出来的,我都getshell了,为什么还是不能改其他的文件”,但是想想这个就是一个非常复杂的问题,因为懒惰,我就是自己没有试过怎么实现的……正如那句话,出来混总是要还的,今天欠下的债,早晚都得补上。这次借着给校赛出题我就挑战了一下自己,学习实践了一下如何配置这个环境。

1.首先明确的一个问题

我们getshell一般使用的都是菜刀,毕竟菜刀比较方便嘛,当然如果是就是找一个flag什么的直接hackbar就能搞定了,要是其他需求就要自己写脚本了。

那么你知不知道菜刀连接上去是什么权限呢?

正解:其实菜刀连接上去默认是 www-data 的权限

不信自己去试一下

2.如何限制 www-data 的权限?

没错,这就是本文的重点了,
首先我们需要创建一个 apache用户组 并在 apache 用户组中创建一个 apache 用户

groupadd apache
useradd -r -g apache apache 

接下来我们就要把我们的web目录的全部文件改成属于apache组的apache用户的(因为是docker 所以我的web目录里只有我这一道题)

chown -R apache . 
chgrp -R apache . 

然后我们给他们744的权限,也就是只读,那他们 www-data 用户就凉了

chmod 744 -R .

接下来还有最最重要的一步,就是我们必须将apache配置文件 apache2.conf (这个配置文件的名字要根据不同的环境而定,也有可能是 httpd.conf)里面的 apache的启动权限设置为Apache用户和Apache用户组。(找到配置文件里面的 USER 和 GROUP 然后我们将其都改成apache 就行了)

USER apache 
GROUP apache 

最后别忘了重启 apache 哦!

因为这里涉及到权限的问题,比较复杂,我会更新这篇文章或者新开一篇文章

下面是关于 Shell 权限的探究的文章地址:

关于 Shell 权限的一些探究

3.最终的Dockerfile

下面是我写的dockerfile 的大致内容 (直接运行不一定可以,只是给大家一个参考),由于没能一步生成题目,于是下面有一些手动配置的东西

Dockerfile

#创建基础镜像                                               
FROM linode/lamp
#导入题目代码
COPY ./test.zip  /var/www/html/test.zip
#更新源以及安装服务修改权限
RUN apt-get update \
    && apt-get -y upgrade \
    && apt-get install -y  vim \
    && service apache2 start \
    && cd /usr/share/apache2 \
    && groupadd apache \
    && useradd -r -g apache apache \
    && chown -R apache . \
    && chgrp -R apache . \
    && chmod 744 -R .
#安装zip软件对文件解压
RUN apt-get install -y zip \
    && unzip /var/www/html/test.zip \
#删除压缩包
    && rm -rf /var/www/html/test.zip \
#修改权限(与题目有关)
    && chmod 777 /var/www/html/Uploads \
#移除默认的目录
    && rm -rf /var/www/example.com \
#生成新的log目录
    && mkdir /var/www/log 

一些手动的配置:

1.修改apache 的网站根路径为html(在这个文件里:/etc/apache2/sites-enabled/example.com.conf)
2.修改apache2.conf 实现URL重写(因为我用了.htaccess)
3.修改apache2.conf 里面的 USER GROUP 为 apache
4.修改php.ini(与本题有关)

使URL重写生效

a2enmod rewrite 
service apache2 restart