martin carpenter

contents

most popular
2012/05/05, updated 2012/12/15
Ubuntu unity lens for vim
2010/04/14
ckwtmpx

escape from ansible

2015/07/01

tags: Ansible vulnerability

summary

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 shutil.copyfile()) was vulnerable to a straightforward symlink attack, allowing a malicious process in the sub-environment to write to the filesystem at the higher level.

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, zlogin(1), 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. Oops.

Given that we can assume that the local zone attacker has (local) root I wrote a simple PoC leveraging FUSE (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 (umount(2) with MS_FORCE) 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 underlying filesystem.

This, then, was the strategy:

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...

timeline