From 810cff117101832b053d9b540957426f54b3d864 Mon Sep 17 00:00:00 2001 From: n0mad1k Date: Mon, 12 May 2025 22:39:58 -0400 Subject: [PATCH] working on it --- AWS/c2.yml | 26 +++++++- AWS/redirector.yml | 50 +++++++++------ deploy.py | 136 +++++++++++++++++++++++++++++----------- tasks/install_tools.yml | 6 ++ 4 files changed, 158 insertions(+), 60 deletions(-) diff --git a/AWS/c2.yml b/AWS/c2.yml index 837a144..b9505e6 100644 --- a/AWS/c2.yml +++ b/AWS/c2.yml @@ -14,9 +14,12 @@ instance_type: "{{ aws_instance_type | default('t2.medium') }}" deployment_id: "{{ deployment_id | default('') }}" c2_name: "{{ c2_name | default('s-' + deployment_id) }}" - # Check for shared infrastructure - # Only use shared when C2 and redirector are in the same region - use_shared_infra: "{{ not (c2_region is defined and redirector_region is defined and c2_region != redirector_region) and not c2_only | default(false) | bool and not redirector_only | default(false) | bool }}" + # Define split_regions - only true when regions are explicitly different + split_regions: "{{ c2_region is defined and redirector_region is defined and c2_region != redirector_region }}" + # Only use shared infra when NOT doing split-region deployment + use_shared_infra: "{{ not split_regions and not c2_only | default(false) | bool and not redirector_only | default(false) | bool }}" + # Set correct region variable + aws_c2_region: "{{ c2_region | default(aws_region) }}" # AMI map comes from vars.yaml - add fallback for safety kali_ami_map_fallback: us-east-1: "ami-061b17d332829ab1c" @@ -249,6 +252,22 @@ timeout: 300 state: started + - name: Test SSH and prepare remote environment + block: + - name: Ensure .ansible directory exists with proper permissions + shell: | + ssh -i ~/.ssh/c2deploy_{{ deployment_id }}.pem -o StrictHostKeyChecking=no {{ ami_ssh_user }}@{{ c2_ip }} "sudo mkdir -p /root/.ansible/tmp && sudo chmod 0700 /root/.ansible/tmp && sudo chown {{ ami_ssh_user }}:{{ ami_ssh_user }} /root/.ansible/tmp" + register: ssh_prep + until: ssh_prep is success + retries: 5 + delay: 15 + ignore_errors: yes + delegate_to: localhost + + - name: Display SSH preparation results + debug: + msg: "SSH preparation completed: {{ ssh_prep.stdout | default('No output') }}" + # Test SSH connection directly to verify key is working - name: Test SSH connection to verify key shell: "ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o IdentitiesOnly=yes -i ~/.ssh/c2deploy_{{ deployment_id }}.pem {{ ami_ssh_user }}@{{ c2_ip }} 'echo SSH CONNECTION SUCCESSFUL'" @@ -288,6 +307,7 @@ - name: Configure C2 server hosts: c2servers become: yes + become_user: root gather_facts: true vars_files: - vars.yaml # Add this line to load the variables diff --git a/AWS/redirector.yml b/AWS/redirector.yml index 5a1936a..d486045 100644 --- a/AWS/redirector.yml +++ b/AWS/redirector.yml @@ -9,7 +9,7 @@ - vars.yaml vars: # Default values - ssh_user: "{{ ssh_user | default('ubuntu') }}" # Changed from 'root' to 'ubuntu' + ssh_user: "{{ ssh_user | default('ubuntu') }}" aws_region: "{{ aws_region | default(aws_region_choices | random) }}" instance_type: "{{ aws_instance_type | default('t2.micro') }}" deployment_id: "{{ deployment_id | default('') }}" @@ -41,18 +41,25 @@ - aws_secret_key is defined and aws_secret_key != "" fail_msg: "AWS credentials are required" - # Load shared infrastructure state if available + # Set region for redirector - fix for noop task error + - name: Set region for redirector + set_fact: + aws_redirector_region: "{{ redirector_region | default(aws_region) }}" + + # Load shared infrastructure state if available - fixed implementation - name: Check for shared infrastructure state - stat: - path: "infrastructure_state_{{ deployment_id }}.json" - register: infra_state_file + block: + - name: Check if state file exists + stat: + path: "infrastructure_state_{{ deployment_id }}.json" + register: infra_state_file + + - name: Include vars if file exists + include_vars: + file: "infrastructure_state_{{ deployment_id }}.json" + name: shared_infra + when: infra_state_file.stat.exists | default(false) when: use_shared_infra | bool - - - name: Load shared infrastructure state - include_vars: - file: "infrastructure_state_{{ deployment_id }}.json" - name: shared_infra - when: use_shared_infra | bool and infra_state_file.stat.exists | default(false) # After loading shared infrastructure state - name: Validate shared VPC exists @@ -75,16 +82,11 @@ use_shared_infra: false when: use_shared_infra | bool and vpc_check.vpcs is defined and vpc_check.vpcs | length == 0 - - name: Set region for redirector from shared infra + - name: Set region variables from shared infra set_fact: aws_redirector_region: "{{ shared_infra.region | default(aws_region) }}" when: use_shared_infra | bool and infra_state_file.stat.exists | default(false) - - name: Set default region for redirector - set_fact: - aws_redirector_region: "{{ redirector_region | default(aws_region) }}" - when: not (use_shared_infra | bool and infra_state_file.stat.exists | default(false)) - - name: Set AMI ID for selected region set_fact: ami_id: "{{ ubuntu_ami_map[aws_redirector_region] | default(ubuntu_ami_map['us-east-1']) }}" @@ -194,7 +196,7 @@ state: present register: security_group - # Save infrastructure state for reuse + # Save infrastructure state for reuse - name: Save infrastructure state for reuse copy: content: | @@ -231,6 +233,16 @@ redirector_ip: "{{ redirector_instance.instances[0].public_ip_address }}" redirector_instance_id: "{{ redirector_instance.instances[0].instance_id }}" + - name: Wait for instance initialization + pause: + seconds: 120 + when: redirector_instance.changed + + - name: Set correct permissions on SSH key + file: + path: "~/.ssh/{{ redirector_name }}.pem" + mode: "0600" + - name: Wait for redirector SSH to be available wait_for: host: "{{ redirector_ip }}" @@ -244,7 +256,7 @@ name: "redirector" groups: "redirectors" ansible_host: "{{ redirector_ip }}" - ansible_user: "ubuntu" # Change this from 'root' to 'ubuntu' + ansible_user: "ubuntu" ansible_ssh_private_key_file: "~/.ssh/{{ redirector_name }}.pem" ansible_ssh_common_args: "-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o IdentitiesOnly=yes" ansible_python_interpreter: "/usr/bin/python3" diff --git a/deploy.py b/deploy.py index 3054d03..b778a94 100755 --- a/deploy.py +++ b/deploy.py @@ -1786,46 +1786,99 @@ def cleanup_resources(config, interactive=True): except Exception as e: logging.error(f"Failed to remove SSH public key {pub_key_path}.pub: {e}") - # Use Ansible for cleanup with confirmation set to false - extra_vars = { - "confirm_cleanup": False, # Skip confirmation prompt - "redirector_name": config.get('redirector_name'), - "c2_name": config.get('c2_name'), - "tracker_name": config.get('tracker_name'), - "cleanup_redirector": True, - "cleanup_c2": True, - "cleanup_tracker": config.get('deploy_tracker', False) and not config.get('integrated_tracker', False) - } + # Check for split-region deployment + is_split_region = provider == "aws" and 'redirector_region' in config and 'c2_region' in config and config['redirector_region'] != config['c2_region'] - playbook = f"{provider_dir}/cleanup.yml" - if os.path.exists(playbook): - logging.info(f"Running cleanup playbook: {playbook}") - inventory_path = create_inventory_file(config, "local") + if is_split_region: + logging.info("Detected split-region deployment, cleaning up both regions...") - # Add extra vars to config for cleanup - cleanup_config = config.copy() - cleanup_config.update(extra_vars) - - try: - success, stdout, stderr = run_ansible_playbook( - playbook, inventory_path, cleanup_config, - cleanup_config.get('debug', False) - ) + # Clean up each region separately + regions_to_clean = [config['redirector_region'], config['c2_region']] + for region in regions_to_clean: + region_config = config.copy() + region_config['aws_region'] = region + region_config['selected_region'] = region + region_config['region'] = region - if not success: - logging.error(f"Cleanup playbook failed: {stderr}") - - # Log what we attempted to clean up - logging.error(f"Failed to clean up resources: redirector={config.get('redirector_name')}, c2={config.get('c2_name')}, tracker={config.get('tracker_name')}") - else: - logging.info("Cleanup completed successfully") - except Exception as e: - logging.error(f"Cleanup playbook failed: {e}") - finally: - if os.path.exists(inventory_path): - os.unlink(inventory_path) + logging.info(f"Cleaning up resources in region: {region}") + + # Create inventory for this region + inventory_path = create_inventory_file(region_config, "local") + + # Set confirmation to false for second run + extra_vars = { + "confirm_cleanup": False, + "redirector_name": config.get('redirector_name'), + "c2_name": config.get('c2_name'), + "tracker_name": config.get('tracker_name'), + "cleanup_redirector": True, + "cleanup_c2": True, + "cleanup_tracker": config.get('deploy_tracker', False) and not config.get('integrated_tracker', False), + "aws_region": region + } + + # Add extra vars to config for cleanup + cleanup_config = region_config.copy() + cleanup_config.update(extra_vars) + + playbook = f"{provider_dir}/cleanup.yml" + if os.path.exists(playbook): + try: + success, stdout, stderr = run_ansible_playbook( + playbook, inventory_path, cleanup_config, + cleanup_config.get('debug', False) + ) + + if not success: + logging.error(f"Cleanup playbook failed in region {region}: {stderr}") + except Exception as e: + logging.error(f"Cleanup playbook failed in region {region}: {e}") + finally: + if os.path.exists(inventory_path): + os.unlink(inventory_path) + else: - logging.warning(f"No cleanup playbook found at {playbook}") + # Standard single-region cleanup + # Use Ansible for cleanup with confirmation set to false + extra_vars = { + "confirm_cleanup": False, # Skip confirmation prompt + "redirector_name": config.get('redirector_name'), + "c2_name": config.get('c2_name'), + "tracker_name": config.get('tracker_name'), + "cleanup_redirector": True, + "cleanup_c2": True, + "cleanup_tracker": config.get('deploy_tracker', False) and not config.get('integrated_tracker', False) + } + + playbook = f"{provider_dir}/cleanup.yml" + if os.path.exists(playbook): + logging.info(f"Running cleanup playbook: {playbook}") + inventory_path = create_inventory_file(config, "local") + + # Add extra vars to config for cleanup + cleanup_config = config.copy() + cleanup_config.update(extra_vars) + + try: + success, stdout, stderr = run_ansible_playbook( + playbook, inventory_path, cleanup_config, + cleanup_config.get('debug', False) + ) + + if not success: + logging.error(f"Cleanup playbook failed: {stderr}") + + # Log what we attempted to clean up + logging.error(f"Failed to clean up resources: redirector={config.get('redirector_name')}, c2={config.get('c2_name')}, tracker={config.get('tracker_name')}") + else: + logging.info("Cleanup completed successfully") + except Exception as e: + logging.error(f"Cleanup playbook failed: {e}") + finally: + if os.path.exists(inventory_path): + os.unlink(inventory_path) + else: + logging.warning(f"No cleanup playbook found at {playbook}") # Clean up SSH key if we generated one ssh_key = config.get('ssh_key') @@ -2332,8 +2385,8 @@ def generate_deployment_info(config, success=True): return log_file def deploy_cross_provider(config, redirector_provider, c2_provider): - """Deploy infrastructure across multiple providers""" - # Create copies of config for each provider + """Deploy infrastructure across multiple providers or regions""" + # Create copies of config for each provider/region redirector_config = config.copy() redirector_config['provider'] = redirector_provider redirector_config['c2_only'] = False @@ -2347,8 +2400,15 @@ def deploy_cross_provider(config, redirector_provider, c2_provider): # Set specific regions if provided if config.get('redirector_region'): redirector_config['region'] = config['redirector_region'] + # For AWS, set both region variables + if redirector_provider == 'aws': + redirector_config['aws_region'] = config['redirector_region'] + if config.get('c2_region'): c2_config['region'] = config['c2_region'] + # For AWS, set both region variables + if c2_provider == 'aws': + c2_config['aws_region'] = config['c2_region'] logging.info(f"Cross-provider deployment: Redirector using {redirector_provider} in {redirector_config.get('region', 'default region')}") diff --git a/tasks/install_tools.yml b/tasks/install_tools.yml index e0763a8..cf65cf9 100644 --- a/tasks/install_tools.yml +++ b/tasks/install_tools.yml @@ -2,6 +2,12 @@ # Common task for installing offensive security tools # Shared across all providers +- name: Force tools directory to root regardless of user + set_fact: + home_dir: "/root" + tools_dir: "/root/Tools" + when: provider == "aws" + - name: Determine home directory path set_fact: home_dir: "{{ (ansible_user == 'root') | ternary('/root', '/home/' + ansible_user) }}"