因为一些原因在学docker复现题目,这里做个笔记记录一下以便以后查阅
1.Docker安装
我用的是debian 10
系统,使用daocloud
一键安装命令
curl -sSL https://get.daocloud.io/docker | sh
提示curl
未安装需要安装一下
apt-get update
apt-get install curl
安装完curl
后再次执行安装docker
的命令
2.Docker-Compose安装
使用以下命令安装docker compose
sudo curl -L "https://github.com/docker/compose/releases/download/v2.2.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
给予权限
sudo chmod +x /usr/local/bin/docker-compose
创建软链
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
可以使用以下命令检测是否安装成功
docker-compose --version
如果提示如
cker-compose version 1.24.1, build 4667896b
则安装成功
3.Docker基础命令
写Dockerfile
需要先了解docker的基础的命令,了解run
、cp
、exec
、build
等基础使用即可。
attach Attach local standard input, output, and error streams to a running container
#当前shell下 attach连接指定运行的镜像
build Build an image from a Dockerfile # 通过Dockerfile定制镜像
commit Create a new image from a container's changes #提交当前容器为新的镜像
cp Copy files/folders between a container and the local filesystem #拷贝文件
create Create a new container #创建一个新的容器
diff Inspect changes to files or directories on a container's filesystem #查看docker容器的变化
events Get real time events from the server # 从服务获取容器实时时间
exec Run a command in a running container # 在运行中的容器上运行命令
export Export a container's filesystem as a tar archive #导出容器文件系统作为一个tar归档文件[对应import]
history Show the history of an image # 展示一个镜像形成历史
images List images #列出系统当前的镜像
import Import the contents from a tarball to create a filesystem image #从tar包中导入内容创建一个文件系统镜像
info Display system-wide information # 显示全系统信息
inspect Return low-level information on Docker objects #查看容器详细信息
kill Kill one or more running containers # kill指定docker容器
load Load an image from a tar archive or STDIN #从一个tar包或标准输入中加载一个镜像[对应save]
login Log in to a Docker registry #
logout Log out from a Docker registry
logs Fetch the logs of a container
pause Pause all processes within one or more containers
port List port mappings or a specific mapping for the container
ps List containers
pull Pull an image or a repository from a registry
push Push an image or a repository to a registry
rename Rename a container
restart Restart one or more containers
rm Remove one or more containers
rmi Remove one or more images
run Run a command in a new container
save Save one or more images to a tar archive (streamed to STDOUT by default)
search Search the Docker Hub for images
start Start one or more stopped containers
stats Display a live stream of container(s) resource usage statistics
stop Stop one or more running containers
tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
top Display the running processes of a container
unpause Unpause all processes within one or more containers
update Update configuration of one or more containers
version Show the Docker version information
wait Block until one or more containers stop, then print their exit codes
4.Dockerfile基础命令
FROM # 基础镜像,一切从这里开始构建
MAINTAINER # 镜像是谁写的,姓名+邮箱
RUN # 镜像构建的时候需要运行的命令
ADD # 步骤,tomcat镜像,这个tomcat压缩包!添加内容
WORKDIR # 镜像的工作目录
VOLUME # 挂载目录
EXPOSE # 保留端口配置
CMD # 指定这个容器启动的时候要运行的命令,只有最后一命令会生效,可被替代
ENTRYPOINT # 指定这个容器启动的时候运行的命令,可以追加命令
ONBUILD # 当构建一个被继承Dockerfile这个时候就会运行ONBUILD的指令。
COPY # 类似ADD,将我们的文件拷贝到镜像中
ENV # 构建的时候设置环境变量
有一些需要注意的点
RUN
和CMD
的区别RUN
是在镜像构建时运行的命令,CMD
是在容器生成是运行的命令,RUN
与ENTRYPOINT
的区别同RUN
和CMD
。RUN
和ENTRYPOINT
的区别CMD
:指定这个容器启动的时候要运行的命令,只有最后一命令会生效,可被替代。ENTRYPOINT
:指定这个容器启动的时候运行的命令,可以追加命令。docker容器
需要一个永不退出的进程,否则docker会认为容器没有工作,自动关闭容器。
5.部署环境(以[DASCTF]ezpop为例)
/建议先自己搭建成功一次后再写Dockerfile和Docker-compose文件/
根据实际情况选用不同版本的php等镜像,我这里选php7.3.4和apache的镜像
拉取镜像
docker pull php:7.3.4-apache
开启容器
docker run -it -d -p 2333:80 php:7.3.4-apache
进入容器
docker exec -it <CONTAINER ID> bash
CONTAINER ID
可以使用命令docker ps
查看
进入容器后默认在工作目录,也就是/var/www/html
目录
将题目源代码环境添加进目录中
touch index.php
vim index.php
vim未安装情况使用以下命令安装
apt-get install vim
# 题目源代码,放进index.php中
<?php
class crow
{
public $v1;
public $v2;
function eval() {
echo new $this->v1($this->v2);
}
public function __invoke()
{
$this->v1->world();
}
}
class fin
{
public $f1;
public function __destruct()
{
echo $this->f1 . '114514';
}
public function run()
{
($this->f1)();
}
public function __call($a, $b)
{
echo $this->f1->get_flag();
}
}
class what
{
public $a;
public function __toString()
{
$this->a->run();
return 'hello';
}
}
class mix
{
public $m1;
public function run()
{
($this->m1)();
}
public function get_flag()
{
eval('#' . $this->m1);
}
}
if (isset($_POST['cmd'])) {
unserialize($_POST['cmd']);
} else {
highlight_file(__FILE__);
}
?>
返回根目录创建一个flag
文件
使用ip:2333
进入靶机,能够正常获取flag
6.文件组成
--|ezpop
|--| _files
|--| aa
|-- index.php #装有源代码
|-- docker-php-entrypoint
|-- php.ini
|-- start.sh
|-- docker-compose.yml #docker-compose文件
|-- Dockerfile #Dockerfile文件
7.Dockerfile
FROM php:7.3.4-apache #拉取镜像
COPY _files /tmp/ #复制_files文件夹中所有文件进容器的/tmp/目录下
RUN rm -rf /var/www/html/* \ #删除/var/www/html/目录下的所有文件
&& mv /tmp/docker-php-entrypoint /usr/local/bin/docker-php-entrypoint \ #移动docker-php-entrypoint到/usr/local/bin/docker-php-entrypoint
&& chmod +x /usr/local/bin/docker-php-entrypoint \ #给予权限
&& mv /tmp/aa/* /var/www/html/ \ #移动aa/目录下所有文件到/var/www/html/目录下
&& chown -R www-data:www-data /var/www/html \ #给予权限
# && mv /tmp/php.ini /usr/local/etc/php/php.ini \ 移动php.ini到/usr/local/etc/php/php.ini (部分题目需要)
&& mv /tmp/start.sh /start.sh \ #移动start.sh到根目录
&& chmod +x /start.sh \ #给予权限
&& rm -rf /tmp/* #删除/tmp/目录下所有文件
WORKDIR /var/www/html #设置工作目录为/var/www/html
EXPOSE 80 #开放80端口
CMD ["/bin/bash", "-c", "docker-php-entrypoint"] #容器开启时执行命令
8.docker-compose.yml
version: "2"
services:
web:
build: .
image: ezpop #镜像名称
restart: always
ports:
- "2333:80" #设置映射端口
environment:
- FLAG=flag{jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj} #设置FLAG为环境变量,为了ctfd实现动态flag
9.docker-php-entrypoint
#!/bin/sh
sh /start.sh #启动脚本
tail -F /dev/null #永不停止的进程
10.start.sh
#!/bin/sh
echo $FLAG > /f14g #将全局变量$FLAG放入根目录的/f14g文件中
export FLAG=not_flag
FLAG=not_flag #设置动态flag
/etc/init.d/apache2 start #启动apache
rm -f /start.sh #删除start.sh
11.测试
将打包好的文件压缩包上传至服务器,解压后进入文件夹
使用以下命令启动容器
docker-compose up -d
等待启动成功后进入网址
ip:2333
成功进入,能够通过解题获取flag
12.动态flag
使用ctfd的插件实现,在前面的文件中已经设置了全局变量
具体方法这里不再赘述
Comments NOTHING