by default, ansible try to create a ControlMaster file in a predictible location in /tmp. This is vulnerable to a ssh socket injection attack like this : ~ $ sudo ln -s /tmp/ansible-ssh-elspeth.example.org-22-misc /tmp/ansible-ssh-sisay.example.org-22-misc ~ $ ansible -i 'elspeth.example.org,sisay.example.org' all -m shell -u misc -a hostname elspeth.example.org | success | rc=0 >> elspeth.example.org sisay.example.org | success | rc=0 >> elspeth.example.org I also did a test without using root, that's the same. Based on this attack, someone could divert the ssh connexion to another server, make it connect to a server under the control of attacker, and steal configuration file ( with passwords ), or steal password with a fake sudo ( since ansible can also use sudo ) Please note that you need to : - disable selinux # setenforce 0 - disable latest protection from the kernel # sysctl -w fs.protected_symlinks=0 # sysctl -w fs.protected_hardlinks=0 to make sure this work. I didn't found how/where ssh control the socket file for suitability, maybe it should I am not sure what could be a good fix. I do have a patch that put the socket in $XDG_RUNTIME_DIR but it is a very weak mitigation technique that do not work on older platform such as RHEL 6. Another solution would be to make sure the socket is created in specific temporary directory, but this could make the software much slower. And checking if the socket exist first is prone to race condition. Upstream was not contacted yet, and plan to release 1.3 around 2 weeks. Issue is not public ( but quite easy to spot )
The issue is in https://github.com/ansible/ansible/blob/devel/lib/ansible/runner/connection_plugins/ssh.py#L59 Possible fix : commit d06eaae5fa32ae24e8076f846bdf3f04e6090384 Author: Michael Scherer <misc> Date: Sun Aug 18 13:19:01 2013 +0200 Try to mitigate symlink attacks on newer platform A attacker could pre create a socket in /tmp and so divert the ssh connexion to another server. However, newer platform are protected against this since kernel 3.10 and surely with a proper selinux policy. diff --git a/lib/ansible/runner/connection_plugins/ssh.py b/lib/ansible/runner/connection_plugins/ssh.py index abbffcf..be8289e 100644 --- a/lib/ansible/runner/connection_plugins/ssh.py +++ b/lib/ansible/runner/connection_plugins/ssh.py @@ -51,12 +51,15 @@ class Connection(object): self.common_args = [] extra_args = C.ANSIBLE_SSH_ARGS + control_path_dir = '/tmp' + if 'XDG_RUNTIME_DIR' in os.environ: + control_path_dir = os.environ['XDG_RUNTIME_DIR'] if extra_args is not None: self.common_args += shlex.split(extra_args) else: self.common_args += ["-o", "ControlMaster=auto", "-o", "ControlPersist=60s", - "-o", "ControlPath=/tmp/ansible-ssh-%h-%p-%r"] + "-o", "ControlPath=%s/ansible-ssh-%%h-%%p-%%r" % control_path_dir] if not C.HOST_KEY_CHECKING: self.common_args += ["-o", "StrictHostKeyChecking=no"]
Created attachment 787788 [details] better patch So here is a proper patch, using a temporary directory shared during the playbook run. However, it could be written more cleanly without using global, and using proper object lifecycle, but I consider that being minor when compared to the security fix.
Hi, Michael. The best thing to do here would be to alert upstream to this. We can assign a CVE for this that you can pass along as well, and then we can open this bug up and get fixes into Fedora and EPEL6 once the issue is fixed upstream.
Acknowledgements: Red Hat would like to thank Michael Scherer for reporting this issue.
Michael, when you report this to upstream can you also note that it was assigned CVE-2013-4259? Thanks.
Yep, will do. I keep you in CC to see how we organize the embargo, if upstream want one.
Created ansible tracking bugs for this issue: Affects: fedora-all [bug 999621]
This is public now: https://groups.google.com/forum/#!topic/ansible-project/UVDYW0HGcNg
Created ansible tracking bugs for this issue: Affects: epel-6 [bug 1001454]
ansible-1.2.3-2.el6 has been pushed to the Fedora EPEL 6 stable repository. If problems still persist, please make note of it in this bug report.
ansible-1.2.3-2.fc18 has been pushed to the Fedora 18 stable repository. If problems still persist, please make note of it in this bug report.
ansible-1.2.3-2.fc19 has been pushed to the Fedora 19 stable repository. If problems still persist, please make note of it in this bug report.