AuthZ& AuthN - Docker Access Authorization Plugin
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Docker’s out-of-the-box authorization model is all or nothing. Any user with permission to access the Docker daemon can run any Docker client command. The same is true for callers using Docker’s Engine API to contact the daemon. If you require greater access control, you can create authorization plugins and add them to your Docker daemon configuration. Using an authorization plugin, a Docker administrator can configure granular access policies for managing access to the Docker daemon.
Docker Auth plugins are external plugins you can use to allow/deny actions requested to the Docker Daemon depending on the user that requested it and the action requested.
The following info is from the docs
When an HTTP request is made to the Docker daemon through the CLI or via the Engine API, the authentication subsystem passes the request to the installed authentication plugin(s). The request contains the user (caller) and command context. The plugin is responsible for deciding whether to allow or deny the request.
The sequence diagrams below depict an allow and deny authorization flow:
Each request sent to the plugin includes the authenticated user, the HTTP headers, and the request/response body. Only the user name and the authentication method used are passed to the plugin. Most importantly, no user credentials or tokens are passed. Finally, not all request/response bodies are sent to the authorization plugin. Only those request/response bodies where the Content-Type
is either text/*
or application/json
are sent.
For commands that can potentially hijack the HTTP connection (HTTP Upgrade
), such as exec
, the authorization plugin is only called for the initial HTTP requests. Once the plugin approves the command, authorization is not applied to the rest of the flow. Specifically, the streaming data is not passed to the authorization plugins. For commands that return chunked HTTP response, such as logs
and events
, only the HTTP request is sent to the authorization plugins.
During request/response processing, some authorization flows might need to do additional queries to the Docker daemon. To complete such flows, plugins can call the daemon API similar to a regular user. To enable these additional queries, the plugin must provide the means for an administrator to configure proper authentication and security policies.
You are responsible for registering your plugin as part of the Docker daemon startup. You can install multiple plugins and chain them together. This chain can be ordered. Each request to the daemon passes in order through the chain. Only when all the plugins grant access to the resource, is the access granted.
The plugin authz allows you to create a simple JSON file that the plugin will be reading to authorize the requests. Therefore, it gives you the opportunity to control very easily which API endpoints can reach each user.
This is an example that will allow Alice and Bob can create new containers: {"name":"policy_3","users":["alice","bob"],"actions":["container_create"]}
In the page route_parser.go you can find the relation between the requested URL and the action. In the page types.go you can find the relation between the action name and the action
You can find an easy to understand plugin with detailed information about installation and debugging here: https://github.com/carlospolop-forks/authobot
Read the README
and the plugin.go
code to understand how is it working.
The main things to check are the which endpoints are allowed and which values of HostConfig are allowed.
To perform this enumeration you can use the tool https://github.com/carlospolop/docker_auth_profiler.
run --privileged
In this case the sysadmin disallowed users to mount volumes and run containers with the --privileged
flag or give any extra capability to the container:
However, a user can create a shell inside the running container and give it the extra privileges:
Now, the user can escape from the container using any of the previously discussed techniques and escalate privileges inside the host.
In this case the sysadmin disallowed users to run containers with the --privileged
flag or give any extra capability to the container, and he only allowed to mount the /tmp
folder:
Note that maybe you cannot mount the folder /tmp
but you can mount a different writable folder. You can find writable directories using: find / -writable -type d 2>/dev/null
Note that not all the directories in a linux machine will support the suid bit! In order to check which directories support the suid bit run mount | grep -v "nosuid"
For example usually /dev/shm
, /run
, /proc
, /sys/fs/cgroup
and /var/lib/lxcfs
don't support the suid bit.
Note also that if you can mount /etc
or any other folder containing configuration files, you may change them from the docker container as root in order to abuse them in the host and escalate privileges (maybe modifying /etc/shadow
)
The responsibility of the sysadmin configuring this plugin would be to control which actions and with which privileges each user can perform. Therefore, if the admin takes a blacklist approach with the endpoints and the attributes he might forget some of them that could allow an attacker to escalate privileges.
You can check the docker API in https://docs.docker.com/engine/api/v1.40/#
It's possible that when the sysadmin configured the docker firewall he forgot about some important parameter of the API like "Binds". In the following example it's possible to abuse this misconfiguration to create and run a container that mounts the root (/) folder of the host:
Note how in this example we are using the Binds
param as a root level key in the JSON but in the API it appears under the key HostConfig
Follow the same instruction as with Binds in root performing this request to the Docker API:
Follow the same instruction as with Binds in root performing this request to the Docker API:
Follow the same instruction as with Binds in root performing this request to the Docker API:
It's possible that when the sysadmin configured the docker firewall he forgot about some important attribute of a parameter of the API like "Capabilities" inside "HostConfig". In the following example it's possible to abuse this misconfiguration to create and run a container with the SYS_MODULE capability:
The HostConfig
is the key that usually contains the interesting privileges to escape from the container. However, as we have discussed previously, note how using Binds outside of it also works and may allow you to bypass restrictions.
If the sysadmin forgotten to forbid the ability to disable the plugin, you can take advantage of this to completely disable it!
Remember to re-enable the plugin after escalating, or a restart of docker service won’t work!
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)