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 withpython sqlmap.py
. - So this has potential. Quickly show the code with a focus on the string concatenation and
mysqli_multi_query
. - 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
DELETE
orDROP
data for example with;DROP TABLE employees
, which doesn't work since our connection only allowsSELECT
orINSERT
. - Point to https://xeraa.wtf:8080, which is using the same code but runs on Apache and ModSecurity instead of nginx.
- Run
sqlmap --url "https://xeraa.wtf:8080/read.php?id=1" --purge
, which results in403 (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 therename
to themessage
field. - Show the custom rule in action by trying to add someone called
Shay Banon
or justShay
and show the log message. - But this isn't fully fool proof. For example
'(Or)1=1()
still allows you to skip the login form.
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_ACCESS_KEY_ID
andAWS_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
and set the environment variables with the values forELASTICSEARCH_HOST
,ELASTICSEARCH_USER
,ELASTICSEARCH_PASSWORD
, as well asKIBANA_HOST
,KIBANA_ID
. - 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 init
first. Then create the keypair, DNS settings, and instances withterraform apply
. - Apply the configuration to the instance with
ansible-playbook configure.yml
and then deploy withansible-playbook deploy.yml
.
When you are done, remove the instances, DNS settings, and key with terraform destroy
.
- Add file inclusion (local or remote) trickery?
- Add cookie trickery?