Code Monkey home page Code Monkey logo

nord-juice-shop's Introduction

Nord Juice Shop

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.

Prerequisites

Packages & Services

Environment variables

# 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!

Running

Deploying the CTF services

Deployment of the CTF services (i.e. MultiJuicer and CTFd) is done using the script manage-multijuicer.sh

Prerequisites

  • 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.

Configuring CTFd

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 running manage-ctfd.sh gen

If your deployment uses self-signed certificates, or you must set the environment variable CURL_INSECURE=1.

Prerequisites

  • 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

Creating a Kubernetes cluster in Azure

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.

Prerequisites

Packages & Services
Authenticate against Azure
# 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>
Environment variables

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 set MANAGE_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 name AZURE_RESOURCE_GROUP exists.
  • MANAGE_KEYVAULT

⚠️ Make sure that the resource group AZURE_RESOURCE_GROUP exists prior to running, or set MANAGE_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

Full example with deployment on Azure

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

Creating a Service Principal in Azure

Creation of a Service Principal (App Registration) in Azure Active Directory (AAD) is done using the script service-principal.sh.

Prerequisites

Packages & Services
Authenticate against Azure
# 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>
Environment variables

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 group AZURE_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

Contributing

Thanks for your interest in contributing! Please see the Contribution guide for details

Acknowledgements

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:

nord-juice-shop's People

Contributors

markusrf avatar netr0m avatar olavis avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar

nord-juice-shop's Issues

Broken TLS when TLS_CERT_EMAIL uses an invalid domain name

Expected Behaviour

For HTTPS certificates to be acquired and used

Actual Behaviour

Using the .env template's default ([email protected], which is an invalid domain), the certificate acquisiton process fails due to invalid domain

E0410 09:32:12.711413       1 setup.go:271] cert-manager/controller/clusterissuers "msg"="skipping retrying account registration as a BadRequest response was returned from the ACME server" "error"="400 urn:ietf:params:acme:error:invalidContact: Error creating new account :: contact email \"[email protected]\" has invalid domain : Domain name does not end with a valid public suffix (TLD)"

Steps to Reproduce

Extend `generate-challenges.sh` to support full automation

Describe Problem

Currently, the generate-challenges.sh script does one thing - it generates the CTFd challenges CSV by wrapping the various steps involved in running juice-shop-ctf-cli into a single command.

  • This requires that an active instance of juice-shop is created in the multi-juicer cluster (from which the challenges are retrieved), which must be done by creating a team in the multi-juicer balancer. This currently blocks a fully automated setup.

  • When deploying the services (with manage-multijuicer.sh), the CTFd instance is deployed in an unconfigured state. This means that manual configuration has to be done, including creating the admin account. Theoretically, this could be hijacked by some other party (although we could wipe it, having control of the infrastructure/kubernetes cluster).

  • The admin must also manually import the generated challenges (as well as the guides).

Suggest Solution

Extend the generate-challenges.sh script to:

  • Support fully automated CTFd challenges generation:
    • create an instance of juice-shop by creating a team in the multi-juicer balancer
  • Support automated configuration (setup) of the CTFd instance
    • Issue an HTTP request to the /setup endpoint of CTFd, similarly to how interaction is done via the browser by an administrator configuring the instance
    • Issue an HTTP request to the /admin/import/csv endpoint, importing the generated challenges CSV
    • Automate the uploading of the custom pages containing guides, etc.
  • Allow the user (executing the script) to choose which command to run, i.e.
    • gen: generate challenges (producing a CSV)
    • import: import challenges (importing the specified CSV)
    • cfg: configure the CTFd instance
    • pages: import the custom pages, such as the guides/tips pages (./guides-and-tips)
    • run: All of the above

Additional Details

  • Replaces the un-resolvable issue #54

Handle AuthorizationFailed in `manage-azure-deployment.sh`

Expected Behaviour

Receiving an AuthorizationFailed error should cause the script to abort.

Actual Behaviour

Creating Resource Group 'MultiJuicerTest' in 'norwayeast'
ERROR: (AuthorizationFailed) The client '<REDACTED>' with object id '<REDACTED>' does not have authorization to perform action 'Microsoft.Resources/subscriptions/resourcegroups/write' over scope '/subscriptions/<REDACTED>/resourcegroups/MultiJuicerTest' or the scope is invalid. If access was recently granted, please refresh your credentials.
Code: AuthorizationFailed

Creating AKS cluster 'juicy-k8s'
ERROR: (AuthorizationFailed) The client '<REDACTED>' with object id '<REDACTED>' does not have authorization to perform action 'Microsoft.Resources/subscriptions/resourcegroups/read' over scope '/subscriptions/<REDACTED>/resourcegroups/MultiJuicerTest' or the scope is invalid. If access was recently granted, please refresh your credentials.
Code: AuthorizationFailed

[...]

Steps to Reproduce

  • Run the script manage-azure-delpoyment.sh as a user without permission to create resources (e.g. as the Service Principal)

Include generated config, pages, and users when generating CTFd challenges ZIP

Describe Problem

Each time we set up a new instance of the CTFd service (typically every time we deploy), we have to manually intervene by completing the configuration steps in CTFd. This includes creating a new user, configuring the settings, and importing the custom pages defined in guides-and-tips/. Rather than doing this manually, we should consider generating the user JSON and config JSON to reduce the amount of manual work required.

Currently, we generate the challenges file for CTFd with the script generate-challenges.sh, which produces a ZIP file containing challenges.json, among other things. This is manually uploaded to CTFd after configuration has taken place.

By extending this script, we could potentially include all common configurations in the zip file and upload it directly, eliminating the need for manual steps.

Suggest Solution

  • Look at the contents of a backed up ZIP file exported from CTFd to identify how to generate such files
  • Implement logic in generate-challenges.sh to
    • generate these JSON files, and add them to the ZIP file produced by juice-shop-ctf-cli
    • upload the ZIP file to the CTFd instance

Additional Details

Set up GitHub Actions

The following GitHub Actions are needed and need to be set up. While the exact MultiJuicer setup script is not yet ready, the setup of the actions can still be made.

  • Configure OpenID Connect in Azure #16
  • Action for authenticating against AAD (Entra ID)
  • Run the AKS creation script (manage-azure-deployment.sh)
  • Run the deployment script (manage-multijuicer.sh) (blocked by #5 and #14)
  • Run the script for importing the challenges to configuring CTFd (generate-challenges.sh) (manage-ctfd.sh) (blocked by #58) (awaits #60)

The actions should both be triggered manually and after a merge to the master branch.

The github actions also need to be allowed to deploy resources in azure. Look into federated credentials for connecting github actions to azure.

https://learn.microsoft.com/en-us/azure/developer/github/connect-from-azure?tabs=azure-portal%2Clinux
https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-azure
https://github.com/marketplace/actions/azure-cli-action#workflow-to-execute-an-az-cli-script-of-a-specific-cli-version-via-file-present-in-your-repository

feat(ctfd): Manage CTFd-Helm deployment in manage-multijuicer.sh

In order to manage the CTFd deployment, we should incorporate it into our preexisting deployment script so that all resources are created/destroyed upon deployment/taking it down.

  1. Deploy & Destroy:
  2. Configure INGRESS & TLS:
  3. Configure DNS:

Actions: Workflow `configure-ctfd` fails

Expected Behaviour

Actual Behaviour

[...]
Waiting for juice-shop instance to be ready...
pod/t-ctfd-config-gen-juiceshop-67b75dd6f5-mtflv condition met
Opening temporary tunnel to a juice-shop pod
    SUCCESS
Writing juice-shop-ctf config to file
    SUCCESS
Importing challenges from JuiceShop

Generate OWASP Juice Shop challenge archive for setting up CTFd, FBCTF or RootTheBox score server

Failed to fetch snippet from API! AggregateError
ERROR: juice-shop-ctf-cli failed to generate the CTFd config file

Steps to Reproduce

feat(ctfd): Define CTFd-Helm variables

We have several ways to choose from when it comes to the deployment of the CTFd instance for our multi-juicer CTF setup. In short, the three alternatives are

  1. helm chart (as with multi-juicer itself);
  2. our own setup in k8s, i.e. writing a fair amount of YAML; or
  3. our own setup without k8s, e.g. Azure Container Instances

We've previously landed on going for the Helm chart, as it aligns well with our current setup, is maintained, and significantly reduces the workload incl. manual labor we'd need for the other two options. Details can be seen in the comments of issue #8.

Tasks

Use the bman46/CTFd-Helm helm chart

  1. Override default values (config) defined in values.yml:
    1. Identify values to override (e.g. passwords, etc.)
    2. Create ctfd.yml containing the values to override
    3. Determine secret values to override using --set, such as --set redis.auth.password=$REDIS_PASS

Example

We've made a similar approach with our multi-juicer setup:

Based on the default values defined in the multi-juicer configuration values.yml, we firstly identified the values we wished to override.

Next, we created juicer.yml and proceeded to override the values from values.yml.

Finally, we identified the secret values we wished to override (such as passwords and other information we want to keep secret), and added them to the deployment using the --set flag. The task here is to identify and make a list of the variables. They will be consumed in the deployment script which is part of #25 (see https://github.com/bouvet/nord-juice-shop/blob/feat/monitoring-setup-script/manage-multijuicer.sh#L119-L127 for an example with multi-juicer variables)

Identify minimal set of Azure permissions required to deploy

Describe Problem

We currently expect the user to have full access to the Azure subscription in question (i.e. Owner), as we have not outlined the required permission set for deployment.

We should identify and document all required permissions, in order to ensure that we use Azure IAM role grants with the permissions that are strictly required.

Suggest Solution

  • Identify by trial and error (documentation lacks)
  • Produce JSON representing the custom role.
  • Create documentation explaining the requirements

Additional Details

Tech-meeting 31/5

Present the CTF stuff on the tech-meeting

Need these things ready by the tech-meeting:

  • Create agenda (intro, food, CTF, walkthrough?)
  • Get security people from Øst to hold the intro?
  • Set a date
  • Set a location (office, Jotunheimen)

Actions: Add step for configuration of the CTFd instance

Describe Problem

Create a workflow for execution of the manage-ctfd.sh script. Should be separated from deploy-ctf.yml (due to differing purpose and the need to wait for TLS cert propagation post-deployment)

Suggest Solution

Additional Details

Create PowerPoint for meetings

Create presentation to present to participants during MulitJuicer workshops (before hacking begins).
Depending on skill level of participants, presentation should include a short tutorial on using the JuiceShop and also tips on how to start hacking (SQL injections, XSS, etc)
Must be ready for #6

Link to PowerPoint is found in OneDrive folder, bookmarked in slack-channel

Configure `release-please`

Describe Problem

We should consider setting up release-please to assist in creating versioned releases with automatically generated changelogs.

Suggest Solution

Set up release-please to create releases with automatically generated changelogs.

Additional Details

Docs: Define prerequisites for running the `deploy-ctf` workflow

Describe Problem

Requirements include:

  • Service principal
    • with permission to create resources (relates to #57)
    • with federated credential grants for
      • the specific branch(es)
      • the specific environment(s)
  • Organization/repository/environment variables and secrets required to run

Suggest Solution

Document the requirements

Additional Details

Create script to add whitelist IPs to the cluster NSG (if still relevant)

The MultiJuicer setup automatically creates a NSG for the cluster, ref the medium post. After it is created we need to add rules that block all incoming traffic and then whitelist/allow the specific IP ranges we want. This process needs to be scripted. We also need to figure out how to specify 'Norwegian IPs' or otherwise identify the IPs we want.

Script has to do the following:

  • Find the id/name of the newly created NSG in Azure
  • Add the IP rules to the NSG

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.