heat_template_version: 2018-03-02

description: Student Op Stations - This is the Unified Student Ops Station YAML. Module configurations are made with each modules setup script and not in this YAML.

parameters:
  domain:
    type: string
    label: Domain
    description: Set as '10.50.255.254' for VTA or '172.20.255.254' for VTA-DEV
    default: 10.50.255.254
    hidden: false

  username:
    type: string
    label: User Name
    description: Sets the login username for the instances
    default: student
    hidden: false

  password:
    type: string
    label: Password
    description: Sets the Login Password for the instances
    default: password
    hidden: true

  vncpass:
    type: string
    label: VNC-Password
    description: Sets the regular VNC connection password
    default: password
    hidden: true

  view_only_password:
    type: string
    label: View-Only-Password
    description: Sets the VNC View Only Password for the instances
    default: view_only_password
    hidden: true

  package_proxy:
    type: string
    label: the URL for the package cache
    default: "http://pkg-cache.bbh.cyberschool.army.mil:3142"
    hidden: true

resources:
  rand_string:
    type: OS::Heat::RandomString
    properties:
      length: 4

  # ----- Ops Network Configuration Start ----- #
  ops_network:
    type: OS::Neutron::Net
    properties:
      name:
        str_replace:
          template: ops_network_RAND
          params:
            RAND: { get_resource: rand_string }
      admin_state_up: true
      shared: false

  ops_subnet:
    type: OS::Neutron::Subnet
    depends_on: ops_network
    properties:
      cidr: 192.168.65.0/27
      gateway_ip:  192.168.65.30
      dns_nameservers: [{ get_param: domain }]
      enable_dhcp: true
      host_routes: [ ]
      ip_version: 4
      name:
        str_replace:
          template: ops_subnet_RAND
          params:
            RAND: { get_resource: rand_string }
      network_id:
        get_resource: ops_network
  # ----- Ops Network Configuration End ----- #

  # ----- Ops Router Configuration Start ----- #
  ops_neutron_router:
    type: OS::Neutron::Router
    properties:
      name:
        str_replace:
          template: ops_neutron_router_RAND
          params:
            RAND: { get_resource: rand_string }
      external_gateway_info:
        network: public

  ops_neutron_router_interface:
    type: OS::Neutron::RouterInterface
    properties:
      router_id: { get_resource: ops_neutron_router }
      subnet_id: { get_resource: ops_subnet }
  # ----- Ops Router Configuration Start ----- #

  # ----- Windows Analyst Workstation Configuration Start ----- #
  windows_opstation:
    type: OS::Nova::Server
    properties:
      diskConfig: AUTO
      flavor: m6.medium.4
      image: windows_2004_vta
      name:
        str_replace:
          template: windows_opstation_RAND
          params:
            RAND: { get_resource: rand_string }
      networks:
        - port: { get_resource: windows_opstation_port }
      user_data_format: RAW
      user_data:
        str_replace:
          template: |
            #ps1_sysnative

            #Before creating image, Windows will need to be updated to the newest version via GUI and unistall oneDrive. 
            #Immunity Debugger will need to be installed manually using the following link https://debugger.immunityinc.com/ID_register.py  
            #Mona plug-in will also need to be installed https://github.com/corelan/mona

            Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Force
            $ErrorActionPreference = 'SilentlyContinue'

            #----Turn off Firewall
            Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled False
            Set-NetFirewallRule -DisplayGroup "Network Discovery" -Enabled True
            Set-NetFirewallRule -DisplayGroup "remote desktop" -Enabled True

            #----Enable SSH
            Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
            Start-Service sshd
            Set-Service -Name sshd -StartupType Automatic

            #----Disable Windows Updates (the "official" Microsoft way)
            $cmd = @()
            $cmd += 'New-Item "HKLM:\SOFTWARE\Policies\Microsoft\Windows" -Name "WindowsUpdate"'
            $cmd += 'New-Item "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" -Name "AU"'
            $cmd += 'New-ItemProperty "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" -Name "NoAutoUpdate" -Type Dword -Value "1"'
            foreach($c in $cmd) {
              Write-Host $c
              Invoke-Expression $c
            }

            #----Update PowerShell Help
            Update-Help -Force

            #----Turn off Windows Defender
            New-Item -path 'HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection'
            New-ItemProperty -path 'HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection'-Name 'DisableRealtimeMonitoring' -Type Dword -Value 1
            set-ItemProperty -Path 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System' -name "dontdisplaylastusername" -Value 1

            #----Disable OOBE Network Discovery
            Set-NetConnectionProfile -Name "*" -NetworkCategory Private

            #----Create User <lastname>, password set to password, add to admin group
            New-LocalUser -Name "$user" -Password (ConvertTo-SecureString -AsPlaintext -String "$pass" -Force)
            Add-LocalGroupMember -Group "Administrators" -Member "$user"
            Add-LocalGroupMember -Group "Remote Desktop Users" -Member "$user"
            Set-LocalUser "$user" -PasswordNeverExpires $TRUE

            #----Disable Default Admin Accounts
            Disable-LocalUser -Name "administrator"
            Disable-LocalUser -Name "admin"

            #----Rename computer
            Rename-computer -newname "win-ops"

            #----Set TimeZone to EST
            Set-TimeZone "Eastern Standard Time"

            #----Downloads and installs Google Chrome
            Invoke-WebRequest -Uri "http://dl.google.com/chrome/install/375.126/chrome_installer.exe" -Outfile "C:\chrome_installer.exe"
            & "C:\chrome_installer.exe" /silent /install

            #-----install choco
            Set-ExecutionPolicy Bypass -Scope Process -Force
            iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))

            #-----Install tightvnc as service with regular connection and view only connection
            choco install tightvnc -y --installArguments 'SERVER_REGISTER_AS_SERVICe=1 SET_ACCEPTRFBCONNECTIONS=1 VALUE_OF_ACCEPTRFBCONNECTIONS=1 SET_ALWAYSSHARED=1 VALUE_OF_ALWAYSSHARED=1 SET_DISCONNECTACTION=+1 VALUE_OF_DISCONNECTACTION=1 SET_USECONTROLAUTHENTICATION=1 VALUE_OF_USECONTROLAUTHENTICATION=1 SET_USEVNCAUTHENTICATION=1 VALUE_OF_USEVNCAUTHENTICATION=1  SET_CONTROLPASSWORD=1 VALUE_OF_CONTROLPASSWORD=$pass SET_PASSWORD=1 VALUE_OF_PASSWORD=$vncpass SET_VIEWONLYPASSWORD=1 VALUE_OF_VIEWONLYPASSWORD=$vncviewpass'

            #----- Install VcXsrv & PuTTY for X connections to Windows
            choco install vcxsrv putty -y
            reg add "HKLM\Software\Microsoft\Windows\CurrentVersion\Run" /V VcXsrv /D "C:\Progra~1\VcXsrv\vcxsrv.exe :0 -multiwindow -clipboard -wgl"
            choco install vscode -y
            choco install ghidra ida-free -yfx
            choco upgrade ghidra ida-free -yfx
            choco install sysinternals -yfx
            
            exit 1001
          params:
            $user: { get_param: username }
            $pass: { get_param: password }
            $vncpass: { get_param: vncpass }
            $vncviewpass: { get_param: view_only_password }
            $domain: { get_param: domain}
  # ----- Windows Analyst Workstation Configuration End ----- #

  # ----- Windows Analyst Workstation Port Configuration Start ----- #
  windows_opstation_port:
    type: OS::Neutron::Port
    description: Windows OpStation IP
    properties:
      name:
        str_replace:
          template: windows_opstation_port_RAND
          params:
            RAND: { get_resource: rand_string }
      network_id: { get_resource: ops_network }
      fixed_ips:
      #- subnet_id: {get_resource: ops_subnet }
      - ip_address: 192.168.65.10
      port_security_enabled: false

  windows_opstation_float_ip:
    type: OS::Neutron::FloatingIP
    description: Windows OpStation Floating IP
    depends_on: ops_neutron_router
    properties: { floating_network: public }

  windows_opstation_float_ip_assoc:
    type: OS::Neutron::FloatingIPAssociation
    depends_on: ops_neutron_router_interface
    properties:
      floatingip_id: { get_resource: windows_opstation_float_ip }
      port_id: { get_resource: windows_opstation_port }
  # ----- Windows Analyst Workstation Port Configuration End ----- #

  # ----- Linux Analyst Workstation Configuration Start ----- #
  linux_opstation:
    type: OS::Nova::Server
    properties:
      name:
        str_replace:
          template: linux_opstation_RAND
          params:
            RAND: { get_resource: rand_string }
      image: ubuntu_18.04.4_vta
      flavor: m6.medium.4
      networks:
        - port: { get_resource: linux_opstation_port }
      diskConfig: AUTO
      config_drive: true
      user_data_format: RAW
      user_data:
        str_replace:
          template: |
            #!/bin/bash

            # ----- CREATES USER GROUPS
            echo "root:$pass" | chpasswd
            useradd -m -U -s /bin/bash $user
            usermod -aG sudo $user
            echo "$user:$pass" | chpasswd

            # --- disable daily upgrade and update
            systemctl stop apt-daily.service
            systemctl stop apt-daily.timer
            systemctl stop apt-daily-upgrade.timer
            systemctl disable apt-daily.service
            systemctl disable apt-daily.timer
            systemctl disable apt-daily-upgrade.timer
            systemctl kill --kill-who=all apt-daily.service

            export DEBIAN_FRONTEND=noninteractive

            echo "domain vta" > /etc/resolv.conf
            echo "search vta" >>/etc/resolv.conf
            echo "nameserver $domain" >>/etc/resolv.conf

            # ----- ENABLE SUDO NOPASSWD
            sed -i '/# %wheel        ALL=(ALL)       NOPASSWD: ALL/ c\%wheel        ALL=(ALL)       NOPASSWD: ALL' /etc/sudoers

            # ----- ENABLES SSH
            sed -i '/ssh_pwauth:   0/ c\ssh_pwauth:   1' /etc/cloud/cloud.cfg
            sed -i '/PasswordAuthentication no/ c\PasswordAuthentication yes' /etc/ssh/sshd_config
            sed -i '/#PermitRootLogin prohibit-password/ c\PermitRootLogin yes' /etc/ssh/sshd_config
            sed -i '/#Port 22/ c\Port 22' /etc/ssh/sshd_config
            sed -i '/#AllowTcpForwarding yes/AllowTcpForwarding yes/' /etc/ssh/sshd_config
            service sshd restart

            # ----- CREATES USER GROUPS
            echo "root:$pass" | chpasswd
            useradd -m -U -s /bin/bash $user
            usermod -aG sudo $user
            echo "$user:$pass" | chpasswd

            # enable APT proxy/mirror to speed things up
            echo 'Acquire::http { Proxy "$packageproxy"; }' >> /etc/apt/apt.conf.d/00aptproxy
            sed -i 's/nova.clouds.archive.ubuntu.com/atl.mirrors.clouvider.net/g' /etc/apt/sources.list

            # ----- updates

            apt-get update -y
            apt-get upgrade -y

            # ----- vnc dependencies

            apt install -y expect

            # ----- Begin install tightvnc as service with regular connection and view only connection
            apt install xfce4 xfce4-goodies xorgxrdp -y
            apt install -y tightvncserver
            apt-get install tigervnc-common -y


            vncserver -kill :1

            prog=/usr/bin/vncpasswd

            /usr/bin/expect <<EOF
            spawn "$prog"
            expect "Password:"
            send "$vncpass\r"
            expect "Verify:"
            send "$vncpass\r"
            expect "Would you like to enter a view-only password (y/n)?"
            send "y\r"
            expect "Password:"
            send "$vncviewpass\r"
            expect "Verify:"
            send "$vncviewpass\r"
            expect eof
            exit
            EOF

            touch /root/.vnc/xstartup
            echo '#!/bin/bash' > /root/.vnc/xstartup
            echo "xrdb $HOME/.Xresources" >> /root/.vnc/xstartup
            echo "startxfce4 &" >> /root/.vnc/xstartup

            chmod +x /root/.vnc/xstartup

            touch /etc/systemd/system/vncserver@.service
            echo "[Unit]" >> /etc/systemd/system/vncserver@.service
            echo "Description=Start TightVNC server at startup" >> /etc/systemd/system/vncserver@.service
            echo "After=syslog.target network.target" >> /etc/systemd/system/vncserver@.service
            echo "[Service]" >> /etc/systemd/system/vncserver@.service
            echo "Type=forking" >> /etc/systemd/system/vncserver@.service
            echo "User=root" >> /etc/systemd/system/vncserver@.service
            echo "Group=root" >> /etc/systemd/system/vncserver@.service
            echo "WorkingDirectory=/root" >> /etc/systemd/system/vncserver@.service
            echo "PIDFile=/root/.vnc/%H:%i.pid" >> /etc/systemd/system/vncserver@.service
            echo "ExecStartPre=-/usr/bin/vncserver -kill :%i > /dev/null 2>&1" >> /etc/systemd/system/vncserver@.service
            echo "ExecStart=/usr/bin/vncserver -localhost no -depth 24 -geometry 1280x800 :%i" >> /etc/systemd/system/vncserver@.service
            echo "ExecStop=/usr/bin/vncserver -kill :%i" >> /etc/systemd/system/vncserver@.service
            echo "[Install]" >> /etc/systemd/system/vncserver@.service
            echo "WantedBy=multi-user.target" >> /etc/systemd/system/vncserver@.service

            systemctl daemon-reload

            systemctl enable vncserver@1.service

            # ----- End tightvnc install and setup

            # ----- module scripts directory

            mkdir /module_scripts

            # ----- grab OS, NET, and SEC configs

            #operating systems
            wget https://git.cybbh.space/CCTC/students/-/raw/master/ops_stations/scripts/os_linux_setup.sh
            mv os_linux_setup.sh /module_scripts/

            #networking
            wget https://git.cybbh.space/CCTC/students/-/raw/master/ops_stations/scripts/net_linux_setup.sh
            mv net_linux_setup.sh /module_scripts/

            # security
            wget https://git.cybbh.space/CCTC/students/-/raw/master/ops_stations/scripts/sec_linux_setup.sh
            mv sec_linux_setup.sh /module_scripts/

            # ------ run all module scripts
            for f in /module_scripts/*.sh; do  # or wget-*.sh instead of *.sh
                bash "$f" -H
            done

            # Blank Horizon SPICE console fix (can remove upon transition to VNC)
            echo "X-GNOME-Autostart-enabled=false" > /etc/xdg/autostart/spice-vdagent.desktop
            echo "X-GNOME-Autostart-enabled=false" > /usr/share/gdm/autostart/LoginWindow/spice-vdagent.desktop
            systemctl stop spice-vdagent
            systemctl disable spice-vdagent

            # Pull the Float-IP from Gateway to save to student home
            curl -o /home/student/float-ip.txt http://192.168.65.30/metadata/float-ip

            reboot

          params:
            $user: { get_param: username }
            $pass: { get_param: password }
            $vncpass: { get_param: vncpass }
            $vncviewpass: { get_param: view_only_password }
            $domain: { get_param: domain}
            $packageproxy: { get_param: package_proxy }
  # ----- Linux Analyst Workstation Configuration End ----- #


  # ----- Linux Analyst Workstation Port Configuration Start ----- #
  linux_opstation_port:
    type: OS::Neutron::Port
    description: Linux OpStation IP
    properties:
      name:
        str_replace:
          template: linux_opstation_port_RAND
          params:
            RAND: { get_resource: rand_string }
      network_id: { get_resource: ops_network }
      fixed_ips:
      #- subnet_id: {get_resource: ops_subnet }
      - ip_address: 192.168.65.20
      port_security_enabled: false

  linux_opstation_float_ip:
    type: OS::Neutron::FloatingIP
    description: Linux OpStation Floating IP
    depends_on: ops_neutron_router
    properties: { floating_network: public }

  linux_opstation_float_ip_assoc:
    type: OS::Neutron::FloatingIPAssociation
    depends_on: ops_neutron_router_interface
    properties:
      floatingip_id: { get_resource: linux_opstation_float_ip }
      port_id: { get_resource: linux_opstation_port }
  # ----- Linux Analyst Workstation Configuration End ----- #