diff --git a/Makefile b/Makefile index 73bfe90..0d9c0a9 100644 --- a/Makefile +++ b/Makefile @@ -45,9 +45,9 @@ # - Ensure that Packer and Terragrunt are installed and configured properly before using this Makefile. .PHONY: packer-firewall packer-repository packer-attacker packer-corpsdns packer-ghostserver packer-kafka \ - packer-linuxshare packer-opensearch packer-userpc packer-videoserver packer-webcam \ + packer-linuxshare packer-opensearch packer-userpc packer-videoserver packer-webcam packer-client\ terragrunt-bootstrap terragrunt-attacker terragrunt-lanturtle terragrunt-logging \ - terragrunt-repository terragrunt-videoserver + terragrunt-repository terragrunt-videoserver terragrunt-client PACKER_CMD := packer build --var-file=default.json . PACKER_ROOT := ~/atb-aecid-testbed/packer @@ -106,6 +106,9 @@ packer-webcam: @echo "Running Packer for webcam..." cd $(PACKER_ROOT)/webcam && $(PACKER_CMD) +packer-client: + @echo "Running Packer for client..." + cd $(PACKER_ROOT)/client && $(PACKER_CMD) #----------------- Terragrunt Targets ----------------- terragrunt-bootstrap: @@ -132,6 +135,10 @@ terragrunt-videoserver: @echo "Running Terragrunt for videoserver..." cd $(TERRAGRUNT_ROOT)/videoserver && $(TERRAGRUNT_CMD) +terragrunt-client: + @echo "Running Terragrunt for client..." + cd $(TERRAGRUNT_ROOT)/client && $(TERRAGRUNT_CMD) + diff --git a/ansible/run/scenario6/README.md b/ansible/run/scenario6/README.md new file mode 100644 index 0000000..e69de29 diff --git a/ansible/run/scenario6/files/playbook.yml b/ansible/run/scenario6/files/playbook.yml new file mode 100644 index 0000000..136fbe0 --- /dev/null +++ b/ansible/run/scenario6/files/playbook.yml @@ -0,0 +1,45 @@ +- name: Install Attacker Host + hosts: attacker + become: true + vars: + attacker_user: aecid + attacker_ip: 192.42.1.174 + handlers: + - name: restart dnsmasq + ansible.builtin.service: + name: dnsmasq + state: restarted + delegate_to: inetdns + + - name: restart msfrpcd + ansible.builtin.service: + name: msfrpcd + state: restarted + + tasks: + - name: get user home directory + ansible.builtin.shell: > + getent passwd {{ attacker_user }} | awk -F: '{ print $6 }' + changed_when: false + register: user_home + tags: + - playbooks + + - name: Install dependencies + ansible.builtin.apt: + pkg: + - xz-utils + - coreutils + tags: + - playbooks + + + - name: Configure public DNS + ansible.builtin.copy: + content: "address=/facebock.com/{{ attacker_ip }}\n" + owner: root + dest: /etc/dnsmasq.d/attacker.conf + delegate_to: inetdns + notify: restart dnsmasq + tags: + - playbooks \ No newline at end of file diff --git a/ansible/run/scenario6/gather.yml b/ansible/run/scenario6/gather.yml new file mode 100644 index 0000000..e69de29 diff --git a/ansible/run/scenario6/main.yml b/ansible/run/scenario6/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/ansible/run/scenario6/templates/wrapper.sh.j2 b/ansible/run/scenario6/templates/wrapper.sh.j2 new file mode 100644 index 0000000..df17f0b --- /dev/null +++ b/ansible/run/scenario6/templates/wrapper.sh.j2 @@ -0,0 +1,22 @@ +#!/bin/bash + +project_path="{{ attackmate_dir | default('/home/aecid/attackmate') }}" +session="{{ attackmate_session | default('aecid') }}" +window="{{ attackmate_window | default('attackmate') }}" + +tmux has-session -t ${session} 2> /dev/null +if [ $? == "1" ] +then + echo "Starting session..." + tmuxinator start ${session} --no-attach +fi + +tmux select-window -t ${window} 2> /dev/null +if [ $? == "1" ] +then + echo "Create window" + tmux new-window -n ${window} + tmux send-keys -t "$session" "source ${project_path}/venv/bin/activate" Enter +fi + +tmux send-keys -t "$pane" "attackmate --debug $@" Enter diff --git a/packer/adminpc/playbook/main.yaml b/packer/adminpc/playbook/main.yaml index 8151081..f0a6383 100644 --- a/packer/adminpc/playbook/main.yaml +++ b/packer/adminpc/playbook/main.yaml @@ -26,7 +26,7 @@ rootkeys_private_key_user: aecid rootkeys_private_dir: "/home/aecid/.ssh" - role: mate-desktop - - role: atb-ansible-novnc + - role: novnc - role: atb-ansible-ghostagent-linux vars: ghostsserver_url: "http://192.168.100.122:5000/api" diff --git a/packer/adminpc/playbook/requirements.yml b/packer/adminpc/playbook/requirements.yml index d5e2b35..7cb14cc 100644 --- a/packer/adminpc/playbook/requirements.yml +++ b/packer/adminpc/playbook/requirements.yml @@ -16,7 +16,7 @@ roles: name: mate-desktop - src: https://github.com/ait-testbed/atb-ansible-novnc.git version: v1.0.0 - name: atb-ansible-novnc + name: novnc - src: https://github.com/ait-testbed/atb-ansible-ghostagent-linux.git version: v1.0.0 name: atb-ansible-ghostagent-linux diff --git a/packer/client/README.md b/packer/client/README.md new file mode 100644 index 0000000..b085e41 --- /dev/null +++ b/packer/client/README.md @@ -0,0 +1,29 @@ +# Configuration + +This packer-config generates client image + +# Prebuild + +Create a default.json: + +``` +{ + "base_image" : "ubuntu2204", + "image_name" : "client-image", + "security_group": "default", + "network": "9c480f42-62f2-4f08-a961-38c28fa19346", + "floating_ip_pool": "provider-aecid-208" +} +``` + +# Install requirements + +``` +ansible-galaxy install -r playbook/requirements.yml +``` + +# Build + +``` +packer build -var-file=default.json . +``` diff --git a/packer/client/build.pkr.hcl b/packer/client/build.pkr.hcl new file mode 100644 index 0000000..8faefb5 --- /dev/null +++ b/packer/client/build.pkr.hcl @@ -0,0 +1,26 @@ +build { + sources = ["source.openstack.builder"] + + provisioner "shell" { + inline = [ + "echo 'Waiting for cloud-init to finish...'", + "/usr/bin/cloud-init status --wait" + ] + } + + provisioner "shell" { + script = "scripts/prep-ansible.sh" + } + + provisioner "ansible" { + groups = "${var.ansible_groups}" + playbook_file = "playbook/main.yaml" + user = "${var.build_user}" + use_proxy = false + } + + provisioner "shell" { + execute_command = "chmod +x {{ .Path }}; sudo {{ .Vars }} {{ .Path }}" + script = "scripts/cleanup.sh" + } +} diff --git a/packer/client/default.json.example b/packer/client/default.json.example new file mode 100644 index 0000000..aa3db2d --- /dev/null +++ b/packer/client/default.json.example @@ -0,0 +1,7 @@ +{ + "base_image" : "Ubuntu 22.04", + "image_name" : "atb-client-image", + "security_group": "default", + "network": "653b15f3-c7e1-41bf-99d5-f8ad0f96f959", + "floating_ip_pool": "provider-aecid-208" +} diff --git a/packer/client/packer.pkr.hcl b/packer/client/packer.pkr.hcl new file mode 100644 index 0000000..e09121b --- /dev/null +++ b/packer/client/packer.pkr.hcl @@ -0,0 +1,12 @@ +packer { + required_plugins { + ansible = { + source = "github.com/hashicorp/ansible" + version = "~> 1" + } + openstack = { + version = ">= 1.1.1" + source = "github.com/hashicorp/openstack" + } + } +} diff --git a/packer/client/playbook/files/Nutzungshinweise.odt b/packer/client/playbook/files/Nutzungshinweise.odt new file mode 100644 index 0000000..2ffaa4f Binary files /dev/null and b/packer/client/playbook/files/Nutzungshinweise.odt differ diff --git a/packer/client/playbook/main.yaml b/packer/client/playbook/main.yaml new file mode 100644 index 0000000..d16228c --- /dev/null +++ b/packer/client/playbook/main.yaml @@ -0,0 +1,56 @@ +- name: Install ClientPC + hosts: all + become: true + vars: + linux_user: "judy" + tasks: + - name: Allow password login + ansible.builtin.copy: + dest: /etc/ssh/sshd_config.d/password.conf + content: 'PasswordAuthentication yes' + - name: Copy ODT document to the host + ansible.builtin.copy: + src: Nutzungshinweise.odt + dest: "/home/{{ linux_user }}/Nutzungshinweise.odt" + mode: '0644' + + roles: + - role: aeciduser + vars: + # pass: aecid + aeciduser_pass: "$6$9AqxTPJqYsFXwgPN$xAC4y1Vndk00EaBCuFcJC37BYDYYVAgt9SHymg15KSdKddZnwG.SsQaJvHarH4DYQj3tuboeLa4G5EfL7itcC0" + - role: aecidtools + vars: + aecidtools_user: "aecid" + - role: weaklinuxuser + vars: + weaklinuxuser_user: "{{ linux_user}}" + weaklinuxuser_pass: "garland" + weaklinuxuser_sudo: True + - role: firefox-home + vars: + vars: + install_user: "{{ linux_user }}" + - role: thunderbird + vars: + thunderbird_user: "{{ linux_user}}" + populate_emails: true + - role: libreoffice + vars: + disable_macros_execution: false + macro_security_level: 'low' + - role: mate-desktop + - role: novnc + - role: tightvnc + vars: + vnc_user: "judy" + vnc_password: "garland" + vnc_display: ":1" + vnc_port: 5901 + + + + + + + diff --git a/packer/client/playbook/requirements.yml b/packer/client/playbook/requirements.yml new file mode 100644 index 0000000..4ebe697 --- /dev/null +++ b/packer/client/playbook/requirements.yml @@ -0,0 +1,30 @@ +roles: + - src: https://github.com/ait-testbed/atb-ansible-aeciduser.git + version: v1.0.0 + name: aeciduser + - src: https://github.com/ait-testbed/atb-ansible-aecidtools.git + version: v1.0.0 + name: aecidtools + - src: https://github.com/ait-cs-IaaS/ansible-mate-desktop.git + version: v1.2.1 + name: mate-desktop + - src: https://github.com/ait-testbed/atb-ansible-novnc.git + version: v1.0.0 + name: novnc + - src: https://github.com/ait-testbed/atb-ansible-weaklinuxuser.git + version: v1.0.2 + name: weaklinuxuser + - src: https://github.com/ait-testbed/atb-ansible-thunderbird.git + version: main + name: thunderbird + - src: https://github.com/ait-testbed/acr-ansible-libreoffice-and-macro-security.git + version: master + name: libreoffice + - src: https://github.com/ait-testbed/atb-ansible-firefox-home.git + version: main + name: firefox-home + - src: https://github.com/ait-testbed/atb-ansible-tightvnc.git + version: v1.0.0 + name: tightvnc + + diff --git a/packer/client/scripts/cleanup.sh b/packer/client/scripts/cleanup.sh new file mode 100644 index 0000000..87eaa3e --- /dev/null +++ b/packer/client/scripts/cleanup.sh @@ -0,0 +1,66 @@ +#!/bin/bash + + +# Apt cleanup. +apt-get -y autoremove --purge +apt-get -y clean +apt-get -y autoclean + +DISK_USAGE_BEFORE_CLEANUP=$(df -h) + +# Remove Bash history +unset HISTFILE +rm -f /root/.bash_history +rm -f /home/${SSH_USER}/.bash_history + +# Clean up log files +find /var/log -type f | while read f; do echo -ne "" > "${f}"; done; + +echo "==> Clearing last login information" +>/var/log/lastlog +>/var/log/wtmp +>/var/log/btmp + + +# Whiteout root +count=$(df --sync -kP / | tail -n1 | awk -F ' ' '{print $4}') +let count-- +dd if=/dev/zero of=/tmp/whitespace bs=1024 count=$count || echo "dd exit code $? is suppressed" +rm /tmp/whitespace + +# Whiteout /boot +count=$(df --sync -kP /boot | tail -n1 | awk -F ' ' '{print $4}') +let count-- +dd if=/dev/zero of=/boot/whitespace bs=1024 count=$count || echo "dd exit code $? is suppressed" +rm /boot/whitespace + + +echo '==> Clear out swap and disable until reboot' +set +e +swapuuid=$(/sbin/blkid -o value -l -s UUID -t TYPE=swap) +case "$?" in + 2|0) ;; + *) exit 1 ;; +esac +set -e +if [ "x${swapuuid}" != "x" ]; then + # Whiteout the swap partition to reduce box size + # Swap is disabled till reboot + swappart=$(readlink -f /dev/disk/by-uuid/$swapuuid) + /sbin/swapoff "${swappart}" + dd if=/dev/zero of="${swappart}" bs=1M || echo "dd exit code $? is suppressed" + /sbin/mkswap -U "${swapuuid}" "${swappart}" +fi + +# Zero out the free space to save space in the final image +dd if=/dev/zero of=/EMPTY bs=1M || echo "dd exit code $? is suppressed" +rm -f /EMPTY + +# Add `sync` so Packer doesn't quit too early, before the large file is deleted. +sync + +echo "==> Disk usage before cleanup" +echo ${DISK_USAGE_BEFORE_CLEANUP} + +echo "==> Disk usage after cleanup" +df -h diff --git a/packer/client/scripts/prep-ansible.sh b/packer/client/scripts/prep-ansible.sh new file mode 100644 index 0000000..0782e49 --- /dev/null +++ b/packer/client/scripts/prep-ansible.sh @@ -0,0 +1,6 @@ + +#!/bin/bash + +#sudo echo "sleeping well.. " && sleep 320s +sudo apt-get update +sudo apt-get install python3 -yq diff --git a/packer/client/source.pkr.hcl b/packer/client/source.pkr.hcl new file mode 100644 index 0000000..953a2df --- /dev/null +++ b/packer/client/source.pkr.hcl @@ -0,0 +1,18 @@ +# Sources + +## Build Hosts +source "openstack" "builder" { + flavor = "${var.flavor}" + floating_ip_network = "${var.floating_ip_pool}" + image_name = "${var.timestamp_image ? replace(format("%s-%s", var.image_name, timestamp()), ":","-") : var.image_name}" + networks = ["${var.network}"] +# security_groups = ["${var.security_group}", "default"] + ssh_ip_version = "4" + ssh_username = "${var.build_user}" + source_image_filter { + filters { + name = "${var.base_image}" + } + most_recent = true + } +} diff --git a/packer/client/variables.pkr.hcl b/packer/client/variables.pkr.hcl new file mode 100644 index 0000000..83fb3d6 --- /dev/null +++ b/packer/client/variables.pkr.hcl @@ -0,0 +1,51 @@ +# Input Variables + +variable "ansible_groups" { + type = list(string) + description = "The ansible groups to assign to the build host" + default = ["all"] +} + +variable "base_image" { + type = string + description = "The base image to build from" +} + +variable "flavor" { + type = string + description = "The openstack flavor to use for the build host" + default = "d2-2" +} + +variable "security_group" { + type = string + description = "The security group to use fo the build host (must allow SSH)" +} + +variable "network" { + type = string + description = "The openstack network to use for the build host" +} + +variable "floating_ip_pool" { + type = string + description = "Name of the floating IP pool to use for the build host" +} + +variable "image_name" { + type = string + description = "The name to use for the resulting image" +} + +variable "timestamp_image" { + type = bool + description = "Image name is suffixed with a build timestamp if set to true" + default = true +} + + +variable "build_user" { + type = string + description = "User to use when building the image" + default = "ubuntu" +} diff --git a/terragrunt/client/module/main.tf b/terragrunt/client/module/main.tf new file mode 100644 index 0000000..81cbf45 --- /dev/null +++ b/terragrunt/client/module/main.tf @@ -0,0 +1,60 @@ +terraform { + backend "http" {} +} + +locals { + client_userdata_file = var.client_userdata == null ? "${path.module}/scripts/default.yml" : var.client_userdata +} + + +data "openstack_networking_router_v2" "router" { + name = var.ext_router +} + + +#################################################################### +# +# CREATE INSTANCE for "CLIENT" +# +data "template_file" "userdata_client" { + template = "${file("${local.client_userdata_file}")}" + vars = { + dns_server_address = "${openstack_compute_instance_v2.inet-dns.access_ip_v4}" + } +} + + + +data "template_cloudinit_config" "cloudinitclient" { + count = local.client_userdata_file == null ? 0 : 1 + gzip = false + base64_encode = false + + part { + filename = "init.cfg" + content_type = "text/cloud-config" + content = data.template_file.userdata_client.rendered + } +} + +data "openstack_images_image_v2" "client-image" { + name = var.client_image + most_recent = true +} + +resource "openstack_compute_instance_v2" "client" { + name = "client" + flavor_name = var.client_flavor + key_pair = var.sshkey + image_id = data.openstack_images_image_v2.client-image.id + user_data = local.client_userdata_file == null ? null : data.template_cloudinit_config.cloudinitclient[0].rendered + + + network { + name = "dmz" + fixed_ip_v4 = cidrhost(var.subnet_cidrs["dmz"],100) + } + +} + + diff --git a/terragrunt/client/module/scripts/default.yml b/terragrunt/client/module/scripts/default.yml new file mode 100644 index 0000000..66931a6 --- /dev/null +++ b/terragrunt/client/module/scripts/default.yml @@ -0,0 +1,21 @@ +#cloud-config +system_info: + default_user: + name: aecid + plain_text_passwd: aecid + lock_passwd: False +write_files: + - encoding: b64 + content: IyEvYmluL2Jhc2gKCk5FVFBMQU49Ii9ldGMvbmV0cGxhbi81MC1jbG91ZC1pbml0LnlhbWwiCgpNQUlOSUY9YGlwIGxpbmsgc2hvdyB8IGdyZXAgVVAgfCBncmVwIC12IExPT1BCQUNLIHwgYXdrICd7cHJpbnQgJDJ9JyB8IHJldiB8IGN1dCAtYyAyLSB8IHJldmAKTUFJTk1BQz1gY2F0IC9zeXMvY2xhc3MvbmV0LyRNQUlOSUYvYWRkcmVzc2AKCmZ1bmN0aW9uIHByaW50bmV0Y29uZmlnKCkKewogICAgZWNobyAiICAgICAgICAgICAgbWF0Y2g6IgogICAgZWNobyAiICAgICAgICAgICAgICAgIG1hY2FkZHJlc3M6ICckMSciCgllY2hvICIgICAgICAgICAgICBkaGNwNDogdHJ1ZSIKCWVjaG8gIiAgICAgICAgICAgIGRoY3A0LW92ZXJyaWRlczoiCgllY2hvICIgICAgICAgICAgICAgICAgdXNlLXJvdXRlczogZmFsc2UiCn0KCmVjaG8gIm5ldHdvcms6IiA+ICRORVRQTEFOCmVjaG8gIiAgICBldGhlcm5ldHM6IiA+PiAkTkVUUExBTgplY2hvICIgICAgICAgICRNQUlOSUY6IiA+PiAkTkVUUExBTgplY2hvICIgICAgICAgICAgICBkaGNwNDogdHJ1ZSIgPj4gJE5FVFBMQU4KZWNobyAiICAgICAgICAgICAgbWF0Y2g6IiA+PiAkTkVUUExBTgplY2hvICIgICAgICAgICAgICAgICAgbWFjYWRkcmVzczogJyRNQUlOTUFDJyIgPj4gJE5FVFBMQU4KZm9yIElGIGluIGBpcCBsaW5rIHNob3cgfCBncmVwIERPV04gfCBhd2sgJ3twcmludCAkMn0nIHwgcmV2IHwgY3V0IC1jIDItIHwgcmV2YApkbwplY2hvICIgICAgICAgICRJRjoiID4+ICRORVRQTEFOCnByaW50bmV0Y29uZmlnICQoY2F0IC9zeXMvY2xhc3MvbmV0LyRJRi9hZGRyZXNzKSA+PiAkTkVUUExBTgpkb25lCmVjaG8gIiAgICB2ZXJzaW9uOiAyIiA+PiAkTkVUUExBTgoKZWNobyAibmV0d29yazoge2NvbmZpZzogZGlzYWJsZWR9IiA+IC9ldGMvY2xvdWQvY2xvdWQuY2ZnLmQvOTktZGlzYWJsZS1uZXR3b3JrLWNvbmZpZy5jZmcKCi91c3Ivc2Jpbi9uZXRwbGFuIGFwcGx5Cg== + owner: root:root + path: /root/ifsetup.sh + permissions: '0700' +bootcmd: + - echo "nameserver ${dns_server_address}" > /etc/resolv.conf +runcmd: + - [echo, "nameserver ${dns_server_address}", >, /etc/resolv.conf] + - [ /root/ifsetup.sh ] + - [apt-get, update] + - [apt-get, install, -y, python] + + diff --git a/terragrunt/client/module/variables.tf b/terragrunt/client/module/variables.tf new file mode 100644 index 0000000..0f0c415 --- /dev/null +++ b/terragrunt/client/module/variables.tf @@ -0,0 +1,46 @@ +variable "floating_pool" { + type = string + description = "Pool for floating ip-addresses" +} + +variable "client_userdata" { + type = string + description = "Userdata for the client virtual machine" + default = null +} + +variable "ext_router" { + type = string + description = "name of the external router" +} + +variable "client_flavor" { + type = string + description = "flavor of the client" + default = "d2-2" +} + +variable "client_image" { + type = string + description = "image of the client" +} + +variable "sshkey" { + type = string + description = "ssh-key for administration" +} + +variable "inet_dns" { + type = list(string) + description = "dns servers to configure for the internet" + default = ["1.1.1.1","8.8.8.8"] +} + +variable "subnet_cidrs" { + type = map(string) + description = "CIDRs for various subnets" + default = { + dmz = "172.17.100.0/24" + user = "192.168.50.0/24" + } +} diff --git a/terragrunt/client/module/versions.tf b/terragrunt/client/module/versions.tf new file mode 100644 index 0000000..7611699 --- /dev/null +++ b/terragrunt/client/module/versions.tf @@ -0,0 +1,8 @@ +terraform { + required_providers { + openstack = { + source = "terraform-provider-openstack/openstack" + } + } + required_version = ">= 0.13" +} diff --git a/terragrunt/client/terragrunt.hcl b/terragrunt/client/terragrunt.hcl new file mode 100644 index 0000000..9ecd877 --- /dev/null +++ b/terragrunt/client/terragrunt.hcl @@ -0,0 +1,19 @@ +terraform { + source = ".//module" + + extra_arguments "parallelism" { + commands = ["apply"] + arguments = ["-parallelism=${get_env("TF_VAR_parallelism", "10")}"] + } +} + +inputs = { + ext_router = "taq-router" + sshkey = "testbed-key" + client_image="" +} + + +include { + path = find_in_parent_folders() +} diff --git a/terragrunt/videoserver/module/userpc_variables.tf b/terragrunt/videoserver/module/userpc_variables.tf index 95fbaf2..4569b50 100644 --- a/terragrunt/videoserver/module/userpc_variables.tf +++ b/terragrunt/videoserver/module/userpc_variables.tf @@ -6,7 +6,7 @@ variable "userpc_image" { variable "userpc_flavor" { type = string description = "flavor of the userpc host" - default = "m1.small" + default = "d2-2" } variable "userpc_userdata" {