Forked from Snyk
A vulnerable demo application, initially based on Ben Hassine's TodoMVC.
The goal of this application is to demonstrate through example how to find, exploit and fix vulnerable Maven packages.
This repo is still incomplete, a work in progress to support related presentations.
- NOTE - ONLY tested on Amazon Linux 2 AMI (HVM), SSD Volume Type, T2 medium
- In env_vars.sh set DATADOG_APP_KEY, DATADOG_API_KEY and SNYK_TOKEN snyk - you will need an API key
- To configure the vm and start the webapp run
sh setup.shfrom the root directory - Once the webapp is up, you can access is at FQDN:8080 (8080 will need to be open for external access) and login with [email protected] / foobar
- You can then go to the Datadog app and look at the traces coming in and the profiles (after a few minutes). In the profiles, at first, you will see "None Detected" under the "Vulnerability Severity" column.
- Now we are set to exploit the application.
- In a shell, execute
export DOMAIN_NAME=<domain_name>where <domain_name> is either localhost or the FQDN of the host (8080 will need to be open for external access) - The first exploit - change permission on a root Java binary. The reference
used for this is the following webinar
hosted by Snyk and Datadog. This uses a vulnerability in struts that allows
shell commands on the host that is running the webapp. In the repo root,
execute
vi exploits/struts-exploit-headers.txtThis is a multipart/form-data header that struts understands and allows the execution of a shell command. Next,vi exploits/struts-exploit.shand let's take a look at the shell code. It uses sed to replace COMMAND with chown to change the permissions of the native2ascii binary in the JVM. This is the method of exploit that was used in the Experian attack. Execute it withcd exploits && sh struts-exploit.shRun it a few times to ensure it is not sampled out and then you can stop here if you want. When you see a profile with "Critical" in the "Vulnerability Severity" column click in then go to "Analysis" and you can see the struts expoit. You can also change the command in struts-exploit.sh (e.g printenv and you can see API keys etc. - nice way to show benefits of using a container for example). - Next we will exploit the app from UI using the zip-slip vulnerability. The
reference I used is from
a Snyk research post and a
webinar included on the page.
This uses Java code that does not check directory structure when unpacking a
zip file. It takes the user up 20 levels of ../ (if you hit root you will
keep traversing back to root) then we traverse to the JVM directory to
overwrite the native2ascii binary with our own binary and executable code. In
the application go to
FQDN:8080/todo/newand create a few todos. Then click the link for 'Upload Files' and upload zip-slip-datadog_example.zip Now click 'My Files' and you will seeroot_of_repo/publicand one file, good.txt. The new native2ascii binary will overwrite the Java binary by traversing the host directory structure outside of the upload (public) directory. This is possible because we changed the owner of the file with the last exploit. Now add another todo and you will see Gotcha! instead of your todo as we have executed code using our binary in the the webapp. The code that is exploited is in todolist-core/src/main/java/io/github/todolist/core/domain/Todo.java
import static io.github.todolist.core.Statics.NATIVE2ASCII;sets the JDK location if$JAVA_HOMEis unset. We set it in env_vars.sh The method that is exploited ispublic Todo(...)Add three of four todos to ensure sampling does not exclude the run in a profile and in a few minutes you should see Critical in the "Vulnerability Severity" column. Click into the profile and then go into Analysis and you will see a struts or hibernate vulnerability. - Enjoy!
The Datadog part of this uses the Datadog agent, Datadog Java APM, the Datadog continuous profiler and the Datadog Snyk integration.
The configuration is as follows:
- Install the agent - done in setup.sh in the line beginning with
DD_AGENT_MAJOR_VERSION - Pull down the tracer - done in setup.sh in the line beginning with
wget - Inject the tracer and system properties in the JAVA_OPTS. Done via
source env_vars.sh
- MAVEN_OPTS="-javaagent:dd-java-agent.jar -Ddd.profiling.enabled=true -XX:FlightRecorderOptions=stackdepth=256 -Ddd.service=javagoof -Ddd.env=lab -Ddd.version=.01"
- -javaagent:dd-java-agent.jar - add the tracer
- -Ddd.profiling.enabled=true -XX:FlightRecorderOptions=stackdepth=256 - add the profiler
- Unified Service Tagging -
- -Ddd.service=javagoof - add the service
- -Ddd.env=lab - add the environment
- -Ddd.version=.01 - add the version
- Authenticate to Snyk - done in setup.sh in the line beginning with
snyk auth - Generate the dependency graph - done in setup.sh in the line beginning
with
snyk test- note we use the pom rather than package.json - Upload the dependency graph to Datadog in setup.sh in the line beginning
with
node_modules/.bin/datadog-ci- note the service and version must match that for the profile.
- MAVEN_OPTS="-javaagent:dd-java-agent.jar -Ddd.profiling.enabled=true -XX:FlightRecorderOptions=stackdepth=256 -Ddd.service=javagoof -Ddd.env=lab -Ddd.version=.01"
Now that Datadog any Snyk have detected a critical runtime vulnerability, we
should alert the team. This can be done using Datadog
Synthetics, specifically Datadog's
Browser Testing.
There can be a cat/mouse issue because you are trying to login to Datadog in
the test while you are using the app. Therefore, it will be necessary to
use incognito mode. The documentation for this is
here. The steps for the test are as follow:
- Create two global variables to use for username/password (obfuscated) to login to Datadog using a test account
- Start recording
- Go to incognito mode
- Populate username/password using the variables
- Navigate to the profile page with the following KV pairs:
- Service:service - for this is javagoof
- Env:env - for this is lab
- Version:version - for this is .01
- @metrics.core_vulns_severity_max:critical (can be found in the facts by searching for vuln and clicking Highest Severity then Critical)
- Test that the following text is present on the page "showing 0 profiles"
- Finish configuring it and you are set to be alerted
(from the original README)
Note that to run locally, you need JDK 8.
- Check out the project source code from github :
git clone https://github.com/snyk/java-goof.git - Open a terminal and run the following command from root directory :
mvn install - Choose a web framework to test and run it. For example :
cd todolist-web-struts && mvn tomcat7:run(note: this example currently only copied the Struts demo) - Browse the following URL :
localhost:8080/ - You can register a new account or login using the following credentials : [email protected] / foobar
docker-compose up --build
docker-compose downThis repo is available released under the MIT License.