├── doc ├── adminer.png ├── captcha-01.png ├── captcha-02.png ├── captcha-01-thumb.png └── captcha-02-thumb.png ├── .gitignore ├── aws ├── terraform.tfvars-example ├── outputs.tf ├── README.md ├── variables.tf ├── userdata.tpl ├── main.tf └── Makefile ├── .github ├── dependabot.yml ├── labels.yml ├── workflows │ ├── release-drafter.yml │ ├── repository.yml │ ├── action_pull_request.yml │ ├── action_schedule.yml │ ├── action_branch.yml │ ├── kubernetes.yml │ ├── terraform.yml │ └── params.yml └── release-drafter.yml ├── k8s ├── secret.yml ├── service-mysql.yml ├── configmap.yml ├── service-dvwa.yml ├── Makefile ├── README.md ├── deployment-mysql.yml └── deployment-dvwa.yml ├── docker ├── ctf │ └── README.md ├── config.inc.php ├── Dockerfile └── entrypoint.sh ├── LICENSE.md ├── docker-compose.yml ├── .env-example ├── Makefile └── README.md /doc/adminer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cytopia/docker-dvwa/master/doc/adminer.png -------------------------------------------------------------------------------- /doc/captcha-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cytopia/docker-dvwa/master/doc/captcha-01.png -------------------------------------------------------------------------------- /doc/captcha-02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cytopia/docker-dvwa/master/doc/captcha-02.png -------------------------------------------------------------------------------- /doc/captcha-01-thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cytopia/docker-dvwa/master/doc/captcha-01-thumb.png -------------------------------------------------------------------------------- /doc/captcha-02-thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cytopia/docker-dvwa/master/doc/captcha-02-thumb.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | Makefile.docker 2 | Makefile.lint 3 | 4 | tests/* 5 | 6 | .env 7 | aws/terraform.tfstate* 8 | aws/terraform.tfvars 9 | .terraform/ 10 | -------------------------------------------------------------------------------- /aws/terraform.tfvars-example: -------------------------------------------------------------------------------- 1 | listen_port = "8080" 2 | php_version = "8.1" 3 | 4 | instance_type = "t3.medium" 5 | 6 | tags = { 7 | Name = "DVWA" 8 | } 9 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: 2 3 | updates: 4 | # Maintain dependencies for GitHub Actions 5 | - package-ecosystem: "github-actions" 6 | directory: "/" 7 | schedule: 8 | interval: "daily" 9 | -------------------------------------------------------------------------------- /k8s/secret.yml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Secret 4 | metadata: 5 | name: dvwa-secrets 6 | type: Opaque 7 | data: 8 | ROOT_PASSWORD: czNyMDB0cGE1NQ== 9 | DVWA_USERNAME: ZHZ3YQ== 10 | DVWA_PASSWORD: cEBzc3dvcmQ= 11 | DVWA_DATABASE: ZHZ3YQ== 12 | -------------------------------------------------------------------------------- /k8s/service-mysql.yml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Service 4 | metadata: 5 | name: dvwa-mysql-service 6 | spec: 7 | selector: 8 | app: dvwa-mysql 9 | tier: backend 10 | ports: 11 | - protocol: TCP 12 | port: 3306 13 | targetPort: 3306 14 | -------------------------------------------------------------------------------- /k8s/configmap.yml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: ConfigMap 4 | metadata: 5 | name: dvwa-config 6 | data: 7 | RECAPTCHA_PRIV_KEY: "" 8 | RECAPTCHA_PUB_KEY: "" 9 | SECURITY_LEVEL: "low" 10 | PHPIDS_ENABLED: "0" 11 | PHPIDS_VERBOSE: "1" 12 | PHP_DISPLAY_ERRORS: "1" 13 | -------------------------------------------------------------------------------- /k8s/service-dvwa.yml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Service 4 | metadata: 5 | name: dvwa-web-service 6 | spec: 7 | selector: 8 | app: dvwa-web 9 | tier: frontend 10 | type: LoadBalancer 11 | ports: 12 | - protocol: TCP 13 | # Port accessible inside cluster 14 | port: 8081 15 | # Port to forward to inside the pod 16 | targetPort: 80 17 | -------------------------------------------------------------------------------- /.github/labels.yml: -------------------------------------------------------------------------------- 1 | # The labels in this file are automatically synced with the repository 2 | # using the micnncim/action-label-syncer action. 3 | --- 4 | - name: C-dependency 5 | color: 1abc9c 6 | description: "Category: Dependency" 7 | - name: PR-block 8 | color: 3498db 9 | description: "Pull Request: Do not merge" 10 | - name: PR-merge 11 | color: 3498db 12 | description: "Pull Request: Merge when ready" 13 | -------------------------------------------------------------------------------- /docker/ctf/README.md: -------------------------------------------------------------------------------- 1 | # CTF Challenges 2 | 3 | The [setup](setup) file in this directory contains obfuscated shell code to setup the CTF challenges inside the Docker image. 4 | 5 | You can verify that by looking at the [Dockerfile](../Dockerfile) and the file itself is not doing any harm, nor will it be run on your local machine. 6 | 7 | **I do recommend not to de-obfuscate it, as you will then have the answers for the challenges.** 8 | -------------------------------------------------------------------------------- /k8s/Makefile: -------------------------------------------------------------------------------- 1 | ifneq (,) 2 | .error This Makefile requires GNU Make. 3 | endif 4 | 5 | .PHONY: help lint_lint_files _lint_k8s _pull-tf _pull-tf-docs 6 | 7 | CURRENT_DIR = $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) 8 | 9 | help: 10 | @echo "lint Static source code analysis" 11 | 12 | lint: 13 | @$(MAKE) --no-print-directory _lint_k8s 14 | 15 | _lint_k8s: 16 | docker run --rm -v $(CURRENT_DIR):/data cytopia/kubeval *.yml 17 | -------------------------------------------------------------------------------- /aws/outputs.tf: -------------------------------------------------------------------------------- 1 | output "public_ip" { 2 | description = "Public IP address of EC2 instance containing DVWA web interface" 3 | value = aws_instance.web.public_ip 4 | } 5 | 6 | output "dvwa_web_uri" { 7 | description = "DVWA web interface uri" 8 | value = "http://${aws_instance.web.public_ip}:${var.listen_port}" 9 | } 10 | 11 | output "dvwa_ssh_uri" { 12 | description = "DVWA SSH uri" 13 | value = "ssh ubuntu@${aws_instance.web.public_ip}" 14 | } 15 | -------------------------------------------------------------------------------- /.github/workflows/release-drafter.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Release Drafter 3 | 4 | on: 5 | push: 6 | # branches to consider in the event; optional, defaults to all 7 | branches: 8 | - master 9 | 10 | jobs: 11 | update_release_draft: 12 | runs-on: ubuntu-latest 13 | steps: 14 | # Drafts your next Release notes as Pull Requests are merged into "master" 15 | - uses: release-drafter/release-drafter@v5 16 | with: 17 | publish: true 18 | env: 19 | GITHUB_TOKEN: ${{ secrets.RELEASE_DRAFTER_TOKEN }} 20 | -------------------------------------------------------------------------------- /.github/workflows/repository.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Repository 3 | 4 | on: 5 | push: 6 | branches: 7 | - master 8 | paths: 9 | - .github/labels.yml 10 | 11 | jobs: 12 | labels: 13 | name: Labels 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - name: Checkout code 18 | uses: actions/checkout@v3 19 | 20 | - name: Sync labels 21 | uses: micnncim/action-label-syncer@v1 22 | env: 23 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 24 | with: 25 | manifest: .github/labels.yml 26 | -------------------------------------------------------------------------------- /docker/config.inc.php: -------------------------------------------------------------------------------- 1 | 20 | -------------------------------------------------------------------------------- /.github/release-drafter.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name-template: '$RESOLVED_VERSION 🌈' 3 | tag-template: '$RESOLVED_VERSION' 4 | version-template: '$MAJOR.$MINOR' 5 | categories: 6 | - title: '🚀 Features' 7 | labels: 8 | - 'feature' 9 | - 'enhancement' 10 | - title: '🐛 Bug Fixes' 11 | labels: 12 | - 'fix' 13 | - 'bugfix' 14 | - 'bug' 15 | - title: '🧰 Maintenance' 16 | label: 'chore' 17 | change-template: '- $TITLE @$AUTHOR (#$NUMBER)' 18 | change-title-escapes: '\<*_&' # You can add # and @ to disable mentions, and add ` to disable code blocks. 19 | version-resolver: 20 | major: 21 | labels: 22 | - 'major' 23 | minor: 24 | labels: 25 | - 'minor' 26 | patch: 27 | labels: 28 | - 'patch' 29 | default: minor 30 | template: | 31 | ## Changes 32 | 33 | $CHANGES 34 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 cytopia 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: '2.4' 3 | 4 | services: 5 | 6 | dvwa_web: 7 | image: cytopia/dvwa:php-${PHP_VERSION:-8.1} 8 | restart: unless-stopped 9 | ports: 10 | - "${LISTEN_PORT:-8000}:80" 11 | networks: 12 | - dvwa-net 13 | environment: 14 | - RECAPTCHA_PRIV_KEY=${RECAPTCHA_PRIV_KEY:-} 15 | - RECAPTCHA_PUB_KEY=${RECAPTCHA_PUB_KEY:-} 16 | - SECURITY_LEVEL=${SECURITY_LEVEL:-medium} 17 | - PHPIDS_ENABLED=${PHPIDS_ENABLED:-0} 18 | - PHPIDS_VERBOSE=${PHPIDS_VERBOSE:-0} 19 | - PHP_DISPLAY_ERRORS=${PHP_DISPLAY_ERRORS:-0} 20 | - MYSQL_HOSTNAME=dvwa_db 21 | - MYSQL_DATABASE=dvwa 22 | - MYSQL_USERNAME=dvwa 23 | - MYSQL_PASSWORD=p@ssw0rd 24 | 25 | dvwa_db: 26 | image: mariadb:10.1 27 | hostname: dvwa_db 28 | volumes: 29 | - dvwa_db_data:/var/lib/mysql 30 | environment: 31 | MYSQL_ROOT_PASSWORD: rootpass 32 | MYSQL_DATABASE: dvwa 33 | MYSQL_USER: dvwa 34 | MYSQL_PASSWORD: p@ssw0rd 35 | restart: unless-stopped 36 | networks: 37 | - dvwa-net 38 | 39 | networks: 40 | dvwa-net: 41 | driver: bridge 42 | 43 | volumes: 44 | dvwa_db_data: 45 | -------------------------------------------------------------------------------- /.github/workflows/action_pull_request.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | # ------------------------------------------------------------------------------------------------- 4 | # Job Name 5 | # ------------------------------------------------------------------------------------------------- 6 | name: build 7 | 8 | 9 | # ------------------------------------------------------------------------------------------------- 10 | # When to run 11 | # ------------------------------------------------------------------------------------------------- 12 | on: 13 | pull_request: 14 | 15 | 16 | jobs: 17 | 18 | # (1/2) Determine repository params 19 | params: 20 | uses: ./.github/workflows/params.yml 21 | # Only run for forks (contributor) 22 | if: github.event.pull_request.head.repo.fork 23 | 24 | # (2/2) Build 25 | docker: 26 | needs: [params] 27 | uses: devilbox/github-actions/.github/workflows/docker-name-version-flavour-arch.yml@master 28 | with: 29 | enabled: true 30 | can_deploy: false 31 | matrix: ${{ needs.params.outputs.matrix }} 32 | refs: ${{ needs.params.outputs.refs }} 33 | secrets: 34 | dockerhub_username: "" 35 | dockerhub_password: "" 36 | -------------------------------------------------------------------------------- /.github/workflows/action_schedule.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | # ------------------------------------------------------------------------------------------------- 4 | # Job Name 5 | # ------------------------------------------------------------------------------------------------- 6 | name: nightly 7 | 8 | 9 | # ------------------------------------------------------------------------------------------------- 10 | # When to run 11 | # ------------------------------------------------------------------------------------------------- 12 | on: 13 | # Runs daily 14 | schedule: 15 | - cron: '0 0 * * *' 16 | 17 | 18 | jobs: 19 | 20 | # (1/2) Determine repository params 21 | params: 22 | uses: ./.github/workflows/params.yml 23 | 24 | # (2/2) Build 25 | docker: 26 | needs: [params] 27 | uses: devilbox/github-actions/.github/workflows/docker-name-version-flavour-arch.yml@master 28 | with: 29 | enabled: true 30 | can_deploy: true 31 | matrix: ${{ needs.params.outputs.matrix }} 32 | refs: ${{ needs.params.outputs.refs }} 33 | secrets: 34 | dockerhub_username: ${{ secrets.DOCKERHUB_USERNAME }} 35 | dockerhub_password: ${{ secrets.DOCKERHUB_PASSWORD }} 36 | -------------------------------------------------------------------------------- /aws/README.md: -------------------------------------------------------------------------------- 1 | # Terraform AWS DVWA 2 | 3 | This directory contains a Terraform module to deploy DVWA on AWS. 4 | 5 | 6 | ## Usage 7 | ```bash 8 | cp terraform.tfvars-example terraform.tfvars 9 | terraform init 10 | terraform plan 11 | terraform apply 12 | ``` 13 | 14 | 15 | ## Inputs 16 | 17 | | Name | Description | Type | Default | Required | 18 | |------|-------------|:----:|:-----:|:-----:| 19 | | instance\_type | AWS EC2 instance type to use for DVWA server | string | `"t3.nano"` | no | 20 | | listen\_port | Port for DVWA web interface | string | `"8080"` | no | 21 | | php\_version | PHP version to run DVWA | string | `"8.1"` | no | 22 | | public\_key | SSH public key to add | string | `""` | no | 23 | | tags | Tags to add to all resources | map | `{ "Name": "dvwa" }` | no | 24 | | vpc\_cidr | VPC CIDR | string | `"10.0.0.0/16"` | no | 25 | | vpc\_subnet\_cidr | Subnet CIDR | string | `"10.0.1.0/24"` | no | 26 | 27 | ## Outputs 28 | 29 | | Name | Description | 30 | |------|-------------| 31 | | dvwa\_ssh\_uri | DVWA SSH uri | 32 | | dvwa\_web\_uri | DVWA web interface uri | 33 | | public\_ip | Public IP address of EC2 instance containing DVWA web interface | 34 | 35 | 36 | -------------------------------------------------------------------------------- /aws/variables.tf: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------------------------------- 2 | # DVWA 3 | # -------------------------------------------------------------------------------------------------- 4 | variable "listen_port" { 5 | description = "Port for DVWA web interface" 6 | default = "8080" 7 | } 8 | 9 | variable "php_version" { 10 | description = "PHP version to run DVWA" 11 | default = "8.1" 12 | } 13 | 14 | variable "public_key" { 15 | description = "SSH public key to add" 16 | default = "" 17 | } 18 | 19 | # -------------------------------------------------------------------------------------------------- 20 | # INFRASTRUCTURE 21 | # -------------------------------------------------------------------------------------------------- 22 | variable "vpc_cidr" { 23 | description = "VPC CIDR" 24 | default = "10.0.0.0/16" 25 | } 26 | 27 | variable "vpc_subnet_cidr" { 28 | description = "Subnet CIDR" 29 | default = "10.0.1.0/24" 30 | } 31 | 32 | variable "instance_type" { 33 | description = "AWS EC2 instance type to use for DVWA server" 34 | default = "t3.nano" 35 | } 36 | 37 | variable "tags" { 38 | description = "Tags to add to all resources" 39 | default = { 40 | Name = "dvwa" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /k8s/README.md: -------------------------------------------------------------------------------- 1 | # Kubernetes deployment 2 | 3 | 4 | 5 | ## Minikube 6 | 7 | The following show-cases how to deploy everything locally on minikube. 8 | 9 | ### Start minikube 10 | ```bash 11 | minikube start 12 | ``` 13 | 14 | 15 | ### Make Loadbalancer work with minikube 16 | 17 | Retrieve the IP address minikube is running on 18 | ```bash 19 | $ minikube ip 20 | 192.168.49.2 21 | ``` 22 | 23 | Install metallb 24 | ```bash 25 | $ minikube addons enable metallb 26 | ``` 27 | 28 | Configure an IP address range for metallb, based on the minikube address found earlier. Just increment a few digits: 29 | ``` 30 | $ minikube addons configure metallb 31 | -- Enter Load Balancer Start IP: 192.168.49.10 32 | -- Enter Load Balancer End IP: 192.168.49.20 33 | ``` 34 | 35 | Verify 36 | ``` 37 | kubectl describe configmap config -n metallb-system 38 | ``` 39 | 40 | 41 | ### Deploy 42 | 43 | Ensure to be inside the `k8s/` directory of this repository. 44 | 45 | ```bash 46 | kubectl apply -f . 47 | ``` 48 | 49 | 50 | ### View 51 | 52 | Retrieve the load balancer URL 53 | ```bash 54 | $ kubectl get svc dvwa-web-service 55 | NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE 56 | dvwa-web-service LoadBalancer 10.102.127.193 192.168.49.10 8081:30434/TCP 78s 57 | ``` 58 | Then open http://192.168.49.10:8081 59 | -------------------------------------------------------------------------------- /.github/workflows/action_branch.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | # ------------------------------------------------------------------------------------------------- 4 | # Job Name 5 | # ------------------------------------------------------------------------------------------------- 6 | name: build 7 | 8 | 9 | # ------------------------------------------------------------------------------------------------- 10 | # When to run 11 | # ------------------------------------------------------------------------------------------------- 12 | on: 13 | push: 14 | paths: 15 | - 'Makefile' 16 | - 'docker/**' 17 | - 'docker-compose.yml' 18 | - 'tests/**' 19 | - '.github/workflows/action*.yml' 20 | - '.github/workflows/params.yml' 21 | 22 | jobs: 23 | 24 | # (1/2) Determine repository params 25 | params: 26 | uses: ./.github/workflows/params.yml 27 | 28 | # (2/2) Build 29 | docker: 30 | needs: [params] 31 | uses: devilbox/github-actions/.github/workflows/docker-name-version-flavour-arch.yml@master 32 | with: 33 | enabled: true 34 | can_deploy: ${{ github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/') || startsWith(github.ref, 'refs/heads/release-') }} 35 | matrix: ${{ needs.params.outputs.matrix }} 36 | refs: ${{ needs.params.outputs.refs }} 37 | secrets: 38 | dockerhub_username: ${{ secrets.DOCKERHUB_USERNAME }} 39 | dockerhub_password: ${{ secrets.DOCKERHUB_PASSWORD }} 40 | -------------------------------------------------------------------------------- /.env-example: -------------------------------------------------------------------------------- 1 | # PHP VERSION 2 | # ----------- 3 | # Uncomment one of the PHP versions you want to use for DVWA 4 | #PHP_VERSION=5.6 5 | #PHP_VERSION=7.0 6 | #PHP_VERSION=7.1 7 | #PHP_VERSION=7.2 8 | #PHP_VERSION=7.3 9 | #PHP_VERSION=7.4 10 | #PHP_VERSION=8.0 11 | PHP_VERSION=8.1 12 | 13 | 14 | LISTEN_PORT=8000 15 | # Local Listen Port 16 | # ----------------- 17 | LISTEN_PORT=8000 18 | 19 | 20 | # ReCAPTCHA settings 21 | # ------------------ 22 | # Used for the 'Insecure CAPTCHA' module 23 | # You'll need to generate your own keys at: https://www.google.com/recaptcha/admin 24 | RECAPTCHA_PRIV_KEY= 25 | RECAPTCHA_PUB_KEY= 26 | 27 | 28 | # Difficulty settings 29 | # ------------------- 30 | # Depending on the difficulty you want, set this to: 31 | # * low 32 | # * medium 33 | # * high 34 | # * impossible 35 | SECURITY_LEVEL=medium 36 | 37 | 38 | # Intrusion Detection settings 39 | # ---------------------------- 40 | # Enable PHP Web Application Firewall / Intrusion detection system 41 | # This will make the challenges harder. 42 | # Set to '1' (without quotes) to enable it 43 | PHPIDS_ENABLED=0 44 | 45 | # Enabling this will show why the WAF blocked the request on the blocked request. 46 | # Set to '1' (without quotes) to view blocked request reasons on the webpage 47 | PHPIDS_VERBOSE=0 48 | 49 | 50 | # Difficulty settings 51 | # ------------------- 52 | # By default PHP errors will not be visible on the page. 53 | # If this is too difficult, you can choose to enable the display of PHP errors. 54 | # Set the value to '1' (without quotes) and PHP errors will be displayed 55 | PHP_DISPLAY_ERRORS=0 56 | -------------------------------------------------------------------------------- /.github/workflows/kubernetes.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | # ------------------------------------------------------------------------------------------------- 4 | # Job Name 5 | # ------------------------------------------------------------------------------------------------- 6 | name: kubernetes 7 | 8 | 9 | # ------------------------------------------------------------------------------------------------- 10 | # When to run 11 | # ------------------------------------------------------------------------------------------------- 12 | on: 13 | # Runs on Pull Requests 14 | pull_request: 15 | 16 | # Runs on master Branch and Tags 17 | push: 18 | branches: 19 | - master 20 | tags: 21 | - '[0-9]+.[0-9]+*' 22 | 23 | 24 | # ------------------------------------------------------------------------------------------------- 25 | # What to run 26 | # ------------------------------------------------------------------------------------------------- 27 | jobs: 28 | kubernetes: 29 | name: Kubernetes 30 | runs-on: ubuntu-latest 31 | steps: 32 | 33 | # ------------------------------------------------------------ 34 | # Checkout repository 35 | # ------------------------------------------------------------ 36 | - name: Checkout repository 37 | uses: actions/checkout@v3 38 | with: 39 | fetch-depth: 0 40 | 41 | # ------------------------------------------------------------ 42 | # Tests 43 | # ------------------------------------------------------------ 44 | - name: Lint K8s files 45 | shell: bash 46 | run: | 47 | cd k8s/ 48 | make lint 49 | -------------------------------------------------------------------------------- /k8s/deployment-mysql.yml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | 5 | 6 | ### 7 | ### Deployment Metadata 8 | ### 9 | metadata: 10 | name: dvwa-mysql 11 | 12 | 13 | ### 14 | ### Specs 15 | ### 16 | spec: 17 | replicas: 1 18 | 19 | selector: 20 | matchLabels: 21 | app: dvwa-mysql 22 | tier: backend 23 | 24 | template: 25 | 26 | # Template Metadata to be used by service for discovery 27 | metadata: 28 | labels: 29 | app: dvwa-mysql 30 | tier: backend 31 | 32 | # Container/Volume definition 33 | spec: 34 | containers: 35 | - name: mysql 36 | image: mariadb:10.1 37 | ports: 38 | - containerPort: 3306 39 | volumeMounts: 40 | - name: dvwa-mysql-vol 41 | mountPath: /var/lib/mysql 42 | env: 43 | - name: MYSQL_ROOT_PASSWORD 44 | valueFrom: 45 | secretKeyRef: 46 | name: dvwa-secrets 47 | key: ROOT_PASSWORD 48 | - name: MYSQL_USER 49 | valueFrom: 50 | secretKeyRef: 51 | name: dvwa-secrets 52 | key: DVWA_USERNAME 53 | - name: MYSQL_PASSWORD 54 | valueFrom: 55 | secretKeyRef: 56 | name: dvwa-secrets 57 | key: DVWA_PASSWORD 58 | - name: MYSQL_DATABASE 59 | valueFrom: 60 | secretKeyRef: 61 | name: dvwa-secrets 62 | key: DVWA_DATABASE 63 | volumes: 64 | - name: dvwa-mysql-vol 65 | hostPath: 66 | path: "/var/lib/mysql" 67 | -------------------------------------------------------------------------------- /aws/userdata.tpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -eux 4 | set -o pipefail 5 | 6 | # -------------------------------------------------------------------------------------------------- 7 | # GLOBALS 8 | # -------------------------------------------------------------------------------------------------- 9 | RETRIES=20 10 | 11 | 12 | # -------------------------------------------------------------------------------------------------- 13 | # FUNCTIONS 14 | # -------------------------------------------------------------------------------------------------- 15 | retry() { 16 | for n in $(seq $${RETRIES}); do 17 | echo "[$${n}/$${RETRIES}] $${*}"; 18 | if eval "$${*}"; then 19 | echo "[SUCC] $${n}/$${RETRIES}"; 20 | return 0; 21 | fi; 22 | sleep 2; 23 | echo "[FAIL] $${n}/$${RETRIES}"; 24 | done; 25 | return 1; 26 | } 27 | 28 | 29 | # -------------------------------------------------------------------------------------------------- 30 | # ENTRYPOINT 31 | # -------------------------------------------------------------------------------------------------- 32 | 33 | ### 34 | ### Installation 35 | ### 36 | 37 | # Install Docker 38 | curl -fsSL https://get.docker.com | sh 39 | 40 | # Install Docker Compose 41 | curl -L "https://github.com/docker/compose/releases/download/1.24.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose 42 | chmod +x /usr/local/bin/docker-compose 43 | 44 | # Install git 45 | apt update; 46 | apt install -y git; 47 | 48 | # Install docker-dvwa 49 | git clone https://github.com/cytopia/docker-dvwa /tmp/docker-dvwa 50 | 51 | 52 | ### 53 | ### Configuration 54 | ### 55 | 56 | # Setup dvwa 57 | cd /tmp/docker-dvwa 58 | cp .env-example .env 59 | echo "PHP_VERSION=${php_version}" >> .env 60 | echo "LISTEN_PORT=${listen_port}" >> .env 61 | 62 | 63 | ### 64 | ### Run 65 | ### 66 | 67 | docker-compose up -d 68 | -------------------------------------------------------------------------------- /.github/workflows/terraform.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | # ------------------------------------------------------------------------------------------------- 4 | # Job Name 5 | # ------------------------------------------------------------------------------------------------- 6 | name: terraform 7 | 8 | 9 | # ------------------------------------------------------------------------------------------------- 10 | # When to run 11 | # ------------------------------------------------------------------------------------------------- 12 | on: 13 | # Runs on Pull Requests 14 | pull_request: 15 | 16 | # Runs on master Branch and Tags 17 | push: 18 | branches: 19 | - master 20 | tags: 21 | - '[0-9]+.[0-9]+*' 22 | 23 | 24 | # ------------------------------------------------------------------------------------------------- 25 | # What to run 26 | # ------------------------------------------------------------------------------------------------- 27 | jobs: 28 | terraform: 29 | name: Terraform 30 | runs-on: ubuntu-latest 31 | steps: 32 | 33 | # ------------------------------------------------------------ 34 | # Checkout repository 35 | # ------------------------------------------------------------ 36 | - name: Checkout repository 37 | uses: actions/checkout@v3 38 | with: 39 | fetch-depth: 0 40 | 41 | # ------------------------------------------------------------ 42 | # Tests 43 | # ------------------------------------------------------------ 44 | - name: Check Terraform documentation 45 | shell: bash 46 | run: | 47 | cd aws/ 48 | make gen 49 | git diff --quiet || { echo "Build Changes"; git diff; git status; false; }; 50 | 51 | - name: Lint Terraform files 52 | shell: bash 53 | run: | 54 | cd aws/ 55 | make lint 56 | 57 | - name: Test Terraform files 58 | shell: bash 59 | run: | 60 | cd aws/ 61 | make test 62 | -------------------------------------------------------------------------------- /k8s/deployment-dvwa.yml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | 5 | 6 | ### 7 | ### Deployment Metadata 8 | ### 9 | metadata: 10 | name: dvwa-web 11 | 12 | 13 | ### 14 | ### Specs 15 | ### 16 | spec: 17 | replicas: 1 18 | 19 | selector: 20 | matchLabels: 21 | app: dvwa-web 22 | tier: frontend 23 | 24 | template: 25 | 26 | # Template Metadata to be used by service for discovery 27 | metadata: 28 | labels: 29 | app: dvwa-web 30 | tier: frontend 31 | 32 | # Container/Volume definition 33 | spec: 34 | containers: 35 | - name: dvwa 36 | image: cytopia/dvwa:php-8.1 37 | ports: 38 | - containerPort: 80 39 | env: 40 | - name: RECAPTCHA_PRIV_KEY 41 | valueFrom: 42 | configMapKeyRef: 43 | name: dvwa-config 44 | key: RECAPTCHA_PRIV_KEY 45 | - name: RECAPTCHA_PUB_KEY 46 | valueFrom: 47 | configMapKeyRef: 48 | name: dvwa-config 49 | key: RECAPTCHA_PUB_KEY 50 | - name: SECURITY_LEVEL 51 | valueFrom: 52 | configMapKeyRef: 53 | name: dvwa-config 54 | key: SECURITY_LEVEL 55 | - name: PHPIDS_ENABLED 56 | valueFrom: 57 | configMapKeyRef: 58 | name: dvwa-config 59 | key: PHPIDS_ENABLED 60 | - name: PHPIDS_VERBOSE 61 | valueFrom: 62 | configMapKeyRef: 63 | name: dvwa-config 64 | key: PHPIDS_VERBOSE 65 | - name: PHP_DISPLAY_ERRORS 66 | valueFrom: 67 | configMapKeyRef: 68 | name: dvwa-config 69 | key: PHP_DISPLAY_ERRORS 70 | 71 | - name: MYSQL_HOSTNAME 72 | value: dvwa-mysql-service 73 | - name: MYSQL_DATABASE 74 | valueFrom: 75 | secretKeyRef: 76 | name: dvwa-secrets 77 | key: DVWA_DATABASE 78 | - name: MYSQL_USERNAME 79 | valueFrom: 80 | secretKeyRef: 81 | name: dvwa-secrets 82 | key: DVWA_USERNAME 83 | - name: MYSQL_PASSWORD 84 | valueFrom: 85 | secretKeyRef: 86 | name: dvwa-secrets 87 | key: DVWA_PASSWORD 88 | -------------------------------------------------------------------------------- /.github/workflows/params.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | # ------------------------------------------------------------------------------------------------- 4 | # Job Name 5 | # ------------------------------------------------------------------------------------------------- 6 | name: params 7 | 8 | 9 | # ------------------------------------------------------------------------------------------------- 10 | # Custom Variables 11 | # ------------------------------------------------------------------------------------------------- 12 | env: 13 | MATRIX: >- 14 | [ 15 | { 16 | "NAME": "dvwa", 17 | "VERSION": [ 18 | "latest", 19 | "8.1", 20 | "8.0", 21 | "7.4", 22 | "7.3", 23 | "7.2", 24 | "7.1", 25 | "7.0", 26 | "5.6" 27 | ], 28 | "FLAVOUR": ["latest"], 29 | "ARCH": ["linux/amd64", "linux/arm64"] 30 | } 31 | ] 32 | 33 | 34 | # ------------------------------------------------------------------------------------------------- 35 | # When to run 36 | # ------------------------------------------------------------------------------------------------- 37 | on: 38 | workflow_call: 39 | outputs: 40 | matrix: 41 | description: "The determined version matrix" 42 | value: ${{ jobs.params.outputs.matrix }} 43 | refs: 44 | description: "The determined git ref matrix (only during scheduled run)" 45 | value: ${{ jobs.params.outputs.refs }} 46 | 47 | jobs: 48 | params: 49 | runs-on: ubuntu-latest 50 | 51 | outputs: 52 | matrix: ${{ steps.set-matrix.outputs.matrix }} 53 | refs: ${{ steps.set-refs.outputs.matrix }} 54 | 55 | steps: 56 | - name: "[Set-Output] Matrix" 57 | id: set-matrix 58 | run: | 59 | echo "matrix=$( echo '${{ env.MATRIX }}' | jq -M -c )" >> $GITHUB_OUTPUT 60 | 61 | - name: "[Set-Output] Matrix 'Refs' (master branch and latest tag)" 62 | id: set-refs 63 | uses: cytopia/git-ref-matrix-action@v0.1.13 64 | with: 65 | repository_default_branch: master 66 | branches: master 67 | num_latest_tags: 0 68 | if: github.event_name == 'schedule' 69 | 70 | - name: "[DEBUG] Show settings'" 71 | run: | 72 | echo 'Matrix' 73 | echo '--------------------' 74 | echo '${{ steps.set-matrix.outputs.matrix }}' 75 | echo 76 | 77 | echo 'Matrix: Refs' 78 | echo '--------------------' 79 | echo '${{ steps.set-matrix-refs.outputs.matrix }}' 80 | echo 81 | -------------------------------------------------------------------------------- /docker/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG VERSION 2 | FROM php:${VERSION}-apache as builder 3 | 4 | # Install requirements 5 | RUN set -eux \ 6 | && apt-get update \ 7 | && apt-get install -y --no-install-recommends --no-install-suggests \ 8 | git \ 9 | ca-certificates \ 10 | && update-ca-certificates 11 | 12 | # Get DVWA 13 | RUN set -eux \ 14 | && git clone https://github.com/digininja/DVWA /DVWA \ 15 | && rm -rf /DVWA/.git \ 16 | && rm -rf /DVWA/.github \ 17 | && rm -rf /DVWA/.gitignore \ 18 | && rm -rf /DVWA/php.ini 19 | 20 | # Disable SQLITE 21 | RUN set -eux \ 22 | && sed -i'' "s/if (\$_DVWA\['SQLI_DB'\]/if ('no'/g" /DVWA/dvwa/includes/dvwaPage.inc.php \ 23 | && sed -i'' 's/[[:space:]]SQLITE)/"SQLITE")/g' /DVWA/dvwa/includes/dvwaPage.inc.php 24 | 25 | # Get Adminer 26 | RUN set -eux \ 27 | && URL="$( \ 28 | curl -sS --fail -k https://www.adminer.org/ \ 29 | | grep -Eo 'https://github.com/vrana/adminer/releases/download/v[.0-9]+/adminer-[.0-9]+-mysql-en.php' \ 30 | )" \ 31 | && curl -sS --fail -k -L "${URL}" > /adminer.php 32 | 33 | 34 | ARG VERSION 35 | FROM php:${VERSION}-apache 36 | 37 | # Satisfy PHP requirements 38 | RUN set -eux \ 39 | && apt-get update \ 40 | && apt-get install -y --no-install-recommends --no-install-suggests \ 41 | libpng-dev \ 42 | ca-certificates \ 43 | && update-ca-certificates \ 44 | && docker-php-ext-install gd \ 45 | && docker-php-ext-install mysqli \ 46 | && docker-php-ext-install pdo_mysql \ 47 | && apt-get clean \ 48 | && rm -rf /var/lib/apt/lists/* 49 | 50 | # Satisfy Application requirements 51 | RUN set -eux \ 52 | && apt-get update \ 53 | && apt-get install -y --no-install-recommends --no-install-suggests \ 54 | iputils-ping \ 55 | netcat \ 56 | python3 \ 57 | strace \ 58 | sudo \ 59 | telnet \ 60 | && apt-get clean \ 61 | && rm -rf /var/lib/apt/lists/* 62 | 63 | # Copy source 64 | COPY --from=builder /DVWA/ /var/www/html/ 65 | COPY --from=builder /adminer.php /var/www/html/adminer.php 66 | COPY ./config.inc.php /var/www/html/config/config.inc.php 67 | COPY ./entrypoint.sh/ /entrypoint.sh 68 | 69 | # Configure PHP 70 | RUN set -eux \ 71 | && { \ 72 | echo "allow_url_include = on"; \ 73 | echo "allow_url_fopen = on"; \ 74 | echo "error_reporting = E_ALL | E_STRICT"; \ 75 | echo "magic_quotes_gpc = off"; \ 76 | } > /usr/local/etc/php/conf.d/default.ini 77 | 78 | # Adjust permissions 79 | RUN set -eux \ 80 | && chown -R www-data:www-data /var/www/html \ 81 | && chmod 0775 /var/www/html/config/ \ 82 | && chmod 0775 /var/www/html/hackable/uploads/ \ 83 | && chmod 0775 /var/www/html/external/phpids/0.6/lib/IDS/tmp/ \ 84 | && chmod 0664 /var/www/html/external/phpids/0.6/lib/IDS/tmp/phpids_log.txt 85 | 86 | # Configure CTF challenges 87 | COPY ./ctf/setup /tmp/setup 88 | RUN set -eu \ 89 | && cmd="$(cat /tmp/setup)" \ 90 | && for i in $(seq 20); do cmd="$(echo "${cmd}" | base64 -d)"; done \ 91 | && echo "${cmd}" | sh 2>/dev/null \ 92 | && rm /tmp/setup 93 | 94 | CMD ["/entrypoint.sh"] 95 | -------------------------------------------------------------------------------- /aws/main.tf: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------------- 2 | # Networking Infrastructure 3 | # -------------------------------------------------------------------------------- 4 | resource "aws_vpc" "main" { 5 | cidr_block = var.vpc_cidr 6 | 7 | tags = var.tags 8 | } 9 | 10 | resource "aws_subnet" "main" { 11 | vpc_id = aws_vpc.main.id 12 | cidr_block = var.vpc_subnet_cidr 13 | 14 | tags = var.tags 15 | } 16 | 17 | resource "aws_internet_gateway" "igw" { 18 | vpc_id = aws_vpc.main.id 19 | tags = var.tags 20 | } 21 | 22 | # -------------------------------------------------------------------------------- 23 | # Networking Routing 24 | # -------------------------------------------------------------------------------- 25 | resource "aws_route_table" "main" { 26 | vpc_id = aws_vpc.main.id 27 | route { 28 | cidr_block = "0.0.0.0/0" 29 | gateway_id = aws_internet_gateway.igw.id 30 | } 31 | tags = var.tags 32 | } 33 | 34 | resource "aws_route_table_association" "main_rt_assoc" { 35 | subnet_id = aws_subnet.main.id 36 | route_table_id = aws_route_table.main.id 37 | } 38 | 39 | # -------------------------------------------------------------------------------- 40 | # Security 41 | # -------------------------------------------------------------------------------- 42 | resource "aws_security_group" "web" { 43 | name_prefix = "dvwa" 44 | vpc_id = aws_vpc.main.id 45 | 46 | ingress { 47 | from_port = 22 48 | to_port = 22 49 | protocol = "tcp" 50 | cidr_blocks = ["0.0.0.0/0"] 51 | } 52 | ingress { 53 | from_port = var.listen_port 54 | to_port = var.listen_port 55 | protocol = "tcp" 56 | cidr_blocks = ["0.0.0.0/0"] 57 | } 58 | egress { 59 | from_port = 0 60 | to_port = 0 61 | protocol = "-1" 62 | cidr_blocks = ["0.0.0.0/0"] 63 | } 64 | tags = var.tags 65 | 66 | lifecycle { 67 | create_before_destroy = true 68 | } 69 | } 70 | 71 | # -------------------------------------------------------------------------------- 72 | # EC2 instance 73 | # -------------------------------------------------------------------------------- 74 | 75 | resource "aws_key_pair" "web" { 76 | count = length(var.public_key) > 0 ? 1 : 0 77 | key_name = "dvwa-key" 78 | public_key = var.public_key 79 | } 80 | 81 | data "aws_ami" "ubuntu" { 82 | most_recent = true 83 | 84 | filter { 85 | name = "name" 86 | values = ["ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-*"] 87 | } 88 | 89 | filter { 90 | name = "virtualization-type" 91 | values = ["hvm"] 92 | } 93 | 94 | owners = ["099720109477"] # Canonical 95 | } 96 | 97 | data "template_file" "user_data" { 98 | template = file("${path.module}/userdata.tpl") 99 | 100 | vars = { 101 | listen_port = var.listen_port 102 | php_version = var.php_version 103 | } 104 | } 105 | 106 | resource "aws_instance" "web" { 107 | ami = data.aws_ami.ubuntu.id 108 | instance_type = var.instance_type 109 | 110 | key_name = length(var.public_key) > 0 ? aws_key_pair.web[0].key_name : null 111 | 112 | user_data = data.template_file.user_data.rendered 113 | 114 | associate_public_ip_address = true 115 | vpc_security_group_ids = [aws_security_group.web.id] 116 | subnet_id = aws_subnet.main.id 117 | 118 | tags = var.tags 119 | } 120 | -------------------------------------------------------------------------------- /docker/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | set -u 4 | 5 | 6 | ### 7 | ### Sane defaults 8 | ### 9 | DEF_RECAPTCHA_PRIV_KEY="" 10 | DEF_RECAPTCHA_PUB_KEY="" 11 | DEF_SECURITY_LEVEL="medium" 12 | DEF_PHP_DISPLAY_ERRORS="0" 13 | DEF_PHPIDS_ENABLED="disabled" 14 | DEF_PHPIDS_VERBOSE="false" 15 | 16 | 17 | ### 18 | ### Check for required env variables 19 | ### 20 | if ! env | grep '^MYSQL_HOSTNAME=' >/dev/null; then 21 | >&2 printf "[ERROR] MYSQL_HOSTNAME env variable is not set, but required\\n" 22 | exit 1 23 | fi 24 | if ! env | grep '^MYSQL_DATABASE=' >/dev/null; then 25 | >&2 printf "[ERROR] MYSQL_DATABASE env variable is not set, but required\\n" 26 | exit 1 27 | fi 28 | if ! env | grep '^MYSQL_USERNAME=' >/dev/null; then 29 | >&2 printf "[ERROR] MYSQL_USERNAME env variable is not set, but required\\n" 30 | exit 1 31 | fi 32 | if ! env | grep '^MYSQL_PASSWORD=' >/dev/null; then 33 | >&2 printf "[ERROR] MYSQL_PASSWORD env variable is not set, but required\\n" 34 | exit 1 35 | fi 36 | 37 | 38 | ### 39 | ### Summon env variables 40 | ### 41 | if env | grep '^RECAPTCHA_PRIV_KEY=' >/dev/null; then 42 | DEF_RECAPTCHA_PRIV_KEY="${RECAPTCHA_PRIV_KEY}" 43 | fi 44 | if env | grep '^RECAPTCHA_PUB_KEY=' >/dev/null; then 45 | DEF_RECAPTCHA_PUB_KEY="${RECAPTCHA_PUB_KEY}" 46 | fi 47 | if env | grep '^SECURITY_LEVEL=' >/dev/null; then 48 | DEF_SECURITY_LEVEL="${SECURITY_LEVEL}" 49 | fi 50 | if env | grep '^PHP_DISPLAY_ERRORS=' >/dev/null; then 51 | DEF_PHP_DISPLAY_ERRORS="${PHP_DISPLAY_ERRORS}" 52 | fi 53 | if env | grep '^PHPIDS_ENABLED=' >/dev/null; then 54 | DEF_PHPIDS_ENABLED="${PHPIDS_ENABLED}" 55 | if [ "${PHPIDS_ENABLED}" = "0" ]; then 56 | DEF_PHPIDS_ENABLED="disabled" 57 | fi 58 | if [ "${PHPIDS_ENABLED}" = "1" ]; then 59 | DEF_PHPIDS_ENABLED="enabled" 60 | fi 61 | fi 62 | if env | grep '^PHPIDS_VERBOSE=' >/dev/null; then 63 | if [ "${PHPIDS_VERBOSE}" = "0" ]; then 64 | DEF_PHPIDS_VERBOSE="false" 65 | fi 66 | if [ "${PHPIDS_VERBOSE}" = "1" ]; then 67 | DEF_PHPIDS_VERBOSE="true" 68 | fi 69 | fi 70 | 71 | 72 | ### 73 | ### Print settings 74 | ### 75 | >&2 printf "Setting PHP version: %s\\n" "$(php -v | grep ^PHP | head -1)" 76 | 77 | >&2 printf "Setting MySQL hostname: %s\\n" "${MYSQL_HOSTNAME}" 78 | >&2 printf "Setting MySQL database: %s\\n" "${MYSQL_DATABASE}" 79 | >&2 printf "Setting MySQL username: %s\\n" "${MYSQL_USERNAME}" 80 | >&2 printf "Setting MySQL password: %s\\n" "$( echo "${MYSQL_PASSWORD}" | sed 's/./*/g' )" 81 | 82 | >&2 printf "Setting Recaptcha priv key: %s\\n" "$( echo "${DEF_RECAPTCHA_PRIV_KEY}" | sed 's/./*/g' )" 83 | >&2 printf "Setting Recaptcha pub key: %s\\n" "$( echo "${DEF_RECAPTCHA_PUB_KEY}" | sed 's/./*/g' )" 84 | >&2 printf "Setting Security level: %s\\n" "${DEF_SECURITY_LEVEL}" 85 | >&2 printf "Setting PHP error display: %s\\n" "${DEF_PHP_DISPLAY_ERRORS}" 86 | >&2 printf "Setting PHP IDS state: %s\\n" "${DEF_PHPIDS_ENABLED}" 87 | >&2 printf "Setting PHP IDS verbosity: %s\\n" "${DEF_PHPIDS_VERBOSE}" 88 | 89 | 90 | ### 91 | ### Adjust settings 92 | ### 93 | { 94 | echo ""; 113 | } >> /var/www/html/config/config.inc.php 114 | 115 | if [ "${DEF_PHP_DISPLAY_ERRORS}" = "1" ]; then 116 | echo "display_errors = on" > /usr/local/etc/php/conf.d/errors.ini 117 | else 118 | echo "display_errors = off" > /usr/local/etc/php/conf.d/errors.ini 119 | fi 120 | 121 | 122 | ### 123 | ### Normal start 124 | ### 125 | exec apache2-foreground 126 | -------------------------------------------------------------------------------- /aws/Makefile: -------------------------------------------------------------------------------- 1 | ifneq (,) 2 | .error This Makefile requires GNU Make. 3 | endif 4 | 5 | .PHONY: help gen lint test _lint_files _lint_fmt _pull-tf _pull-tf-docs 6 | 7 | CURRENT_DIR = $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) 8 | TF_EXAMPLES = $(sort $(dir $(wildcard $(CURRENT_DIR)examples/*/))) 9 | TF_MODULES = $(sort $(dir $(wildcard $(CURRENT_DIR)modules/*/))) 10 | 11 | TF_VERSION = light 12 | TF_DOCS_VERSION = 0.6.0 13 | 14 | # Adjust your delimiter here or overwrite via make arguments 15 | DELIM_START = 16 | DELIM_CLOSE = 17 | 18 | help: 19 | @echo "gen Generate terraform-docs output and replace in all README.md's" 20 | @echo "lint Static source code analysis" 21 | @echo "test Integration tests" 22 | 23 | gen: _pull-tf-docs 24 | @echo "################################################################################" 25 | @echo "# Terraform-docs generate" 26 | @echo "################################################################################" 27 | @if docker run --rm \ 28 | -v $(CURRENT_DIR):/data \ 29 | -e DELIM_START='$(DELIM_START)' \ 30 | -e DELIM_CLOSE='$(DELIM_CLOSE)' \ 31 | cytopia/terraform-docs:$(TF_DOCS_VERSION) \ 32 | terraform-docs-replace-012 --sort-inputs-by-required --with-aggregate-type-defaults md README.md; then \ 33 | echo "OK"; \ 34 | else \ 35 | echo "Failed"; \ 36 | exit 1; \ 37 | fi 38 | 39 | lint: _pull-tf 40 | @$(MAKE) --no-print-directory _lint_files 41 | @$(MAKE) --no-print-directory _lint_fmt 42 | 43 | test: _pull-tf 44 | @$(foreach example,\ 45 | $(TF_EXAMPLES),\ 46 | DOCKER_PATH="/t/examples/$(notdir $(patsubst %/,%,$(example)))"; \ 47 | echo "################################################################################"; \ 48 | echo "# examples/$$( basename $${DOCKER_PATH} )"; \ 49 | echo "################################################################################"; \ 50 | echo; \ 51 | echo "------------------------------------------------------------"; \ 52 | echo "# Terraform init"; \ 53 | echo "------------------------------------------------------------"; \ 54 | if docker run -it --rm -v "$(CURRENT_DIR):/t" --workdir "$${DOCKER_PATH}" hashicorp/terraform:$(TF_VERSION) \ 55 | init \ 56 | -verify-plugins=true \ 57 | -lock=false \ 58 | -upgrade=true \ 59 | -reconfigure \ 60 | -input=false \ 61 | -get-plugins=true \ 62 | -get=true \ 63 | .; then \ 64 | echo "OK"; \ 65 | else \ 66 | echo "Failed"; \ 67 | docker run -it --rm -v "$(CURRENT_DIR):/t" --workdir "$${DOCKER_PATH}" --entrypoint=rm hashicorp/terraform:$(TF_VERSION) -rf .terraform/ || true; \ 68 | exit 1; \ 69 | fi; \ 70 | echo; \ 71 | echo "------------------------------------------------------------"; \ 72 | echo "# Terraform validate"; \ 73 | echo "------------------------------------------------------------"; \ 74 | if docker run -it --rm -v "$(CURRENT_DIR):/t" --workdir "$${DOCKER_PATH}" hashicorp/terraform:$(TF_VERSION) \ 75 | validate \ 76 | $(ARGS) \ 77 | .; then \ 78 | echo "OK"; \ 79 | docker run -it --rm -v "$(CURRENT_DIR):/t" --workdir "$${DOCKER_PATH}" --entrypoint=rm hashicorp/terraform:$(TF_VERSION) -rf .terraform/ || true; \ 80 | else \ 81 | echo "Failed"; \ 82 | docker run -it --rm -v "$(CURRENT_DIR):/t" --workdir "$${DOCKER_PATH}" --entrypoint=rm hashicorp/terraform:$(TF_VERSION) -rf .terraform/ || true; \ 83 | exit 1; \ 84 | fi; \ 85 | echo; \ 86 | ) 87 | 88 | _lint_files: 89 | @# Lint all non-binary files for trailing spaces 90 | @echo "################################################################################" 91 | @echo "# Lint files" 92 | @echo "################################################################################" 93 | @echo 94 | @echo "------------------------------------------------------------" 95 | @echo "# Trailing spaces" 96 | @echo "------------------------------------------------------------" 97 | find . -type f -not \( -path "*/.git/*" -o -path "*/.github/*" -o -path "*/.terraform/*" \) -print0 \ 98 | | xargs -0 -n1 grep -Il '' \ 99 | | tr '\n' '\0' \ 100 | | xargs -0 -n1 \ 101 | sh -c 'if [ -f "$${1}" ]; then if LC_ALL=C grep --color=always -inHE "^.*[[:blank:]]+$$" "$${1}";then false; else true; fi; fi' -- 102 | @echo 103 | @echo "------------------------------------------------------------" 104 | @echo "# Windows line feeds (CRLF)" 105 | @echo "------------------------------------------------------------" 106 | find . -type f -not \( -path "*/.git/*" -o -path "*/.github/*" -o -path "*/.terraform/*" \) -print0 \ 107 | | xargs -0 -n1 grep -Il '' \ 108 | | tr '\n' '\0' \ 109 | | xargs -0 -n1 \ 110 | sh -c 'if [ -f "$${1}" ]; then if file "$${1}" | grep --color=always -E "[[:space:]]CRLF[[:space:]].*line"; then false; else true; fi; fi' -- 111 | @echo 112 | @echo "------------------------------------------------------------" 113 | @echo "# Single trailing newline" 114 | @echo "------------------------------------------------------------" 115 | find . -type f -not \( -path "*/.git/*" -o -path "*/.github/*" -o -path "*/.terraform/*" \) -print0 \ 116 | | xargs -0 -n1 grep -Il '' \ 117 | | tr '\n' '\0' \ 118 | | xargs -0 -n1 \ 119 | sh -c 'if [ -f "$${1}" ]; then if ! (tail -c 1 "$${1}" | grep -Eq "^$$" && tail -c 2 "$${1}" | grep -Eqv "^$$"); then echo "$${1}"; false; else true; fi; fi' -- 120 | @echo 121 | 122 | _lint_fmt: 123 | @# Lint all Terraform files 124 | @echo "################################################################################" 125 | @echo "# Terraform fmt" 126 | @echo "################################################################################" 127 | @echo 128 | @echo "------------------------------------------------------------" 129 | @echo "# *.tf files" 130 | @echo "------------------------------------------------------------" 131 | @if docker run --rm -v "$(CURRENT_DIR):/t:ro" --workdir "/t" hashicorp/terraform:$(TF_VERSION) \ 132 | fmt -check=true -diff=true -write=false -list=true /t; then \ 133 | echo "OK"; \ 134 | else \ 135 | echo "Failed"; \ 136 | exit 1; \ 137 | fi; 138 | @echo 139 | @echo "------------------------------------------------------------" 140 | @echo "# *.tfvars files" 141 | @echo "------------------------------------------------------------" 142 | @if docker run --rm --entrypoint=/bin/sh -v "$(CURRENT_DIR)/terraform:/t:ro" hashicorp/terraform:$(TF_VERSION) \ 143 | -c "find . -name '*.tfvars' -type f -print0 | xargs -0 -n1 terraform fmt -check=true -write=false -diff=true -list=true"; then \ 144 | echo "OK"; \ 145 | else \ 146 | echo "Failed"; \ 147 | exit 1; \ 148 | fi; 149 | @echo 150 | 151 | _pull-tf: 152 | docker pull hashicorp/terraform:$(TF_VERSION) 153 | 154 | _pull-tf-docs: 155 | docker pull cytopia/terraform-docs:$(TF_DOCS_VERSION) 156 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ifneq (,) 2 | .error This Makefile requires GNU Make. 3 | endif 4 | 5 | # Ensure additional Makefiles are present 6 | MAKEFILES = Makefile.docker Makefile.lint 7 | $(MAKEFILES): URL=https://raw.githubusercontent.com/devilbox/makefiles/master/$(@) 8 | $(MAKEFILES): 9 | @if ! (curl --fail -sS -o $(@) $(URL) || wget -O $(@) $(URL)); then \ 10 | echo "Error, curl or wget required."; \ 11 | echo "Exiting."; \ 12 | false; \ 13 | fi 14 | include $(MAKEFILES) 15 | 16 | # Set default Target 17 | .DEFAULT_GOAL := help 18 | 19 | 20 | # ------------------------------------------------------------------------------------------------- 21 | # Default configuration 22 | # ------------------------------------------------------------------------------------------------- 23 | TAG = latest 24 | PHP_LATEST = 8.1 25 | 26 | NAME = dvwa 27 | IMAGE = cytopia/dvwa 28 | VERSION = latest 29 | DIR = docker 30 | FILE = Dockerfile 31 | 32 | 33 | # Building from master branch: Tag == 'latest' 34 | ifeq ($(strip $(TAG)),latest) 35 | ifeq ($(strip $(VERSION)),latest) 36 | PHP = $(PHP_LATEST) 37 | DOCKER_TAG = latest 38 | else 39 | PHP = $(VERSION) 40 | DOCKER_TAG = php-$(VERSION) 41 | endif 42 | # Building from any other branch or tag: Tag == '' 43 | else 44 | ifeq ($(strip $(VERSION)),latest) 45 | PHP = $(PHP_LATEST) 46 | DOCKER_TAG = latest-$(TAG) 47 | else 48 | PHP = $(VERSION) 49 | DOCKER_TAG = php-$(VERSION)-$(TAG) 50 | endif 51 | endif 52 | 53 | DOCKER_PULL_VARIABLES = "VERSION=$(PHP)" 54 | 55 | # -------------------------------------------------------------------------------------------------- 56 | # Default Target 57 | # -------------------------------------------------------------------------------------------------- 58 | .PHONY: help 59 | help: 60 | @echo "start Start docker-compose" 61 | @echo "stop Stop docker-compose" 62 | @echo "logs View web server access/error logs" 63 | @echo "reset Stop container, remove their state and the remove Docker volume" 64 | @echo "enter Enter the web server container" 65 | @echo "update Pull latest Docker images" 66 | 67 | # -------------------------------------------------------------------------------------------------- 68 | # User Targets 69 | # -------------------------------------------------------------------------------------------------- 70 | .PHONY: start 71 | start: .env 72 | @echo "Starting DVWA" 73 | docker-compose up -d 74 | docker-compose logs dvwa_web 2>&1 | grep "Setting" 75 | 76 | .PHONY: stop 77 | stop: 78 | @echo "Stopping DVWA" 79 | docker-compose down 80 | 81 | .PHONY: logs 82 | logs: 83 | docker-compose logs -f dvwa_web 84 | 85 | .PHONY: reset 86 | reset: 87 | @echo "Resetting DVWA and removing MySQL volumes" 88 | docker-compose kill 2> /dev/null || true 89 | docker-compose rm -f 2>/dev/null || true 90 | docker volume rm $(shell basename $(CURDIR))_dvwa_db_data 2> /dev/null || true 91 | @echo "Reset complete" 92 | 93 | .PHONY: enter 94 | enter: 95 | docker-compose exec -w /var/www/html dvwa_web bash 96 | 97 | .PHONY: update 98 | update: _update_web 99 | update: _update_db 100 | 101 | .PHONY: _update_web 102 | _update_web: 103 | docker-compose pull dvwa_web 104 | 105 | .PHONY: _update_db 106 | _update_db: 107 | docker-compose pull dvwa_db 108 | 109 | # Copy .env from .env-example if it does not exist (NO .PHONY) 110 | .env: 111 | cp .env-example .env 112 | 113 | 114 | # ------------------------------------------------------------------------------------------------- 115 | # Docker Targets 116 | # ------------------------------------------------------------------------------------------------- 117 | .PHONY: build 118 | build: ARGS+=--build-arg VERSION=$(PHP) 119 | build: docker-arch-build 120 | 121 | .PHONY: rebuild 122 | rebuild: ARGS+=--build-arg VERSION=$(PHP) 123 | rebuild: docker-arch-rebuild 124 | 125 | .PHONY: push 126 | push: docker-arch-push 127 | 128 | 129 | # ------------------------------------------------------------------------------------------------- 130 | # Manifest Targets 131 | # ------------------------------------------------------------------------------------------------- 132 | .PHONY: manifest-create 133 | manifest-create: docker-manifest-create 134 | 135 | .PHONY: manifest-push 136 | manifest-push: docker-manifest-push 137 | 138 | 139 | # ------------------------------------------------------------------------------------------------- 140 | # Test Targets 141 | # ------------------------------------------------------------------------------------------------- 142 | .PHONY: test 143 | test: _test-configure 144 | test: _test-start 145 | test: _test-available 146 | test: _test-ready 147 | test: _test-stop 148 | 149 | .PHONY: _test-configure 150 | _test-configure: 151 | @echo "#---------------------------------------------------------------------------------#" 152 | @echo "# [TESTING] Configure DVWA" 153 | @echo "#---------------------------------------------------------------------------------#" 154 | mkdir -p tests/ 155 | cp -f .env-example tests/.env 156 | cp -f docker-compose.yml tests/ 157 | sed -i'' "s|image: cytopia.*|image: $(IMAGE):$(DOCKER_TAG)|g" tests/docker-compose.yml 158 | echo "PHP_VERSION=${VERSION}" >> tests/.env 159 | @echo 160 | 161 | .PHONY: _test-start 162 | _test-start: 163 | @echo "#---------------------------------------------------------------------------------#" 164 | @echo "# [TESTING] Start DVWA" 165 | @echo "#---------------------------------------------------------------------------------#" 166 | cd tests && docker-compose up -d 167 | cd tests && docker-compose logs dvwa_web 2>&1 | grep "Setting" 168 | @echo 169 | 170 | .PHONY: _test-stop 171 | _test-stop: 172 | @echo "#---------------------------------------------------------------------------------#" 173 | @echo "# Stop DVWA" 174 | @echo "#---------------------------------------------------------------------------------#" 175 | cd tests && docker-compose down 176 | cd tests && docker-compose rm -f 177 | @echo 178 | 179 | .PHONY: _test-available 180 | _test-available: 181 | @echo "#---------------------------------------------------------------------------------#" 182 | @echo "# [TESTING] Check login: avail" 183 | @echo "#---------------------------------------------------------------------------------#" 184 | @echo "Waiting for login page to become available" 185 | @SUCCESS=0; \ 186 | for in in $$(seq 60); do \ 187 | printf "."; \ 188 | if [ "$$(curl -sS -o /dev/null -w '%{http_code}' http://localhost:8000/login.php)" = "200" ]; then \ 189 | SUCCESS=1; \ 190 | break; \ 191 | fi; \ 192 | sleep 1; \ 193 | done; \ 194 | if [ "$${SUCCESS}" != "1" ]; then \ 195 | cd tests && docker-compose logs; \ 196 | printf "\\nFAILED\\n"; \ 197 | exit 1; \ 198 | else \ 199 | printf "\\nSUCCESS\\n"; \ 200 | fi 201 | @echo 202 | 203 | .PHONY: _test-ready 204 | _test-ready: 205 | @echo "#---------------------------------------------------------------------------------#" 206 | @echo "# [TESTING] Check login: ready" 207 | @echo "#---------------------------------------------------------------------------------#" 208 | @echo "Testing for login page to become ready" 209 | @for in in $$(seq 60); do \ 210 | SUCCESS=0; \ 211 | printf "."; \ 212 | if ! curl -sS http://localhost:8000/login.php | grep -E 'Unable to connect|Cannot modify header|Undefined variable|Warning:|Notice:' >/dev/null; then \ 213 | SUCCESS=1; \ 214 | fi; \ 215 | if curl -sS http://localhost:8000/login.php | grep -E 'Damn Vulnerable Web Application' >/dev/null; then \ 216 | SUCCESS=$$(( SUCCESS + 1 )); \ 217 | fi; \ 218 | if [ "$${SUCCESS}" = "2" ]; then \ 219 | break; \ 220 | fi; \ 221 | sleep 1; \ 222 | done; \ 223 | if [ "$${SUCCESS}" != "2" ]; then \ 224 | cd tests && docker-compose logs; \ 225 | printf "\\nFAILED\\n"; \ 226 | exit 1; \ 227 | else \ 228 | printf "\\nSUCCESS\\n"; \ 229 | fi 230 | @echo 231 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Dockerized DVWA 2 | 3 | **[Install](#tada-install)** | 4 | **[Start](#zap-start)** | 5 | **[Stop](#no_entry_sign-stop)** | 6 | **[Usage](#computer-usage)** | 7 | **[Features](#star-features)** | 8 | **[Configuration](#wrench-configuration)** | 9 | **[Capture the flag](#pirate_flag-capture-the-flag)** | 10 | **[Tools](#gear-tools)** | 11 | **[FAQ](#bulb-faq)** | 12 | **[Sec Tools](#lock-cytopia-sec-tools)** | 13 | **[License](#page_facing_up-license)** 14 | 15 | [![Tag](https://img.shields.io/github/tag/cytopia/docker-dvwa.svg)](https://github.com/cytopia/docker-dvwa/releases) 16 | [![build](https://github.com/cytopia/docker-dvwa/workflows/build/badge.svg)](https://github.com/cytopia/docker-dvwa/actions?query=workflow%3Abuild) 17 | [![nightly](https://github.com/cytopia/docker-dvwa/workflows/nightly/badge.svg)](https://github.com/cytopia/docker-dvwa/actions?query=workflow%3Anightly) 18 | [![](https://img.shields.io/docker/pulls/cytopia/dvwa.svg)](https://hub.docker.com/r/cytopia/dvwa) 19 | [![](https://img.shields.io/badge/github-cytopia%2Fdocker--dvwa-red.svg)](https://github.com/cytopia/docker-dvwa "github.com/cytopia/docker-dvwa") 20 | [![License](https://img.shields.io/badge/license-MIT-%233DA639.svg)](https://opensource.org/licenses/MIT) 21 | 22 | > Damn Vulnerable Web Application (DVWA) is a PHP/MySQL web application that is damn vulnerable. Its main goal is to be an aid for security professionals to test their skills and tools in a legal environment, help web developers better understand the processes of securing web applications and to aid both students & teachers to learn about web application security in a controlled class room environment. 23 | > 24 | > https://github.com/digininja/DVWA 25 | 26 | [DVWA](https://github.com/digininja/DVWA) has an official Docker image available at [Dockerhub](https://hub.docker.com/r/vulnerables/web-dvwa/), however by the time of writing this image did not receive any recent updates. 27 | 28 | If you need an always up-to-date version or **`arm64`** images, you can use the here provided Docker Compose setup. The image is built every night against the latest master branch of the [DVWA](https://github.com/digininja/DVWA) and pushed to [Dockehub](https://hub.docker.com/r/cytopia/dvwa). 29 | 30 | Additionally this Docker image comes with a few **CTF challenges** that require you to completely compromise the machine and reach root access. [Read here](#pirate_flag-capture-the-flag) for details. 31 | 32 | 33 | **Available Architectures:** `amd64`, `arm64` 34 | 35 | 36 | 37 | ## :whale: Available Docker image versions 38 | 39 | [![](https://img.shields.io/docker/pulls/cytopia/dvwa.svg)](https://hub.docker.com/r/cytopia/dvwa) 40 | [![Docker](https://badgen.net/badge/icon/:latest?icon=docker&label=cytopia/dvwa)](https://hub.docker.com/r/cytopia/dvwa) 41 | 42 | #### Rolling releaess 43 | 44 | The following Docker image tags are rolling releases and are built and updated every night. 45 | 46 | [![nightly](https://github.com/cytopia/docker-dvwa/workflows/nightly/badge.svg)](https://github.com/cytopia/docker-dvwa/actions?query=workflow%3Anightly) 47 | 48 | 49 | | Docker Tag | Git Ref | PHP | Available Architectures | 50 | |-----------------------|--------------|-------------|----------------------------------------------| 51 | | **`latest`** | master | latest | `amd64`, `arm64` | 52 | | `php-8.1` | master | **`8.1`** | `amd64`, `arm64` | 53 | | `php-8.0` | master | **`8.0`** | `amd64`, `arm64` | 54 | | `php-7.4` | master | **`7.4`** | `amd64`, `arm64` | 55 | | `php-7.3` | master | **`7.3`** | `amd64`, `arm64` | 56 | | `php-7.2` | master | **`7.2`** | `amd64`, `arm64` | 57 | | `php-7.1` | master | **`7.1`** | `amd64`, `arm64` | 58 | | `php-7.0` | master | **`7.0`** | `amd64`, `arm64` | 59 | | `php-5.6` | master | **`5.6`** | `amd64`, `arm64` | 60 | 61 | 62 | ## :tada: Install 63 | Clone repository from GitHub: 64 | ```bash 65 | git clone https://github.com/cytopia/docker-dvwa 66 | ``` 67 | 68 | 69 | 70 | ## :zap: Start 71 | Inside the cloned repository (`docker-dvwa/` directory): 72 | ```bash 73 | make start 74 | ``` 75 | 76 | 77 | 78 | ## :no_entry_sign: Stop 79 | Inside the cloned repository (`docker-dvwa/` directory): 80 | ```bash 81 | make stop 82 | ``` 83 | 84 | 85 | 86 | ## :computer: Usage 87 | 88 | After running `make start` you can access DVWA in your browser via: 89 | 90 | * Url: http://localhost:8000 91 | * User: `admin` 92 | * Pass: `password` 93 | 94 | 95 | 96 | ## :star: Features 97 | 98 | * :whale: - Works out of the box on Linux, MacOS and Windows via Docker 99 | * :elephant: - Comes in flavours of all common [PHP version](#wrench-configuration) 100 | * :pirate_flag: - Enhances DVWA with [local exploitation](#pirate_flag-capture-the-flag) challenges 101 | * :repeat: - Docker images are [updated every night](https://hub.docker.com/r/cytopia/dvwa) against [DVWA](https://github.com/digininja/DVWA) master branch 102 | * :open_file_folder: - Bundles [Adminer](https://www.adminer.org/) to inspect the database 103 | 104 | 105 | 106 | ## :wrench: Configuration 107 | 108 | This setup allows you to configure a few settings via the `.env` file. 109 | 110 | | Variable | Default | Settings | 111 | |----------------------|---------|----------| 112 | | `PHP_VERSION` | `8.1` | PHP version to run DVWA (`5.6`, `7.0`, `7.1`, `7.2`, `7.3`, `7.4`, `8.0` or `8.1`) | 113 | | `LISTEN_PORT` | `8000` | Local port for the web server to listen on | 114 | | `RECAPTCHA_PRIV_KEY` | | Required to make the captcha module work. (See [FAQ](#bulb-faq) section below) | 115 | | `RECAPTCHA_PUB_KEY` | | Required to make the captcha module work. (See [FAQ](#bulb-faq) section below) | 116 | | `PHP_DISPLAY_ERRORS` | `0` | Set to `1` to display PHP errors (if you want a really easy mode) | 117 | 118 | The following `.env` file variables are default settings and their values can also be changed from within the web interface: 119 | 120 | | Variable | Default | Settings | 121 | |------------------|----------|----------| 122 | | `SECURITY_LEVEL` | `medium` | Adjust the difficulty level for the challenges[1]
(`low`, `medium`, `high` or `impossible`) | 123 | | `PHPIDS_ENABLED` | `0` | Set to `1` to enable PHP WAF/IDS[2] (off by default) | 124 | | `PHPIDS_VERBOSE` | `0` | Set to `1` to display WAF/IDS reasons for blocked requests | 125 | 126 | > [1] For the `SECURITY_LEVEL` changes to take effect, you will have to clear your cookies. Alternatively change it in the web interface.
127 | > [2] WAF (Web Application Firewall) / IDS (Intrusion Detection System) 128 | 129 | 130 | 131 | ## :pirate_flag: Capture the flag 132 | 133 | Additionally to the default DVWA features, this flavour also contains a few flags that can be captured via various means (including local privilege escalation). 134 | 135 | * Flag 1: `flag{b9bbcb33e11b80be759c4e844862482d}` 136 | * Flag 2: `flag{fc3fd58dcdad9ab23faca6e9a36e581c}` 137 | * Flag 3: `flag{eca7d1f3cf60a8b5344a49287b9076e4}` 138 | 139 | **How to play?** 140 | 141 | * :heavy_check_mark: You must gain access to the running Docker container through the web application. 142 | * **:no_entry: You cannot use `docker exec -it dvwa_web bash` to gain access** 143 | 144 | Let me know on :bird: [Twitter](https://twitter.com/everythingcli) if you've solved them and how easy/difficult they were. 145 | 146 | 147 | 148 | ## :gear: Tools 149 | 150 | The DVWA Docker image contains the following tools assisting you in solving the challenges and also allowing you to gain access via reverse shells. 151 | 152 | * `bash` 153 | * `netcat` 154 | * `ping` 155 | * `sudo` 156 | * `telnet` 157 | * `python3` 158 | 159 | 160 | 161 | ## :bulb: FAQ 162 | 163 |
Q: I want to proxy through BurpSuite, but it does not work on localhost or 127.0.0.1. 164 |


165 | Browsers ususally bypass localhost or 127.0.0.1 for proxy traffic. One solution is to add an alternative hostname to /etc/hosts and access the application through that.

166 | /etc/hosts: 167 | 168 | ```bash 169 | 127.0.0.1 dvwa 170 | ``` 171 | 172 | Then use http://dvwa:8000 in your browser. 173 |

174 |
175 | 176 | 177 | 178 |
Q: How can I run DVWA with a different PHP version? 179 |


180 | The here provided Docker images are built against all common PHP versions and you can easily select your version of choice in the .env prior startup. To do so, just uncomment the version of choice and restart the Docker Compose stack:
181 | .env 182 | 183 | ```bash 184 | # PHP VERSION 185 | # ----------- 186 | # Uncomment one of the PHP versions you want to use for DVWA 187 | #PHP_VERSION=5.6 188 | #PHP_VERSION=7.0 189 | #PHP_VERSION=7.1 190 | #PHP_VERSION=7.2 191 | #PHP_VERSION=7.3 192 | #PHP_VERSION=7.4 193 | #PHP_VERSION=8.0 194 | PHP_VERSION=8.1 195 | ``` 196 |

197 |
198 | 199 | 200 | 201 |
Q: How can I reset the database and start fresh? 202 |


203 | The database uses a Docker volume and you can simply remove it via:
204 | 205 | ```bash 206 | # the command below will stop all running container, 207 | # remove their state and delete the MySQL docker volume. 208 | make reset 209 | ``` 210 |

211 |
212 | 213 | 214 | 215 |
Q: How can I view Apache access or error log files? 216 |


217 | Log files are piped to stderr from the Docker container and you can view them via:
218 | 219 | ```bash 220 | make logs 221 | ``` 222 |

223 |
224 | 225 | 226 | 227 |
Q: How can I get a shell on the web server container? 228 |


229 | warning Note: Doing so is basically cheating, you are supposed to gain access to the machine via exploitation.

230 | You can enter the running web server container as root via:
231 | 232 | ```bash 233 | make enter 234 | ``` 235 |

236 |
237 | 238 | 239 | 240 |
Q: How do I setup the reCAPTCHA key? 241 |


242 | Go to https://www.google.com/recaptcha/admin and generate your captcha as shown below:
243 |

247 | 248 | 252 | 253 |

254 |
255 | 256 | 257 | 258 |
Q: How can I access/view the MySQL database? 259 |


260 | warning Note: Doing so is basically cheating, but if you really need to, you can do so.

261 | This Docker image bundles Adminer (a PHP web interace similar to phpMyAdmin) and you can access it here: http://localhost:8000/adminer.php
262 |

267 | 268 |

269 |
270 | 271 | 272 | 273 |
Q: How can I build the Docker image locally? 274 |


275 | To build or rebuild the Docker image against new updates in DVWA master branch, simply do the following:
276 | 277 | ```bash 278 | # This is builing the image for the default PHP version 279 | make rebuild 280 | 281 | # This is building the image with PHP 8.0 282 | make rebuild VERSION=8.0 283 | 284 | # Rebuild PHP 8.1 for arm64 platform 285 | make rebuild VERSION=8.0 ARCH=linux/arm64 286 | ``` 287 |

288 |
289 | 290 | 291 | 292 | ## :rocket: Deployment 293 | 294 | ### AWS 295 | 296 | [![Terraform](https://github.com/cytopia/docker-dvwa/actions/workflows/terraform.yml/badge.svg)](https://github.com/cytopia/docker-dvwa/actions/workflows/terraform.yml) 297 | 298 | This repository ships a [Terraform module](aws/) to deploy DVWA on AWS. 299 | 300 | ```bash 301 | cd aws/ 302 | cp terraform.tfvars-example terraform.tfvars 303 | 304 | terraform init 305 | terraform apply 306 | ``` 307 | 308 | For more information see [Terraform module](aws/). 309 | 310 | 311 | ### Kubernetes 312 | 313 | [![Kubernetes](https://github.com/cytopia/docker-dvwa/actions/workflows/kubernetes.yml/badge.svg)](https://github.com/cytopia/docker-dvwa/actions/workflows/kubernetes.yml) 314 | 315 | This repository ships [Kubernetes resources](k8s/) to deploy DVWA on K8s or minikube. 316 | 317 | ```bash 318 | cd k8s/ 319 | kubectl apply -f . 320 | ``` 321 | 322 | For more information see [k8s](k8s/). 323 | 324 | 325 | 326 | 327 | ## :lock: [cytopia](https://github.com/cytopia) sec tools 328 | 329 | Below is a list of sec tools and docs I am maintaining, which might come in handy working on DVWA. 330 | 331 | | Name | Category | Language | Description | 332 | |----------------------|----------------------|------------|-------------| 333 | | **[offsec]** | Documentation | Markdown | Offsec checklist, tools and examples | 334 | | **[header-fuzz]** | Enumeration | Bash | Fuzz HTTP headers | 335 | | **[smtp-user-enum]** | Enumeration | Python 2+3 | SMTP users enumerator | 336 | | **[urlbuster]** | Enumeration | Python 2+3 | Mutable web directory fuzzer | 337 | | **[pwncat]** | Pivoting | Python 2+3 | Cross-platform netcat on steroids | 338 | | **[badchars]** | Reverse Engineering | Python 2+3 | Badchar generator | 339 | | **[fuzza]** | Reverse Engineering | Python 2+3 | TCP fuzzing tool | 340 | 341 | [offsec]: https://github.com/cytopia/offsec 342 | [header-fuzz]: https://github.com/cytopia/header-fuzz 343 | [smtp-user-enum]: https://github.com/cytopia/smtp-user-enum 344 | [urlbuster]: https://github.com/cytopia/urlbuster 345 | [pwncat]: https://github.com/cytopia/pwncat 346 | [badchars]: https://github.com/cytopia/badchars 347 | [fuzza]: https://github.com/cytopia/fuzza 348 | 349 | 350 | 351 | ## :page_facing_up: License 352 | 353 | **[MIT License](LICENSE.md)** 354 | 355 | Copyright (c) 2021 **[cytopia](https://github.com/cytopia)** 356 | --------------------------------------------------------------------------------