Nord Juice Shop is a collection of scripts that aims to facilitate automation of the deployment of MultiJuicer and CTFd, which may be used to host CTF events or internal training on real-world web application security issues using OWASP JuiceShop.
The main script, manage-multijuicer.sh
, is a wrapper around MultiJuicer and CTFd (see Acknowledgements), and as such must be deployed on a Kubernetes cluster. The repository also contains a script for creating a new Kubernetes cluster in Azure Kubernetes Service (AKS) (see Creating a Kubernetes cluster in Azure). For a full example of going from zero to deployment, see Full example with deployment on Azure.
We have been using this solution in our internal workshops and events, with the aim of providing IT personnel with hands-on practical experience on web application security, in a safe environment.
# Copy the example environment variable file .env
cp .env .env.local
Modify the values in the file to your liking. Required variables are marked as (required)
:
CTF_KEY
: A key used to generate challenge flags. Should be rotated between CTF-events to ensure unique flags.COOKIE_SECRET
: Secret used for the cookie.CTFD_SECRET_KEY
: Secret key used by the CTFd instance.JUICE_FQDN
: The domain name at which the setup will be reachable. A DNS record must exist and be publicly reachable for TLS certificate acquisition and routing to work.
Optionally specify the max. number of JuiceShop instances that can be created by setting the variabel MAX_INSTANCES
, or any other variables you wish to modify.
If you'd like to automate the CTFd configuration as well, make sure to at least set the following environment variable:
CTFD_ADMIN_PASSWORD
: Password for the CTFd admin user (by default, the username of this user is 'admin')
We'd also recommend setting the variable CTFD_REGISTRATION_CODE
, which requires users to provide the specified code upon registering an account on the CTFd instance.
❗ Make sure to source the environment variable file you just created before proceeding!
Deployment of the CTF services (i.e. MultiJuicer and CTFd) is done using the script manage-multijuicer.sh
- Access to a Kubernetes cluster, and having activated that context in your
kubectl
config
./manage-multijuicer.sh -h
Usage: ./manage-multijuicer.sh COMMAND
Commands:
up Deploy the MultiJuicer and CTFd services in the Kubernetes cluster
down Remove the MultiJuicer and CTFd services from the Kubernetes cluster
# Deploy the services
./manage-multijuicer.sh up
# The MultiJuicer service should now be available at `JUICE_FQDN`,
# while CTFd should be available at `JUICE_FQDN/ctfd`
# Shut down the services
./manage-multijuicer.sh down
Once you've deployed the services (using ./manage-multijuicer.sh up
), make sure to configure the CTFd instance, either by hand or using the script provided in this repository (unless you've disabled the CTFd service). See Configuring CTFd below.
The CTFd instance comes unconfigured by default. To configure it, either navigate to the /ctfd
endpoint of your domain, or run the script manage-ctfd.sh
(see below for details).
⚠️ If you choose to configure CTFd manually, the CTF flags from JuiceShop must be imported into the CTFd instance before the users can submit their flags. The CSV file that should be imported can be generated by runningmanage-ctfd.sh gen
If your deployment uses self-signed certificates, or you must set the environment variable
CURL_INSECURE=1
.
- Access to a Kubernetes cluster, and having activated that context in your
kubectl
config - Having deployed the services by running
./manage-multijuicer.sh up
./manage-ctfd.sh -h
Usage: ./manage-ctfd.sh COMMAND
Commands:
cfg Configures the CTFd instance
gen Generates the CTFd challenges CSV
import Import a CTFd challenges CSV to the CTFd instance
pages Import the custom pages to the CTFd instance
run Runs all of the above, i.e. configures CTFd, and generates and imports the challenges
Creation of a Kubernetes cluster in Azure Kubernetes Service (AKS) is done using the script manage-azure-deployment.sh
. The script may also be used to create a Resource Group and a Key Vault.
# Log in to Azure CLI with your account
# A new tab will open in your browser, asking you to authenticate
az login
# Set the subscription in which you wish to deploy the services
az account set -s <subscription_id | subscription_name>
Modify the environment variables in the file you copied in Environment variables. Required variables are marked as (required)
:
AZURE_DNS_NAME
: The hostname used for the NGINX ingress service. Must be unique within a zone.AZURE_SUBSCRIPTION_ID
: The subscription ID of your Azure subscription.AZURE_RESOURCE_GROUP
: A pre-existing resource group. The script may create it for you, if you setMANAGE_RG=1
.
Specify which services the script should manage (in addition to the cluster):
MANAGE_RG
: If not specified, you must make sure that a resource group with the nameAZURE_RESOURCE_GROUP
exists.MANAGE_KEYVAULT
⚠️ Make sure that the resource groupAZURE_RESOURCE_GROUP
exists prior to running, or setMANAGE_RG=1
.
❗ Make sure to source the environment variable file you just created before proceeding!
./manage-azure-deployment.sh -h
Usage: ./manage-azure-deployment.sh COMMAND
Commands:
new Deploy a brand new cluster
up Spin the cluster back up, scaling up the resources
down Scale down the cluster to save resources (keeps the AKS resource itself intact)
wipe Removes the cluster
wipe-all Removes the cluster, resource group, and key vault.
write-secrets Write the secrest to Azure Key Vault.
password Retrieve the admin password for the multi-juicer instance
# Creating a new cluster
./manage-azure-deployment.sh new
# 'Turn on' a cluster previously taken down with the 'down' command (see below).
./manage-azure-deployment.sh up
# Shut down the cluster, but keep the AKS resource intact - intended for when you plan to spin it back up within a short time.
./manage-azure-deployment.sh down
# Shut down the cluster and remove the AKS resource.
./manage-azure-deployment.sh wipe
# Shut down the cluster and remove the AKS resource as well as the resource group and key vault.
./manage-azure-deployment.sh wipe-all
# Write the secrets to the Azure Keyvault
./manage-azure-deployment.sh write-secrets
# Retrieve the password for the admin-user in the MultiJuicer instance
./manage-azure-deployment.sh password
You may use the domain name provided by Azure DNS to reach your host. If you wish to do so, make sure to set JUICE_FQDN
to <AZURE_DNS_NAME>.<AZURE_LOCATION>.cloudapp.azure.com
(e.g. juice1337.norwayeast.cloudapp.azure.com
) prior to running the scripts.
# Firstly, create a new Kubernetes cluster in Azure Kubernetes Service
./manage-azure-deployment.sh new
# Next, we will deploy the services in the Kubernetes cluster
./manage-multijuicer.sh up
# Next, generate the challenge list for CTFd and upload the CSV file to CTFd
./manage-ctfd.sh run
# Once the event is done, you may remove the cluster and all services by running
./manage-multijuicer.sh down
./manage-azure-deployment.sh wipe
Creation of a Service Principal (App Registration) in Azure Active Directory (AAD) is done using the script service-principal.sh
.
# Log in to Azure CLI with your account
# A new tab will open in your browser, asking you to authenticate
az login
# Set the subscription in which you wish to deploy the services
az account set -s <subscription_id | subscription_name>
Modify the environment variables in the file you copied in Environment variables. Required variables are marked as (required)
:
AZURE_SUBSCRIPTION_ID
: The subscription ID of your Azure subscription.AZURE_RESOURCE_GROUP
: Name of the resource group to use.AZURE_SERVICE_PRINCIPAL_NAME
: Name of the service principal.AZURE_AD_APP_ADMIN_GROUP
: Name of the Azure AD group allowed to administrate the Service Principal.
Optionally specify the Github repository in which the code exists, to allow the Service Principal access to the repository:
GIT_REPO
: E.g.bouvet/nord-juice-shop
⚠️ Make sure that the resource groupAZURE_RESOURCE_GROUP
exists prior to running.
❗ Make sure to source the environment variable file you just created before proceeding!
./service-principal.sh
Usage: ./service-principal.sh COMMAND
Commands:
new Create a new service principal
wipe Delete the service principal
Thanks for your interest in contributing! Please see the Contribution guide for details
This project provides scripts for automating as much as possible in terms of deploying the MultiJuicer
and CTFd
services in a Kubernetes cluster.
Please see the respective websites for more information: