ModSecurity & Logging
Demo code for the talk Hands-On ModSecurity and Logging. This is insecure and generally bad code — only use it for demos and education on what not to do.
- Show https://xeraa.wtf and then focus on the login form https://xeraa.wtf/login.php. After a successful login, try it with
' or true --and a random password to skip the login form.
- Let's look at https://xeraa.wtf/read.php?id=1 — this looks potentially interesting, right?
- Validate the suspicion with
sqlmap --url "https://xeraa.wtf/read.php?id=1" --purge. This assumes you have installed sqlmap (for example with Homebrew), otherwise download and run it with
- So this has potential. Quickly show the code with a focus on the string concatenation and
- Exploit the bad code by attaching
;INSERT INTO employees (name) VALUES ('Bad Actor')to https://xeraa.wtf/read.php?id=1.
- Also we are not escaping the output, so
;INSERT INTO employees (name) VALUES ('<script>alert("Hello Friend")</script>')will add more fun to the demo.
- Dive into the logging by showing /var/log/app.log and then how Filebeat is collecting this information.
- In Kibana show the relevant parts either in Discover or the Log UI by filtering down to
application : "app".
- Try to
DROPdata for example with
;DROP TABLE employees, which doesn't work since our connection only allows
- Point to https://xeraa.wtf:8080, which is using the same code but runs on Apache and ModSecurity instead of nginx.
sqlmap --url "https://xeraa.wtf:8080/read.php?id=1" --purge, which results in
403 (Forbidden) - 134 times.
- Show the Apache Filebeat dashboard where you can see the blocked requests.
- Also show the raw ModSecurity logs by filtering to
application : "mod_security"and point out that JSON logging is the important configuration here as well as the
Make sure you have run this before the demo.
- Have your AWS account set up, access key created, and added as environment variables in
AWS_SECRET_ACCESS_KEY. Protip: Use https://github.com/sorah/envchain to keep your environment variables safe.
- Create the Elastic Cloud instance with the same version as specified in variables.yml's
elastic_version, enable Kibana as well as the GeoIP & user agent plugins, and set the environment variables with the values for
ELASTICSEARCH_PASSWORD, as well as
- Change the settings to a domain you have registered under Route53 in inventory, variables.tf, and variables.yml. Set the Hosted Zone for that domain and export the Zone ID under the environment variable
TF_VAR_zone_id. If you haven't created the Hosted Zone yet, you should set it up in the AWS Console first and then set the environment variable.
- If you haven't installed the AWS plugin for Terraform, get it with
terraform initfirst. Then create the keypair, DNS settings, and instances with
- Open HTTPS and TCP/8080 on the network configuration (waiting for this Terraform issue).
- Apply the configuration to the instance with
ansible-playbook configure.ymland then deploy with
When you are done, remove the instances, DNS settings, and key with
- Add custom ModSecurity rule — maybe filter out Shay in POST requests: https://www.digitalocean.com/community/tutorials/how-to-set-up-mod_security-with-apache-on-debian-ubuntu
- Add cookie trickery