From cd971722283493782716375cc5ad23ad970817c4 Mon Sep 17 00:00:00 2001 From: Greg Sienkiewicz Date: Fri, 20 Oct 2023 16:45:59 -0400 Subject: [PATCH 01/10] update cloudwatch log query fiter --- cloudwatch.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cloudwatch.tf b/cloudwatch.tf index 241465f..f9a835f 100644 --- a/cloudwatch.tf +++ b/cloudwatch.tf @@ -120,7 +120,7 @@ fields @timestamp as Timestamp, httpRequest.httpMethod as Request_Method, httpRequest.uri as URI | sort @timestamp desc -| filter action not like "ALLOW" and -| terminatingRuleId in ["AWSManagedRulesAmazonIpReputationList", "AWSManagedRulesCommonRuleSet", "AWSManagedRulesKnownBadInputsRuleSet", "AWSManagedRulesSQLiRuleSet", "AWSManagedRulesLinuxRuleSet"] +| filter terminatingRuleId in ["AWSManagedRulesAmazonIpReputationList", "AWSManagedRulesCommonRuleSet", "AWSManagedRulesKnownBadInputsRuleSet", "AWSManagedRulesSQLiRuleSet", "AWSManagedRulesLinuxRuleSet"] +or nonTerminatingMatchingRules.0.ruleId in ["AWSManagedRulesAmazonIpReputationList", "AWSManagedRulesCommonRuleSet", "AWSManagedRulesKnownBadInputsRuleSet", "AWSManagedRulesSQLiRuleSet", "AWSManagedRulesLinuxRuleSet"] EOF } From 0162017a87de826cc69fd78381208e115f0fa085 Mon Sep 17 00:00:00 2001 From: Greg Sienkiewicz Date: Sun, 22 Oct 2023 13:21:51 -0400 Subject: [PATCH 02/10] add ansible playbook for cftd --- ansible/playbook_cftd.yml | 81 +++++++++++++++++++++++++++++++++++++++ rds.tf | 2 + s3.tf | 43 +++++++++++++++++++++ 3 files changed, 126 insertions(+) create mode 100644 ansible/playbook_cftd.yml create mode 100644 s3.tf diff --git a/ansible/playbook_cftd.yml b/ansible/playbook_cftd.yml new file mode 100644 index 0000000..f30be1e --- /dev/null +++ b/ansible/playbook_cftd.yml @@ -0,0 +1,81 @@ +--- + +- name: CFTd + gather_facts: false + remote_user: ssm-user + become: true + hosts: all + + tasks: + - name: Install Git + dnf: + name: git + state: present + + - name: Install Docker + dnf: + name: docker + state: present + + - name: Enable Docker service + ansible.builtin.systemd: + name: docker.service + state: started + enabled: true + + - name: Add cftd user to docker group + ansible.builtin.user: + name: ssm-user + groups: docker + append: yes + + - name: Create /opt/cftd directory + ansible.builtin.file: + path: /opt/cftd + state: directory + owner: ssm-user + group: ssm-user + mode: "0755" + + - name: Workaround Git safe directory error + community.general.git_config: + name: safe.directory + value: /opt/cftd + scope: global + environment: + HOME: /home/ssm-user + + - name: Read safe directory from git config + community.general.git_config: + name: safe.directory + scope: global + environment: + HOME: /home/ssm-user + + - name: Git clone CFTd git repo + ansible.builtin.git: + repo: "https://github.com/CTFd/CTFd.git" + dest: /opt/cftd + clone: yes + environment: + HOME: /home/ssm-user + + - name: Change ownership of CFTd directory + ansible.builtin.file: + path: /opt/cftd + state: directory + recurse: yes + owner: ssm-user + group: ssm-user + + - name: Download docker-compose + become: true + ansible.builtin.get_url: + url: https://github.com/docker/compose/releases/download/v2.20.3/docker-compose-linux-x86_64 + dest: /usr/bin/docker-compose + mode: "755" + + - name: Run docker-compose to start cftd + ansible.builtin.command: /usr/bin/docker-compose up -d + args: + chdir: /opt/cftd diff --git a/rds.tf b/rds.tf index 446bc6a..84d8ee7 100644 --- a/rds.tf +++ b/rds.tf @@ -22,6 +22,7 @@ resource "aws_db_subnet_group" "cftd" { } } +/* resource "aws_db_instance" "cftd" { identifier = "ctfd-db" instance_class = "db.t3.micro" @@ -38,3 +39,4 @@ resource "aws_db_instance" "cftd" { publicly_accessible = false skip_final_snapshot = true } +*/ diff --git a/s3.tf b/s3.tf new file mode 100644 index 0000000..aa7b46a --- /dev/null +++ b/s3.tf @@ -0,0 +1,43 @@ +###======================== CTF S3 Ansible ====================== ### + +# resource "aws_s3_bucket" "ansible" { +# #checkov:skip=CKV2_AWS_61:Ensure that an S3 bucket has a lifecycle configuration +# #checkov:skip=CKV_AWS_18:Ensure the S3 bucket has access logging enabled +# #checkov:skip=CKV2_AWS_65:Ensure access control lists for S3 buckets are disabled +# #checkov:skip=CKV2_AWS_62:Ensure S3 buckets should have event notifications enabled +# #checkov:skip=CKV_AWS_145:Ensure that S3 buckets are encrypted with KMS by default +# #checkov:skip=CKV_AWS_144:Ensure that S3 bucket has cross-region replication enabled + +# bucket = var.ansible_playbook_bucket_name +# } + +# resource "aws_s3_bucket_versioning" "ansible" { +# bucket = aws_s3_bucket.ansible.id +# versioning_configuration { +# status = "Enabled" +# } +# } + +# resource "aws_s3_bucket_server_side_encryption_configuration" "ansible" { +# bucket = aws_s3_bucket.ansible.id + +# rule { +# apply_server_side_encryption_by_default { +# sse_algorithm = "AES256" +# } +# } +# } + +# resource "aws_s3_bucket_ownership_controls" "ansible" { +# bucket = aws_s3_bucket.ansible.id +# rule { +# object_ownership = "BucketOwnerPreferred" +# } +# } + +# resource "aws_s3_bucket_acl" "ansible" { +# depends_on = [aws_s3_bucket_ownership_controls.ansible] + +# bucket = aws_s3_bucket.ansible.id +# acl = "private" +# } From a42f6f974057270d7a64e3b9c8b7d6c1e39dc667 Mon Sep 17 00:00:00 2001 From: Greg Sienkiewicz Date: Sun, 22 Oct 2023 22:03:49 -0400 Subject: [PATCH 03/10] enable S3 bucket for ansible playbooks --- s3.tf | 106 +++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 65 insertions(+), 41 deletions(-) diff --git a/s3.tf b/s3.tf index aa7b46a..0a07786 100644 --- a/s3.tf +++ b/s3.tf @@ -1,43 +1,67 @@ ###======================== CTF S3 Ansible ====================== ### -# resource "aws_s3_bucket" "ansible" { -# #checkov:skip=CKV2_AWS_61:Ensure that an S3 bucket has a lifecycle configuration -# #checkov:skip=CKV_AWS_18:Ensure the S3 bucket has access logging enabled -# #checkov:skip=CKV2_AWS_65:Ensure access control lists for S3 buckets are disabled -# #checkov:skip=CKV2_AWS_62:Ensure S3 buckets should have event notifications enabled -# #checkov:skip=CKV_AWS_145:Ensure that S3 buckets are encrypted with KMS by default -# #checkov:skip=CKV_AWS_144:Ensure that S3 bucket has cross-region replication enabled - -# bucket = var.ansible_playbook_bucket_name -# } - -# resource "aws_s3_bucket_versioning" "ansible" { -# bucket = aws_s3_bucket.ansible.id -# versioning_configuration { -# status = "Enabled" -# } -# } - -# resource "aws_s3_bucket_server_side_encryption_configuration" "ansible" { -# bucket = aws_s3_bucket.ansible.id - -# rule { -# apply_server_side_encryption_by_default { -# sse_algorithm = "AES256" -# } -# } -# } - -# resource "aws_s3_bucket_ownership_controls" "ansible" { -# bucket = aws_s3_bucket.ansible.id -# rule { -# object_ownership = "BucketOwnerPreferred" -# } -# } - -# resource "aws_s3_bucket_acl" "ansible" { -# depends_on = [aws_s3_bucket_ownership_controls.ansible] - -# bucket = aws_s3_bucket.ansible.id -# acl = "private" -# } +resource "aws_s3_bucket" "ansible" { + #checkov:skip=CKV2_AWS_61:Ensure that an S3 bucket has a lifecycle configuration + #checkov:skip=CKV_AWS_18:Ensure the S3 bucket has access logging enabled + #checkov:skip=CKV2_AWS_65:Ensure access control lists for S3 buckets are disabled + #checkov:skip=CKV2_AWS_62:Ensure S3 buckets should have event notifications enabled + #checkov:skip=CKV_AWS_145:Ensure that S3 buckets are encrypted with KMS by default + #checkov:skip=CKV_AWS_144:Ensure that S3 bucket has cross-region replication enabled + + bucket = var.ansible_playbook_bucket_name +} + +resource "aws_s3_bucket_versioning" "ansible" { + bucket = aws_s3_bucket.ansible.id + versioning_configuration { + status = "Enabled" + } +} + +resource "aws_s3_bucket_server_side_encryption_configuration" "ansible" { + bucket = aws_s3_bucket.ansible.id + + rule { + apply_server_side_encryption_by_default { + sse_algorithm = "AES256" + } + } +} + +resource "aws_s3_bucket_ownership_controls" "ansible" { + bucket = aws_s3_bucket.ansible.id + rule { + object_ownership = "BucketOwnerEnforced" + } +} + +resource "aws_s3_bucket_acl" "ansible" { + depends_on = [aws_s3_bucket_ownership_controls.ansible] + + bucket = aws_s3_bucket.ansible.id + acl = "private" +} + +resource "aws_s3_bucket_policy" "allow_access_from_ssm" { + bucket = aws_s3_bucket.ansible.id + policy = data.aws_iam_policy_document.allow_access_from_ssm.json +} + +data "aws_iam_policy_document" "allow_access_from_ssm" { + statement { + principals { + type = "AWS" + identifiers = ["arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/${aws_iam_instance_profile.ctf.role}"] + } + + actions = [ + "s3:GetObject", + "s3:ListBucket", + ] + + resources = [ + aws_s3_bucket.ansible.arn, + "${aws_s3_bucket.ansible.arn}/*", + ] + } +} From 72c33e98676a243d8c25193b6ae78122d6c05eb9 Mon Sep 17 00:00:00 2001 From: Greg Sienkiewicz Date: Sun, 22 Oct 2023 22:04:37 -0400 Subject: [PATCH 04/10] Update README.md --- README.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/README.md b/README.md index b31bf42..0631fe9 100644 --- a/README.md +++ b/README.md @@ -9,3 +9,25 @@ This repository contains the Terraform that can be used to deploy an instance of ![Juice Shop](https://raw.githubusercontent.com/juice-shop/juice-shop/develop/frontend/src/assets/public/images/JuiceShop_Logo_100px.png) [OWASP Juice Shop](https://owasp.org/www-project-juice-shop/) is probably the most modern and sophisticated insecure web application! ![CTFd](https://ctfd.io/static/img/ctfd.svg) [CTFd](https://ctfd.io/) is a Capture The Flag (CTF) framework designed for ease of use. + +# Usage Instructions + +### Step 1: Provision AWS resources via Terraform + +``` +terraform init +terraform apply +``` + +### Step 2: Install applications via Ansible playbooks + +- Replace the `s3://bucket-name` with the value of the `s3_bucket_name_ansible_playbooks` output from the Terraform apply. +- Replace the `--instance-ids` values with the corresponding `ec2_cftd_instance_id` and `ec2_owaspjs_instance_id` output values from the Terraform apply. + +``` +aws s3 sync ./ansible s3://bucket-name --include "*.yml" +# Install CFTd +aws ssm send-command --document-name "AWS-RunAnsiblePlaybook" --instance-ids "i-0xxxxxxxxxxxxxxxx" --max-errors 1 --parameters '{"extravars":["SSM=True"],"check":["False"],"playbook":["s3://bucket-name/playbook_cftd.yml"]}' --timeout-seconds 600 --region ca-central-1 +# Install OWASP Juice Shop +aws ssm send-command --document-name "AWS-RunAnsiblePlaybook" --instance-ids "i-0xxxxxxxxxxxxxxxx" --max-errors 1 --parameters '{"extravars":["SSM=True"],"check":["False"],"playbook":["s3://bucket-name/playbook_owaspjs.yml"]}' --timeout-seconds 600 --region ca-central-1 +``` From 4f3a7afd5283cf703a2cff4c269a19bb2cd32e1d Mon Sep 17 00:00:00 2001 From: Greg Sienkiewicz Date: Sun, 22 Oct 2023 22:11:43 -0400 Subject: [PATCH 05/10] remove RDS resources Switching over to the bundled postgres container in the docker-componse definition with cftd. --- outputs.tf | 18 +++++++++--------- rds.tf | 42 ------------------------------------------ sg.tf | 26 -------------------------- variables.tf | 29 ++++++++--------------------- vpc.tf | 24 ------------------------ 5 files changed, 17 insertions(+), 122 deletions(-) delete mode 100644 rds.tf diff --git a/outputs.tf b/outputs.tf index 6ee29ec..1c650ba 100644 --- a/outputs.tf +++ b/outputs.tf @@ -8,17 +8,17 @@ output "owaspjs_private_dns" { value = aws_instance.owaspjs.private_dns } -output "rds_hostname" { - description = "RDS instance hostname" - value = aws_db_instance.cftd.address +output "s3_bucket_name_ansible_playbooks" { + description = "The Ansible playbook S3 bucket name" + value = aws_s3_bucket.ansible.bucket } -output "rds_port" { - description = "RDS instance port" - value = aws_db_instance.cftd.port +output "ec2_cftd_instance_id" { + description = "The EC2 instance ID of the CTFd instance" + value = aws_instance.ctfd.id } -output "rds_username" { - description = "RDS instance username" - value = aws_db_instance.cftd.username +output "ec2_owaspjs_instance_id" { + description = "The EC2 instance ID of the OWASP Juice Shop instance" + value = aws_instance.owaspjs.id } diff --git a/rds.tf b/rds.tf deleted file mode 100644 index 84d8ee7..0000000 --- a/rds.tf +++ /dev/null @@ -1,42 +0,0 @@ -###======================== CTF DB ====================== ### - -resource "aws_kms_key" "rds" { - description = "CFTd DB KMS key" - - deletion_window_in_days = 7 - key_usage = "ENCRYPT_DECRYPT" - enable_key_rotation = true - multi_region = true - - tags = { - Name = "CFTd KMS Key" - } -} - -resource "aws_db_subnet_group" "cftd" { - name = "cftd_db_subnet_group" - subnet_ids = [aws_subnet.rds_a.id, aws_subnet.rds_b.id] - - tags = { - Name = "CFTd DB Subnet Group" - } -} - -/* -resource "aws_db_instance" "cftd" { - identifier = "ctfd-db" - instance_class = "db.t3.micro" - allocated_storage = 5 - engine = "mariadb" - engine_version = "10.6.14" - multi_az = false - storage_encrypted = true - kms_key_id = aws_kms_key.rds.arn - username = "cftd" - password = var.db_password - db_subnet_group_name = aws_db_subnet_group.cftd.name - vpc_security_group_ids = [aws_security_group.rds.id] - publicly_accessible = false - skip_final_snapshot = true -} -*/ diff --git a/sg.tf b/sg.tf index 8a45f4c..7047627 100644 --- a/sg.tf +++ b/sg.tf @@ -85,29 +85,3 @@ resource "aws_security_group" "alb" { Name = "sg-ctf-alb" } } - -resource "aws_security_group" "rds" { - name = "CTF RDS Security Group" - description = "CTF RDS Security Group" - vpc_id = aws_vpc.ctf.id - - ingress { - description = "RDS from internal SG" - from_port = 3306 - to_port = 3306 - protocol = "tcp" - security_groups = [aws_security_group.ctf.id] - } - - egress { - description = "Allow All Traffic Outbound" - from_port = 0 - to_port = 0 - protocol = "-1" - cidr_blocks = ["0.0.0.0/0"] - } - - tags = { - Name = "sg-ctf-rds" - } -} diff --git a/variables.tf b/variables.tf index 8583cc3..e280dda 100644 --- a/variables.tf +++ b/variables.tf @@ -5,6 +5,13 @@ variable "aws_region" { default = "ca-central-1" } +variable "ansible_playbook_bucket_name" { + description = "The name of the S3 bucket to hold the Ansible playbooks." + type = string + + default = "trust-ctf-ansible-playbooks" +} + variable "aws_availability_zone_a" { description = "The availability zone to deploy into (defaults to 'ca-central-1a' for legal reasons)" type = string @@ -61,31 +68,11 @@ variable "subnet_cftd_cidr_block" { default = "192.168.42.128/27" } -variable "subnet_a_rds_cidr_block" { - description = "The IPv4 CIDR block for the RDS subnet A" - type = string - - default = "192.168.42.160/27" -} - -variable "subnet_b_rds_cidr_block" { - description = "The IPv4 CIDR block for the RDS subnet B" - type = string - - default = "192.168.42.208/28" -} - variable "instance_type" { description = "The instance type to use for the CTFd and OWASP Juice Shop EC2 instances" type = string - default = "t2.micro" -} - -variable "db_password" { - description = "RDS user password" - type = string - sensitive = true + default = "t2.medium" } # AWS Managed Rules rule groups list diff --git a/vpc.tf b/vpc.tf index c6018c3..06d628e 100644 --- a/vpc.tf +++ b/vpc.tf @@ -131,30 +131,6 @@ resource "aws_subnet" "owaspjs" { } } -resource "aws_subnet" "rds_a" { - vpc_id = aws_vpc.ctf.id - cidr_block = var.subnet_a_rds_cidr_block - availability_zone = var.aws_availability_zone_a - - enable_resource_name_dns_a_record_on_launch = true - - tags = { - Name = "RDS | Subnet ${var.aws_availability_zone_a}" - } -} - -resource "aws_subnet" "rds_b" { - vpc_id = aws_vpc.ctf.id - cidr_block = var.subnet_b_rds_cidr_block - availability_zone = var.aws_availability_zone_b - - enable_resource_name_dns_a_record_on_launch = true - - tags = { - Name = "RDS | Subnet ${var.aws_availability_zone_b}" - } -} - resource "aws_route_table_association" "public_a" { subnet_id = aws_subnet.public_a.id route_table_id = aws_route_table.ctf.id From 5f377d3b866d0ddb08df25340c035fe9d4f35cfa Mon Sep 17 00:00:00 2001 From: Greg Sienkiewicz Date: Mon, 23 Oct 2023 12:32:28 -0400 Subject: [PATCH 06/10] update README.md aws ssm send-command parameters --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0631fe9..253aeb9 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ terraform apply ``` aws s3 sync ./ansible s3://bucket-name --include "*.yml" # Install CFTd -aws ssm send-command --document-name "AWS-RunAnsiblePlaybook" --instance-ids "i-0xxxxxxxxxxxxxxxx" --max-errors 1 --parameters '{"extravars":["SSM=True"],"check":["False"],"playbook":["s3://bucket-name/playbook_cftd.yml"]}' --timeout-seconds 600 --region ca-central-1 +aws ssm send-command --document-name "AWS-RunAnsiblePlaybook" --instance-ids "i-0xxxxxxxxxxxxxxxx" --max-errors 1 --parameters '{"extravars":["SSM=True"],"check":["False"],"playbookurl":["s3://bucket-name/playbook_cftd.yml"]}' --timeout-seconds 600 --region ca-central-1 # Install OWASP Juice Shop -aws ssm send-command --document-name "AWS-RunAnsiblePlaybook" --instance-ids "i-0xxxxxxxxxxxxxxxx" --max-errors 1 --parameters '{"extravars":["SSM=True"],"check":["False"],"playbook":["s3://bucket-name/playbook_owaspjs.yml"]}' --timeout-seconds 600 --region ca-central-1 +aws ssm send-command --document-name "AWS-RunAnsiblePlaybook" --instance-ids "i-0xxxxxxxxxxxxxxxx" --max-errors 1 --parameters '{"extravars":["SSM=True"],"check":["False"],"playbookurl":["s3://bucket-name/playbook_owaspjs.yml"]}' --timeout-seconds 600 --region ca-central-1 ``` From c553f9069a483ce0a72a5ce02900e337a8bceefc Mon Sep 17 00:00:00 2001 From: Greg Sienkiewicz Date: Mon, 23 Oct 2023 13:02:29 -0400 Subject: [PATCH 07/10] update ansible playbooks --- ansible/playbook_cftd.yml | 2 +- ansible/playbook_juice.yml | 39 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 ansible/playbook_juice.yml diff --git a/ansible/playbook_cftd.yml b/ansible/playbook_cftd.yml index f30be1e..6630ba0 100644 --- a/ansible/playbook_cftd.yml +++ b/ansible/playbook_cftd.yml @@ -23,7 +23,7 @@ state: started enabled: true - - name: Add cftd user to docker group + - name: Add ssm-user user to docker group ansible.builtin.user: name: ssm-user groups: docker diff --git a/ansible/playbook_juice.yml b/ansible/playbook_juice.yml new file mode 100644 index 0000000..dda9e9e --- /dev/null +++ b/ansible/playbook_juice.yml @@ -0,0 +1,39 @@ +--- +- name: OWASP Juice Shop + gather_facts: false + remote_user: ssm-user + become: true + hosts: all + + tasks: + - name: Install Docker + become: true + dnf: + name: docker + state: present + + - name: Enable Docker service + become: true + ansible.builtin.systemd: + name: docker.service + state: started + enabled: true + + - name: Add ssm-user user to docker group + become: true + ansible.builtin.user: + name: ssm-user + groups: docker + append: yes + + - name: Pull bkimminich/juice-shop docker image + community.docker.docker_image: + name: bkimminich/juice-shop + source: pull + + - name: Launch OWASP Juice Shop container + community.docker.docker_container: + name: juice-shop + image: bkimminich/juice-shop + ports: + - "80:3000" From dda456e349c942e43dcbeae40d6deea39ad91de2 Mon Sep 17 00:00:00 2001 From: Greg Sienkiewicz Date: Mon, 23 Oct 2023 13:03:37 -0400 Subject: [PATCH 08/10] install ansible on ec2 instances via user data --- ec2.tf | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/ec2.tf b/ec2.tf index 51e6a30..d744ccd 100644 --- a/ec2.tf +++ b/ec2.tf @@ -38,6 +38,12 @@ resource "aws_instance" "ctfd" { iam_instance_profile = aws_iam_instance_profile.ctf.id + user_data = <<-EOF + #!/bin/bash + dnf update -y + dnf install -y ansible + EOF + tags = { Name = "CTFd" } @@ -73,6 +79,12 @@ resource "aws_instance" "owaspjs" { iam_instance_profile = aws_iam_instance_profile.ctf.id + user_data = <<-EOF + #!/bin/bash + dnf update -y + dnf install -y ansible + EOF + tags = { Name = "OWASP Juice Shop" } From b602ff6e3b7c53277c0d91aaf49338c1392b208e Mon Sep 17 00:00:00 2001 From: Greg Sienkiewicz Date: Wed, 25 Oct 2023 08:28:30 -0400 Subject: [PATCH 09/10] Update README.md --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 253aeb9..9fe6492 100644 --- a/README.md +++ b/README.md @@ -31,3 +31,9 @@ aws ssm send-command --document-name "AWS-RunAnsiblePlaybook" --instance-ids "i- # Install OWASP Juice Shop aws ssm send-command --document-name "AWS-RunAnsiblePlaybook" --instance-ids "i-0xxxxxxxxxxxxxxxx" --max-errors 1 --parameters '{"extravars":["SSM=True"],"check":["False"],"playbookurl":["s3://bucket-name/playbook_owaspjs.yml"]}' --timeout-seconds 600 --region ca-central-1 ``` + +### Step 3: Configure the Flags + +[juice-shop-ctf-cli (OWASP Juice Shop CTF Extension)](https://www.npmjs.com/package/juice-shop-ctf-cli) + +> The Node package juice-shop-ctf-cli helps you to prepare Capture the Flag events with the OWASP Juice Shop challenges for different popular CTF frameworks. This interactive utility allows you to populate a CTF game server in a matter of minutes. From 1e954be54b28b8f544baf104e6c37a1bfef9023c Mon Sep 17 00:00:00 2001 From: Greg Sienkiewicz Date: Wed, 25 Oct 2023 09:18:46 -0400 Subject: [PATCH 10/10] add NODE ctf env var to properly launch juice-shop --- ansible/playbook_juice.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ansible/playbook_juice.yml b/ansible/playbook_juice.yml index dda9e9e..5f98d90 100644 --- a/ansible/playbook_juice.yml +++ b/ansible/playbook_juice.yml @@ -37,3 +37,5 @@ image: bkimminich/juice-shop ports: - "80:3000" + env: + NODE: "ctf"