---
# Common tasks for configuring C2 server with Havoc C2 and EDR evasion
# Shared across all providers

- name: Update apt cache
  apt:
    update_cache: yes

- name: Disable default Kali MOTD
  file:
    path: "{{ ansible_env.HOME }}/.hushlogin"
    state: touch
    mode: '0644'
  when: ansible_distribution == "Kali GNU/Linux"

- name: Set a custom MOTD
  template:
    src: "../../common/templates/motd.j2"
    dest: /etc/motd
    owner: root
    group: root
    mode: '0644'

- name: Install base utilities and tools via apt
  apt:
    name:
      - git
      - wget
      - curl
      - unzip
      - python3-pip
      - python3-venv
      - tmux
      - pipx
      - nmap
      - tcpdump
      - hydra
      - john
      - hashcat
      - sqlmap
      - gobuster
      - dirb
      - enum4linux
      - dnsenum
      - seclists
      - responder
      - golang
      - proxychains
      - tor
      - crackmapexec
      - jq
      - build-essential
      - zip
      - unzip
      - postfix
      - net-tools
      - certbot
      - opendkim
      - opendkim-tools
      - dovecot-core
      - dovecot-imapd
      - dovecot-pop3d
      - dovecot-sieve
      - dovecot-managesieved
      - yq
      - build-essential
      # Additional Havoc C2 dependencies
      - mingw-w64
      - nasm
      - cmake
      - ninja-build
      - libfontconfig1
      - libglu1-mesa-dev
      - libgtest-dev
      - libspdlog-dev
      - libboost-all-dev
      - libncurses5-dev
      - libgdbm-dev
      - libssl-dev
      - libreadline-dev
      - libffi-dev
      - libsqlite3-dev
      - libbz2-dev
      - mesa-common-dev
      - qtbase5-dev
      - qtchooser
      - qt5-qmake
      - qtbase5-dev-tools
      - libqt5websockets5
      - libqt5websockets5-dev
    state: present

- name: Create directories for operational scripts
  file:
    path: "{{ item }}"
    state: directory
    mode: '0700'
    owner: root
    group: root
  with_items:
    - /root/Tools
    - /root/Tools/beacons
    - /root/Tools/payloads

- name: Copy operational scripts
  copy:
    src: "{{ item }}"
    dest: "/root/Tools/{{ item | basename }}"
    mode: '0700'
    owner: root
    group: root
  with_items:
    - "../../../common/files/clean-logs.sh"
    - "../../../common/files/secure-exit.sh"
    - "../files/havoc_installer.sh"
    - "../files/havoc_shell_handler.sh"
    - "../files/secure_payload_sync.sh"

- name: Copy post-install script
  copy:
    src: "../../../common/files/post_install_c2.sh"
    dest: "/root/Tools/post_install_c2.sh"
    mode: '0700'
    owner: root
    group: root

- name: Copy port randomization script
  copy:
    src: "../../../common/files/randomize_ports.sh"
    dest: "/root/Tools/randomize_ports.sh"
    mode: '0700'
    owner: root
    group: root

- name: Create post-install instructions
  template:
    src: "../../common/templates/POST_INSTALL_INSTRUCTIONS.txt.j2"
    dest: "/root/POST_INSTALL_INSTRUCTIONS.txt"
    mode: '0644'
    owner: root
    group: root

- name: Set up systemd timer for payload sync
  shell: |
    cat > /etc/systemd/system/payload-sync.service << 'EOF'
    [Unit]
    Description=Secure Payload Sync Service
    After=network-online.target

    [Service]
    Type=oneshot
    ExecStart=/root/Tools/secure_payload_sync.sh
    User=root
    Group=root
    PrivateTmp=true
    StandardOutput=null

    [Install]
    WantedBy=multi-user.target
    EOF

    cat > /etc/systemd/system/payload-sync.timer << 'EOF'
    [Unit]
    Description=Secure Payload Sync Timer
    Requires=payload-sync.service

    [Timer]
    OnBootSec=5min
    OnUnitActiveSec=30m
    RandomizedDelaySec=30m
    Persistent=true

    [Install]
    WantedBy=timers.target
    EOF

    systemctl daemon-reload
    systemctl enable payload-sync.timer
    systemctl start payload-sync.timer

- name: Install Havoc C2 Framework
  shell: "/root/Tools/havoc_installer.sh"
  args:
    creates: "/root/Tools/Havoc"
  async: 1800  # Allow 30 minutes for completion
  poll: 0      # Don't wait for completion
  register: havoc_installation_job

- name: Wait for Havoc installation to complete
  async_status:
    jid: "{{ havoc_installation_job.ansible_job_id }}"
  register: job_result
  until: job_result.finished
  retries: 60  # Check every 30 seconds for up to 30 minutes
  delay: 30
  when: havoc_installation_job is defined

- name: Display Havoc installation output
  debug:
    var: havoc_installation_result.stdout_lines
  when: havoc_installation_result.stdout_lines is defined

- name: Create Havoc payload generation script
  template:
    src: "../templates/generate_havoc_payloads.sh.j2"
    dest: "/root/Tools/generate_havoc_payloads.sh"
    mode: '0700'
    owner: root
    group: root

- name: Create Havoc C2 configuration from template
  template:
    src: "../templates/havoc-config.yaotl.j2"
    dest: "/root/Tools/Havoc/data/havoc.yaotl"
    mode: '0600'
    owner: root
    group: root

- name: Create Linux loader script template
  template:
    src: "../../common/templates/linux_loader.sh.j2" 
    dest: "/root/Tools/linux_loader.template"
    mode: '0644'
    owner: root
    group: root

- name: Create Windows PowerShell loader template
  template:
    src: "../../common/templates/windows_loader.ps1.j2"
    dest: "/root/Tools/windows_loader.template"
    mode: '0644'
    owner: root
    group: root

- name: Create beacon server script from template
  template:
    src: "../templates/serve-havoc-payloads.sh.j2"
    dest: "/root/Tools/serve-havoc-payloads.sh"
    mode: '0700'
    owner: root
    group: root
  vars:
    redirector_subdomain: "{{ redirector_subdomain | default('cdn') }}"
    domain: "{{ domain }}"
    redirector_port: "{{ redirector_port | default('443') }}"

- name: Run port randomization if enabled
  include_tasks: port_randomization.yml
  when: randomize_ports | default(false) | bool

- name: Generate Havoc payloads
  shell: "/root/Tools/generate_havoc_payloads.sh"
  args:
    creates: "/root/Tools/Havoc/payloads/manifest.json"
  register: payload_generation_result
  environment:
    PATH: "{{ ansible_env.PATH }}:/usr/local/bin"
  ignore_errors: yes

- name: Display payload generation output
  debug:
    var: payload_generation_result.stdout_lines
  when: payload_generation_result.stdout_lines is defined

- name: Start payload server
  shell: |
    nohup /root/Tools/serve-havoc-payloads.sh > /dev/null 2>&1 &
  args:
    executable: /bin/bash
  register: beacon_server_result

- name: Create NGINX configuration fragment for redirector
  template:
    src: "../../redirectors/templates/redirector-havoc-fragment.j2"
    dest: "/root/Tools/redirector-config.conf"
    mode: '0644'
    owner: root
    group: root
  vars:
    c2_ip: "{{ ansible_host }}"
    redirector_domain: "{{ redirector_subdomain }}.{{ domain }}"

- name: Create Havoc usage guide
  template:
    src: "../templates/havoc-guide.j2"
    dest: "/root/havoc-guide.txt"
    mode: '0600'
    owner: root
    group: root
  vars:
    c2_ip: "{{ ansible_host }}"
    redirector_domain: "{{ redirector_subdomain }}.{{ domain }}"

- name: Include traffic flow configuration
  include_tasks: "../../common/tasks/traffic_flow_config.yml"

- name: Set up cron job for log cleaning if zero-logs enabled
  cron:
    name: "Clean logs"
    minute: "0"
    hour: "*/6"
    job: "/root/Tools/clean-logs.sh > /dev/null 2>&1"
  when: zero_logs is defined and zero_logs | bool

- name: Ensure SSH key for redirector access is available
  block:
    - name: Copy deployment SSH key to C2 for redirector access (AWS)
      copy:
        src: "~/.ssh/c2deploy_{{ deployment_id }}.pem"
        dest: "/root/.ssh/redirector_key"
        mode: '0600'
        owner: root
        group: root
      when: provider == "aws"
      
    - name: Copy deployment SSH key to C2 for redirector access (non-AWS)
      copy:
        src: "{{ ssh_key_path | replace('.pub', '') }}"
        dest: "/root/.ssh/redirector_key"
        mode: '0600'
        owner: root
        group: root
      when: provider != "aws"
      
    - name: Create SSH config for redirector access
      blockinfile:
        path: /root/.ssh/config
        create: yes
        mode: '0600'
        owner: root
        group: root
        marker: "# {mark} ANSIBLE MANAGED REDIRECTOR CONFIG"
        block: |
          Host redirector
              HostName {{ redirector_ip }}
              User {{ ssh_user | default('root') }}
              IdentityFile /root/.ssh/redirector_key
              StrictHostKeyChecking no
  when: not redirector_only | bool and redirector_ip is defined

# Include integrated tracker tasks if requested
- name: Include integrated tracker setup
  include_tasks: "configure_integrated_tracker.yml"
  when: setup_integrated_tracker | default(false) | bool