This guide explains how to create new target and tool modules for Katana.
Katana supports two types of modules:
| Type | Description | Implementation |
|---|---|---|
| Targets | Vulnerable web applications | Docker Compose |
| Tools | Security testing tools | Shell scripts |
Targets are Docker-based vulnerable web applications accessed through Katana's reverse proxy.
modules/targets/<name>/
├── module.yml # Module metadata and proxy configuration
└── compose.yml # Docker Compose configuration
name: example-target
category: targets
description: Short description of the target
compose: ./compose.yml
proxy:
- hostname: example # Subdomain (becomes example.samurai.wtf or example.domain.com)
service: web # Docker Compose service name
port: 80 # Container port to proxy to
# Optional: Environment variables for compose.yml
env:
SOME_VAR: valueFields:
| Field | Required | Description |
|---|---|---|
name |
Yes | Unique module name (lowercase, alphanumeric, hyphens) |
category |
Yes | Must be targets |
description |
Yes | Brief description |
compose |
Yes | Path to Docker Compose file |
proxy |
Yes | Array of proxy route configurations |
env |
No | Environment variables passed to Docker Compose |
Each proxy entry maps a hostname to a container port:
proxy:
- hostname: dvwa # https://dvwa.samurai.wtf
service: web # Service name in compose.yml
port: 80 # Port the service listens onMulti-hostname targets (like Musashi) can map multiple hostnames to different ports on the same container:
proxy:
- hostname: cors
service: musashi
port: 3021
- hostname: api-cors
service: musashi
port: 3020
- hostname: csp
service: musashi
port: 3041services:
web:
image: vulnerables/web-dvwa
networks:
- katana-net
# Optional: environment variables
environment:
- DB_HOST=db
# NO ports: section - proxy handles external access
# Optional: additional services (databases, etc.)
db:
image: mariadb:10.6
networks:
- katana-net
environment:
- MYSQL_ROOT_PASSWORD=dvwa
networks:
katana-net:
external: trueRules:
- Must join
katana-net- All services must be on the externalkatana-netnetwork - No published ports - Do not use
ports:section; the proxy handles external access - Use official/trusted images - Prefer images from Docker Hub official repositories or verified publishers
The env section in module.yml is passed to Docker Compose. You can use this for runtime configuration:
module.yml:
env:
API_HOST: api.samurai.wtf
CLIENT_HOST: client.samurai.wtfcompose.yml:
services:
app:
image: example/app
environment:
- API_URL=https://${API_HOST}
- CLIENT_URL=https://${CLIENT_HOST}modules/targets/juiceshop/module.yml:
name: juiceshop
category: targets
description: OWASP Juice Shop - Modern vulnerable web application
compose: ./compose.yml
proxy:
- hostname: juiceshop
service: juiceshop
port: 3000modules/targets/juiceshop/compose.yml:
services:
juiceshop:
image: bkimminich/juice-shop
networks:
- katana-net
networks:
katana-net:
external: truemodules/targets/dvwa/module.yml:
name: dvwa
category: targets
description: Damn Vulnerable Web Application - OWASP Top 10 training
compose: ./compose.yml
proxy:
- hostname: dvwa
service: dvwa
port: 80modules/targets/dvwa/compose.yml:
services:
dvwa:
image: ghcr.io/digininja/dvwa:latest
depends_on:
- db
environment:
- DB_SERVER=db
networks:
- katana-net
db:
image: mariadb:10.6
environment:
- MYSQL_ROOT_PASSWORD=dvwa
- MYSQL_DATABASE=dvwa
- MYSQL_USER=dvwa
- MYSQL_PASSWORD=dvwa
networks:
- katana-net
networks:
katana-net:
external: truemodules/targets/musashi/module.yml:
name: musashi
category: targets
description: Musashi.js - CORS, CSP, and JWT security demonstrations
compose: ./compose.yml
proxy:
- hostname: cors
service: musashi
port: 3021
- hostname: api-cors
service: musashi
port: 3020
- hostname: csp
service: musashi
port: 3041
- hostname: jwt
service: musashi
port: 3050
env:
CORS_CLIENT_HOST: cors.samurai.wtf
CORS_API_HOST: api-cors.samurai.wtf
CSP_HOST: csp.samurai.wtf
JWT_HOST: jwt.samurai.wtfTools are security applications installed via shell scripts. They're primarily for local (VM) deployments.
modules/tools/<name>/
├── module.yml
├── install.sh
├── remove.sh
├── start.sh # Optional
└── stop.sh # Optional
name: example-tool
category: tools
description: Description of the tool
install: ./install.sh
remove: ./remove.sh
start: ./start.sh # Optional
stop: ./stop.sh # Optional
install_requires_root: true # Set if install needs sudoScripts must:
- Be executable (
chmod +x) - Exit 0 on success, non-zero on failure
- Use
set -efor fail-fast behavior
Example install.sh:
#!/bin/bash
set -e
VERSION="2.14.0"
URL="https://github.com/zaproxy/zaproxy/releases/download/v${VERSION}/ZAP_${VERSION}_Linux.tar.gz"
CHECKSUM="abc123..." # SHA256
cd /tmp
wget -q "$URL" -O zap.tar.gz
echo "${CHECKSUM} zap.tar.gz" | sha256sum -c
tar xzf zap.tar.gz -C /opt/
ln -sf /opt/ZAP_${VERSION}/zap.sh /usr/local/bin/zap
rm zap.tar.gz
echo "ZAP ${VERSION} installed successfully"Example remove.sh:
#!/bin/bash
set -e
rm -rf /opt/ZAP_*
rm -f /usr/local/bin/zap
echo "ZAP removed successfully"# Check that module loads without errors
katana list targets# Install the target
katana install <name>
# Check status
katana status
docker ps | grep katana-<name># Ensure DNS is synced
sudo katana dns sync
# Start proxy
katana proxy start
# Test in browser or with curl
curl -k https://<hostname>.samurai.wtf# Remove the target
katana remove <name>
# Verify containers removed
docker ps -a | grep katana-<name>To contribute a new module:
-
Create the module in
modules/targets/<name>/ormodules/tools/<name>/ -
Test thoroughly using the steps above
-
Open a Pull Request with:
- The module files
- Brief description of the target/tool
- Any special setup requirements
- Use official Docker images when possible
- Include meaningful descriptions
- Test on a clean system
- Document any special requirements in the PR
See CONTRIBUTING.md for general contribution guidelines.
Check container logs:
katana logs <name>
docker compose -p katana-<name> logs- Verify container is running:
docker ps | grep <name> - Check the service name matches
module.yml - Check the port number is correct
- Verify
module.ymlsyntax is valid YAML - Check all required fields are present
- Ensure file is in correct directory (
modules/targets/<name>/)
Verify container is on katana-net:
docker inspect katana-<name>-<service>-1 | grep -A 10 Networks