ansible is a flexible configuration management tool. It can be used, in addition to managing standalone hosts via SSH (probably the most common use case), to manage Solaris zones, BSD jails or traditional UNIX chroots. All of these containers are intended to provide isolation from the containing host.
The mechanism used by ansible to copy
files into these sub-environments (using Python's
was vulnerable to a straightforward symlink attack, allowing a malicious
process in the sub-environment to write to the filesystem at the higher
For jails and chroots, which are less likely to be running a full
OS environment, this is perhaps less interesting. But for Solaris zones
this is bad not only because an attacker has a full OS at their
disposal but also because the mechanism used to access the local
zone by ansible,
mandates that the ansible zone plugin be invoked as
root from the global
zone. Thus an attacker wins write access to the global zone (or any other
sibling local zone) as root.
Given that we can assume that the local zone attacker
root I wrote a simple PoC leveraging
(again) as an easy way
to sychronize the attack without having to do any tricky nanosecond
estimation. (FUSE is new for Solaris 11). One neat thing I learnt:
one can force unmount a FUSE filesystem (
inside a FUSE call on that same filesystem before that call completes
so that the next file operation under the mount point hits the real
This, then, was the strategy:
copyfile()'s initial calls (
mknod(2), ...): "yeah, yeah, everything's fine" until the call immediately preceding the file write. Then, in that call:
write(2), and is tricked into scribbling over something it should not.
This was fixed promptly by the ansible team to invoke
dd(1) in the
local zone with
stdin piped in from the global zone. The security of
this depends on the existing OS-level zone protection. But if that is
busted, all bets are off...