[opensuse-packaging] "quilt setup" considered harmful
Hello packagers, the SUSE security team wants to draw your attention to a potential security threat involving the use of `quilt setup ...` on untrusted RPM spec files. For many of us calling `quilt setup $PACKAGE.spec` is probably a frequent part of our daily workflows. In contrast to building a package on the server in an isolated VM or on the client in a chroot via `osc build`, the `quilt setup` runs without any isolation on the host in the calling user's context. As it turns out this operation easily allows to execute code in the following ways: - The statements in the `%prep` section of the RPM spec file are unconditionally executed in the context of the calling user. - Arbitrary flags can be passed to `patch` via `%define _default_patch_flags ...` in the spec file. By embedding semicolons into the flags also arbitrary commands can be injected this way. - By combining the available vectors, difficult to spot malicious code can be hidden in RPM spec files. For example patch can be caused to follow symlinks, thereby "patching" files in a user's home directory as demonstrated in [1]. A demonstration works like this: ```sh $ osc co home:mgerstner/surprise $ cd home:mgerstner/surprise $ quilt setup surprise.spec # notice the surprise $ bash ``` We have posted about this on the oss-security mailing list [2] to start a discussion about possible countermeasures. A first aid could be to run the `quilt setup` inside a docker container or in a similar isolated environment. We are currently testing isolation of quilt with nsjail [3]. nsjail RPMs are available for Leap 15 and Tumbleweed from its devel project [4]. It is currently not found in Factory/Leap directly. Via the wrapper "squilt" [5], nsjail is utilized to confine quilt to read only the files it needs and is only able to write in the current directory. According to our initial testing it can be used as a drop in replacement and should reduce the attack surface significantly. Our foremost intent is to make you aware of this so you don't run `quilt setup` unsuspectingly on untrusted packages that did not go through review. Furthermore to make you aware of how malicious code that targets this can be embedded in spec files and patches. This should be taken into account when reviewing package submissions. If you have any questions or suggestions then please let's start a discussion. [1]: https://build.opensuse.org/package/show/home:mgerstner/surprise [2]: https://www.openwall.com/lists/oss-security/2018/09/27/2 [3]: http://nsjail.com [4]: https://build.opensuse.org/package/show/security/nsjail [5]: https://github.com/jsegitz/squilt -- Matthias Gerstner <matthias.gerstner@suse.de> Dipl.-Wirtsch.-Inf. (FH), Security Engineer https://www.suse.com/security Telefon: +49 911 740 53 290 GPG Key ID: 0x14C405C971923553 SUSE Linux GmbH GF: Felix Imendörffer, Jane Smithard, Graham Norton HRB 21284 (AG Nuernberg)
El 27-09-2018 a las 13:09, Matthias Gerstner escribió:
Hello packagers,
the SUSE security team wants to draw your attention to a potential security threat involving the use of `quilt setup ...` on untrusted RPM spec files.
You can do all of this with systemd-run, no need to install anything new something like: systemd-run -q --wait --pty -p PrivateDevices=yes -p ProtectSystem=full -p BindPaths=... -p |ProtectHome=tmpfs| -p ... .. see the systemd.exec and systemd-run man pages for more details. systemd-run -q --wait --pty -p PrivateDevices=yes ls /dev -- To unsubscribe, e-mail: opensuse-packaging+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse-packaging+owner@opensuse.org
On Thu, Sep 27, 2018 at 02:45:27PM -0300, Cristian Rodríguez wrote:
El 27-09-2018 a las 13:09, Matthias Gerstner escribió:
Hello packagers,
the SUSE security team wants to draw your attention to a potential security threat involving the use of `quilt setup ...` on untrusted RPM spec files.
You can do all of this with systemd-run, no need to install anything new something like:
systemd-run -q --wait --pty -p PrivateDevices=yes -p ProtectSystem=full -p BindPaths=... -p |ProtectHome=tmpfs| -p ... .. see the systemd.exec and systemd-run man pages for more details.
systemd-run -q --wait --pty -p PrivateDevices=yes ls /dev
This is nice, but it requires root privileges. nsjail has the advantage that you confine this as normal user Johannes -- GPG Key E7C81FA0 EE16 6BCE AD56 E034 BFB3 3ADD 7BF7 29D5 E7C8 1FA0 Subkey fingerprint: 250F 43F5 F7CE 6F1E 9C59 4F95 BC27 DD9D 2CC4 FD66 SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton HRB 21284 (AG Nürnberg)
El 02-10-2018 a las 10:05, Johannes Segitz escribió:
This is nice, but it requires root privileges. nsjail has the advantage that you confine this as normal user
So nsjail rans on user namespaces? -- To unsubscribe, e-mail: opensuse-packaging+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse-packaging+owner@opensuse.org
On Thu, Sep 27, 2018 at 12:09 PM Matthias Gerstner <mgerstner@suse.de> wrote:
Hello packagers,
the SUSE security team wants to draw your attention to a potential security threat involving the use of `quilt setup ...` on untrusted RPM spec files.
For many of us calling `quilt setup $PACKAGE.spec` is probably a frequent part of our daily workflows. In contrast to building a package on the server in an isolated VM or on the client in a chroot via `osc build`, the `quilt setup` runs without any isolation on the host in the calling user's context. As it turns out this operation easily allows to execute code in the following ways:
- The statements in the `%prep` section of the RPM spec file are unconditionally executed in the context of the calling user. - Arbitrary flags can be passed to `patch` via `%define _default_patch_flags ...` in the spec file. By embedding semicolons into the flags also arbitrary commands can be injected this way. - By combining the available vectors, difficult to spot malicious code can be hidden in RPM spec files. For example patch can be caused to follow symlinks, thereby "patching" files in a user's home directory as demonstrated in [1].
A demonstration works like this:
```sh $ osc co home:mgerstner/surprise $ cd home:mgerstner/surprise $ quilt setup surprise.spec # notice the surprise $ bash ```
We have posted about this on the oss-security mailing list [2] to start a discussion about possible countermeasures. A first aid could be to run the `quilt setup` inside a docker container or in a similar isolated environment. We are currently testing isolation of quilt with nsjail [3]. nsjail RPMs are available for Leap 15 and Tumbleweed from its devel project [4]. It is currently not found in Factory/Leap directly. Via the wrapper "squilt" [5], nsjail is utilized to confine quilt to read only the files it needs and is only able to write in the current directory. According to our initial testing it can be used as a drop in replacement and should reduce the attack surface significantly.
Our foremost intent is to make you aware of this so you don't run `quilt setup` unsuspectingly on untrusted packages that did not go through review. Furthermore to make you aware of how malicious code that targets this can be embedded in spec files and patches. This should be taken into account when reviewing package submissions.
If you have any questions or suggestions then please let's start a discussion.
So for my Fedora and openSUSE packages, I always use Mock[0] for my workflow. Classically, Mock used chroot(), but nowadays it uses systemd-nspawn for secure container environments. Mock provides a feature in which it can run just run the prep stage and then I can install packages into the environment and work from within there. My workflow is often something like the following: $ rpmbuild -bs <package>.spec $ mock -r opensuse-tumbleweed clean $ mock -r opensuse-tumbleweed --short-circuit=prep <package>.src.rpm $ mock -r opensuse-tumbleweed --install nano emacs-nox $ mock -r opensuse-tumbleweed --shell [ ... do stuff in the nspawn container ... ] $ mock -r opensuse-tumbleweed --copyout /builddir/build/SOURCES/* . $ mock -r opensuse-tumbleweed --copyout /builddir/build/SPECS/* . This doesn't appear to be available with "osc", so I ported mock to openSUSE[1] for my use. Unfortunately, the lack of usermode[2] in Factory keeps me from cleaning it up and submitting it to Factory. [0]: https://github.com/rpm-software-management/mock [1]: https://build.opensuse.org/package/show/home:Pharaoh_Atem:SUSE_mock/mock [2]: https://build.opensuse.org/package/show/security:SELinux/usermode -- 真実はいつも一つ!/ Always, there's only one truth! -- To unsubscribe, e-mail: opensuse-packaging+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse-packaging+owner@opensuse.org
Hello, Am Donnerstag, 27. September 2018, 18:09:12 CEST schrieb Matthias Gerstner:
the SUSE security team wants to draw your attention to a potential security threat involving the use of `quilt setup ...` on untrusted RPM spec files. [...] - The statements in the `%prep` section of the RPM spec file are unconditionally executed in the context of the calling user. - Arbitrary flags can be passed to `patch` via `%define _default_patch_flags ...` in the spec file. By embedding semicolons into the flags also arbitrary commands can be injected this way. - By combining the available vectors, difficult to spot malicious code can be hidden in RPM spec files. For example patch can be caused to follow symlinks, thereby "patching" files in a user's home directory as demonstrated in [1].
I'd like to add that code can also be executed via %define, for example %define apache_module_path %(/usr/sbin/apxs2 -q LIBEXECDIR) This %define will also run as part of quilt setup.
A demonstration works like this:
```sh $ osc co home:mgerstner/surprise $ cd home:mgerstner/surprise $ quilt setup surprise.spec # notice the surprise $ bash ```
My latest test doesn't show any surprise when starting bash. Maybe the reason is that I just created an AppArmor profile for quilt? ;-) I'll paste it below - if you want to use it, save it as /etc/apparmor.d/usr.bin.quilt Then adjust @{packages_dir} and run rcapparmor reload Notes: - you'll HAVE TO adjust @{packages_dir} to your needs - it has to be set to the directory where you run osc co - write access is restricted to - *.diff, *.diff~, *.patch, *.patch~ - the directory with the extracted tarball - tempfiles in /tmp/ and /var/tmp/ Note that quilt could modify files of another package in @{packages_dir} matching the above patterns, so there's no perfect protection. - I only tested the quilt commands I typically use - setup, push, pop, edit, refresh - all tests were done using the apparmor package (which includes the %define quoted above - that's also the reason why the profile allows reading a file in /usr/share/apache2/) - other packages might need other / more permissions - you can update the profile with aa-logprof Questions and feedback welcome - maybe we can even come up with a profile that is good enough for everybody, and ship that as part of the quilt rpm ;-) That all said - here's my AppArmor profile for quilt: # --------------------------------------------------------------------- # packages directory # expected layout is @{packages_dir}/$project/$package/ # so set it to the directory where you run osc co @{packages_dir} = /home/cb/packages/ #include <tunables/global> /usr/bin/quilt { #include <abstractions/base> #include <abstractions/bash> #include <abstractions/consoles> #include <abstractions/perl> /bin/bash mrix, /etc/host.conf r, /etc/magic r, /etc/resolv.conf r, /etc/rpm/ r, /etc/rpm/* r, /etc/vimrc r, /proc/filesystems r, /run/nscd/db* r, /usr/bin/* mrix, # [1] /usr/lib*/python*/**.so mr, /usr/lib*/ruby/**.so mr, /usr/lib/sysimage/rpm/Packages rk, /usr/share/apache2/build/config_vars.mk r, /usr/share/misc/magic.mgc r, /usr/share/quilt/ r, /usr/share/quilt/** r, /usr/share/quilt/scripts/* mrix, /usr/share/vim/** r, /var/lib/nscd/group r, /var/lib/nscd/passwd r, owner /home/*/.exrc r, owner /home/*/.quiltrc r, owner /home/*/.vim/** r, owner /home/*/.viminfo rw, owner /home/*/.viminfx.tmp rw, owner /home/*/.vimrc r, owner /proc/*/fd/ r, owner /proc/*/maps r, owner /tmp/* rw, owner /var/tmp/quilt??????/ rw, owner /var/tmp/quilt??????/* rw, owner /var/tmp/quilt??????/bin/ rw, owner /var/tmp/quilt??????/bin/* w, owner /var/tmp/quilt??????/build/ rw, owner /var/tmp/quilt??????/build/** rw, owner /var/tmp/rpm-tmp.?????? rw, owner @{packages_dir}/** r, owner @{packages_dir}/*/*/*.diff rw, owner @{packages_dir}/*/*/*.diff~ rw, owner @{packages_dir}/*/*/*.patch rw, owner @{packages_dir}/*/*/*.patch~ rw, owner @{packages_dir}/*/*/*/ rw, owner @{packages_dir}/*/*/*/** rwl, } # --------------------------------------------------------------------- Regards, Christian Boltz [1] in case you wonder why I allow /usr/bin/* mrix - the first reason is that the profile is restrictive enough to do that, and the second reason is that there's a very big (and never-ending) list of binaries that need to be executed. I stopped at # /usr/bin/apr-1-config mrix, # /usr/bin/apu-1-config mrix, # /usr/bin/apxs mrix, # /usr/bin/cat mrix, # /usr/bin/chmod mrix, # /usr/bin/cmp mrix, # /usr/bin/column mrix, # /usr/bin/cp mrix, # /usr/bin/date mrix, # /usr/bin/diff mrix, # /usr/bin/file mrix, # /usr/bin/find mrix, # /usr/bin/gawk mrix, # /usr/bin/getopt mrix, # /usr/bin/grep mrix, # /usr/bin/gzip mrix, # /usr/bin/head mrix, # /usr/bin/ln mrix, # /usr/bin/md5sum mrix, # /usr/bin/mkdir mrix, # /usr/bin/mktemp mrix, # /usr/bin/mv mrix, # /usr/bin/patch mrix, # /usr/bin/python3.[0-9] mrix, # /usr/bin/quilt r, # /usr/bin/rm mrix, # /usr/bin/rpm mrix, # /usr/bin/rpmbuild mrix, # /usr/bin/ruby mrix, # /usr/bin/sed mrix, # /usr/bin/sort mrix, # /usr/bin/stat mrix, # /usr/bin/tail mrix, # /usr/bin/tar mrix, # /usr/bin/touch mrix, # /usr/bin/tr mrix, # /usr/bin/vim-nox11 mrix, # /usr/bin/xargs mrix, --
good luck, Usually "good luck" is going together with "as I told you before" :) [> Greg KH and Johannes Nohl in opensuse-project]
-- To unsubscribe, e-mail: opensuse-packaging+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse-packaging+owner@opensuse.org
participants (5)
-
Christian Boltz
-
Cristian Rodríguez
-
Johannes Segitz
-
Matthias Gerstner
-
Neal Gompa