trying to fix ssh key issue

This commit is contained in:
n0mad1k
2025-05-13 14:23:36 -04:00
parent 67aa819ceb
commit 2386cac0ef
4 changed files with 153 additions and 129 deletions
+33 -18
View File
@@ -87,21 +87,6 @@
- "Using AMI ID: {{ ami_id | default('AMI not defined') }}" - "Using AMI ID: {{ ami_id | default('AMI not defined') }}"
- "Detected SSH user: {{ ami_ssh_user }}" - "Detected SSH user: {{ ami_ssh_user }}"
# Fix: Use the deployment_id key name if c2deploy prefix exists (for consistency with tool scripts)
- name: Create EC2 key pair with consistent naming
amazon.aws.ec2_key:
name: "c2deploy_{{ deployment_id }}"
region: "{{ aws_c2_region }}"
state: present
register: c2_key_pair
- name: Save private key with consistent naming
copy:
content: "{{ c2_key_pair.key.private_key }}"
dest: "~/.ssh/c2deploy_{{ deployment_id }}.pem"
mode: "0600"
when: c2_key_pair.changed and c2_key_pair.key.private_key is defined
# Create new infrastructure only if not using shared # Create new infrastructure only if not using shared
- name: Create VPC - name: Create VPC
amazon.aws.ec2_vpc_net: amazon.aws.ec2_vpc_net:
@@ -212,10 +197,12 @@
# Management access only from operator IP # Management access only from operator IP
- proto: tcp - proto: tcp
ports: 22 ports: 22
cidr_ip: "{{ operator_ip }}/32" cidr_ip: "{{ operator_ip }}"
proto: tcp
- proto: tcp - proto: tcp
ports: "{{ havoc_teamserver_port | default(40056) }}" ports: "{{ havoc_teamserver_port | default(40056) }}"
cidr_ip: "{{ operator_ip }}/32" cidr_ip: "{{ operator_ip }}"
proto: tcp
# Allow traffic only from redirector # Allow traffic only from redirector
- proto: tcp - proto: tcp
ports: ports:
@@ -225,17 +212,45 @@
- "{{ havoc_https_port | default(443) }}" - "{{ havoc_https_port | default(443) }}"
- "{{ gophish_admin_port }}" - "{{ gophish_admin_port }}"
cidr_ip: "{{ redirector_ip }}/32" cidr_ip: "{{ redirector_ip }}/32"
proto: tcp
rules_egress: rules_egress:
- proto: -1 - proto: -1
cidr_ip: 0.0.0.0/0 cidr_ip: 0.0.0.0/0
state: present state: present
register: security_group register: security_group
# Generate or import SSH key for the deployment
- name: Check if deployment SSH key already exists locally
stat:
path: "~/.ssh/c2deploy_{{ deployment_id }}.pem"
register: ssh_key_file
- name: Ensure proper permissions on SSH key
file:
path: "~/.ssh/c2deploy_{{ deployment_id }}"
mode: '0600'
when: not ssh_key_file.stat.exists
- name: Check if key pair exists in AWS
amazon.aws.ec2_key_info:
region: "{{ aws_c2_region }}"
filters:
key-name: "c2deploy_{{ deployment_id }}"
register: existing_key_pair
- name: Import SSH key to AWS
amazon.aws.ec2_key:
name: "c2deploy_{{ deployment_id }}"
key_material: "{{ lookup('file', '~/.ssh/c2deploy_{{ deployment_id }}.pub') }}"
region: "{{ aws_c2_region }}"
state: present
when: existing_key_pair.key_pairs | length == 0
# Launch the C2 server - use the consistent key pair name # Launch the C2 server - use the consistent key pair name
- name: Launch C2 instance - name: Launch C2 instance
amazon.aws.ec2_instance: amazon.aws.ec2_instance:
name: "{{ c2_name }}" name: "{{ c2_name }}"
key_name: "c2deploy_{{ deployment_id }}" # Use the same key name as created above key_name: "c2deploy_{{ deployment_id }}" # Use the imported key
instance_type: "{{ instance_type | default('t2.medium') }}" instance_type: "{{ instance_type | default('t2.medium') }}"
vpc_subnet_id: "{{ subnet_id }}" vpc_subnet_id: "{{ subnet_id }}"
security_groups: security_groups:
+16 -29
View File
@@ -389,54 +389,41 @@
- "VPC resources deleted: {{ vpc_check.vpcs | length == 0 }}" - "VPC resources deleted: {{ vpc_check.vpcs | length == 0 }}"
when: not disable_summary | default(false) when: not disable_summary | default(false)
# STEP 14: Delete key pairs - more reliable implementation # STEP 14: Delete key pairs - completely revised implementation
- name: Find key pairs related to deployment - name: Check for deployment key in AWS
amazon.aws.ec2_key_info: shell: |
region: "{{ aws_region }}" aws ec2 describe-key-pairs --region {{ aws_region }} --filters "Name=key-name,Values=c2deploy_{{ deployment_id }}" --query "KeyPairs[*].KeyName" --output text
register: all_key_pairs environment:
AWS_ACCESS_KEY_ID: "{{ aws_access_key }}"
- name: Delete deployment related key pairs AWS_SECRET_ACCESS_KEY: "{{ aws_secret_key }}"
amazon.aws.ec2_key: register: keypair_check
name: "{{ item.key_name }}"
region: "{{ aws_region }}"
state: absent
loop: "{{ all_key_pairs.key_pairs | selectattr('key_name', 'search', deployment_id) | list }}"
when: all_key_pairs.key_pairs | length > 0
# Add this after your existing key pair finding task
- name: Find c2deploy key pairs
amazon.aws.ec2_key:
name: "c2deploy_{{ deployment_id }}"
region: "{{ aws_region }}"
state: present
register: c2deploy_key_check
ignore_errors: yes ignore_errors: yes
- name: Delete c2deploy key pairs - name: Delete deployment key pair if it exists
amazon.aws.ec2_key: amazon.aws.ec2_key:
name: "c2deploy_{{ deployment_id }}" name: "c2deploy_{{ deployment_id }}"
region: "{{ aws_region }}" region: "{{ aws_region }}"
state: absent state: absent
when: not c2deploy_key_check.failed | default(true) when: keypair_check.stdout | trim != ""
register: deleted_c2deploy_key register: deleted_keypair
# STEP 15: Delete SSH key files
- name: Delete SSH key files - name: Delete SSH key files
file: file:
path: "{{ item }}" path: "{{ item }}"
state: absent state: absent
with_items: with_items:
- "~/.ssh/c2deploy_{{ deployment_id }}.pem"
- "~/.ssh/c2deploy_{{ deployment_id }}.pub"
- "~/.ssh/{{ redirector_name }}.pem" - "~/.ssh/{{ redirector_name }}.pem"
- "~/.ssh/{{ c2_name }}.pem" - "~/.ssh/{{ c2_name }}.pem"
- "~/.ssh/{{ tracker_name }}.pem" - "~/.ssh/{{ tracker_name }}.pem"
- "~/.ssh/c2deploy_{{ deployment_id }}.pem" # Fix: add .pem extension
- "~/.ssh/c2deploy_{{ deployment_id }}.pub"
ignore_errors: yes ignore_errors: yes
register: deleted_ssh_files register: deleted_ssh_files
- name: Count deleted SSH files - name: Count deleted SSH files
set_fact: set_fact:
cleanup_summary: "{{ cleanup_summary | combine({ cleanup_summary: "{{ cleanup_summary | combine({
'keypairs_deleted': (deleted_keypair.changed | default(false)) | ternary(1, 0),
'ssh_files_deleted': (deleted_ssh_files.results | selectattr('changed', 'defined') | selectattr('changed') | list | length)}) }}" 'ssh_files_deleted': (deleted_ssh_files.results | selectattr('changed', 'defined') | selectattr('changed') | list | length)}) }}"
# Remove infrastructure state file - fix path to include deployment_id # Remove infrastructure state file - fix path to include deployment_id
@@ -458,7 +445,7 @@
- "Security Groups: {{ cleanup_summary.security_groups_found | default(0) }} found, {{ deleted_sgs.results | default([]) | length }} deleted" - "Security Groups: {{ cleanup_summary.security_groups_found | default(0) }} found, {{ deleted_sgs.results | default([]) | length }} deleted"
- "Network Interfaces: {{ cleanup_summary.enis_found | default(0) }} found, {{ deleted_enis.results | default([]) | length }} deleted" - "Network Interfaces: {{ cleanup_summary.enis_found | default(0) }} found, {{ deleted_enis.results | default([]) | length }} deleted"
- "VPCs: {{ cleanup_summary.vpcs_found | default(0) }} found, {{ cleanup_summary.vpcs_deleted | default(0) }} deleted" - "VPCs: {{ cleanup_summary.vpcs_found | default(0) }} found, {{ cleanup_summary.vpcs_deleted | default(0) }} deleted"
- "Key Pairs: {{ cleanup_summary.keypairs_deleted | default(0) }} deleted" - "Key Pairs: {{ deleted_key_pairs.results | default([]) | length }} deleted"
- "SSH Key Files: {{ cleanup_summary.ssh_files_deleted | default(0) }} deleted" - "SSH Key Files: {{ cleanup_summary.ssh_files_deleted | default(0) }} deleted"
- "Infrastructure file: {{ 'Removed' if infra_file.changed else 'Not found' }}" - "Infrastructure file: {{ 'Removed' if infra_file.changed else 'Not found' }}"
- "==========================================================" - "=========================================================="
+40 -22
View File
@@ -91,20 +91,6 @@
set_fact: set_fact:
ami_id: "{{ ubuntu_ami_map[aws_redirector_region] | default(ubuntu_ami_map['us-east-1']) }}" ami_id: "{{ ubuntu_ami_map[aws_redirector_region] | default(ubuntu_ami_map['us-east-1']) }}"
- name: Create EC2 key pair
amazon.aws.ec2_key:
name: "{{ redirector_name }}"
region: "{{ aws_redirector_region }}"
state: present
register: redirector_key_pair
- name: Save private key locally
copy:
content: "{{ redirector_key_pair.key.private_key }}"
dest: "~/.ssh/{{ redirector_name }}.pem"
mode: "0600"
when: redirector_key_pair.changed and redirector_key_pair.key.private_key is defined
# Create new infrastructure only if not using shared # Create new infrastructure only if not using shared
- name: Create VPC - name: Create VPC
amazon.aws.ec2_vpc_net: amazon.aws.ec2_vpc_net:
@@ -210,23 +196,55 @@
dest: "infrastructure_state_{{ deployment_id }}.json" dest: "infrastructure_state_{{ deployment_id }}.json"
when: not (use_shared_infra | bool and infra_state_file.stat.exists | default(false)) when: not (use_shared_infra | bool and infra_state_file.stat.exists | default(false))
# Launch the redirector # Generate or import SSH key for the deployment
- name: Launch redirector instance - name: Check if deployment SSH key already exists locally
stat:
path: "~/.ssh/c2deploy_{{ deployment_id }}.pem"
register: ssh_key_file
- name: Ensure proper permissions on SSH key
file:
path: "~/.ssh/c2deploy_{{ deployment_id }}"
mode: '0600'
when: not ssh_key_file.stat.exists
- name: Check if key pair exists in AWS
amazon.aws.ec2_key_info:
region: "{{ aws_c2_region }}"
filters:
key-name: "c2deploy_{{ deployment_id }}"
register: existing_key_pair
- name: Import SSH key to AWS
amazon.aws.ec2_key:
name: "c2deploy_{{ deployment_id }}"
key_material: "{{ lookup('file', '~/.ssh/c2deploy_{{ deployment_id }}.pub') }}"
region: "{{ aws_c2_region }}"
state: present
when: existing_key_pair.key_pairs | length == 0
# Launch the C2 server - use the consistent key pair name
- name: Launch C2 instance
amazon.aws.ec2_instance: amazon.aws.ec2_instance:
name: "{{ redirector_name }}" name: "{{ c2_name }}"
key_name: "{{ redirector_name }}" key_name: "c2deploy_{{ deployment_id }}" # Use the imported key
instance_type: "{{ redirector_instance_type | default('t2.micro') }}" instance_type: "{{ instance_type | default('t2.medium') }}"
vpc_subnet_id: "{{ subnet_id }}" vpc_subnet_id: "{{ subnet_id }}"
security_groups: security_groups:
- "{{ security_group.group_id }}" - "{{ security_group.group_id }}"
image_id: "{{ ami_id }}" image_id: "{{ ami_id }}"
region: "{{ aws_redirector_region }}" region: "{{ aws_c2_region }}"
state: present state: present
wait: yes wait: yes
volumes:
- device_name: "/dev/xvda"
ebs:
volume_size: 100
delete_on_termination: true
tags: tags:
Name: "{{ redirector_name }}" Name: "{{ c2_name }}"
deployment_id: "{{ deployment_id }}" deployment_id: "{{ deployment_id }}"
register: redirector_instance register: c2_instance
- name: Set redirector_ip for later use - name: Set redirector_ip for later use
set_fact: set_fact:
+64 -60
View File
@@ -508,10 +508,30 @@ def execute_deployment(config):
config['c2_name'] = f"s-{config['deployment_id']}" config['c2_name'] = f"s-{config['deployment_id']}"
config['tracker_name'] = f"t-{config['deployment_id']}" config['tracker_name'] = f"t-{config['deployment_id']}"
# Generate SSH key with the deployment ID if not provided # Generate SSH key with the deployment ID if not provided
if not config.get('ssh_key'): # For all providers, we use a local key that's imported to the cloud
config['ssh_key'] = generate_ssh_key(config['deployment_id']) ssh_key_path = os.path.expanduser(f"~/.ssh/c2deploy_{config['deployment_id']}")
config['ssh_key_path'] = f"{config['ssh_key']}.pub" ssh_key_pub_path = f"{ssh_key_path}.pub"
# Check if key exists, generate if it doesn't
if not os.path.exists(ssh_key_path):
print(f"\n{COLORS['BLUE']}Generating SSH key for deployment...{COLORS['RESET']}")
try:
subprocess.run([
"ssh-keygen", "-t", "rsa", "-b", "4096",
"-f", ssh_key_path, "-q", "-N", ""
], check=True)
os.chmod(ssh_key_path, 0o600)
print(f"{COLORS['GREEN']}SSH key generated at {ssh_key_path}{COLORS['RESET']}")
except subprocess.CalledProcessError as e:
print(f"{COLORS['RED']}Failed to generate SSH key: {e}{COLORS['RESET']}")
input("\nPress Enter to return to menu...")
return
# Set consistent paths for providers
config['ssh_key_path'] = ssh_key_pub_path
if config['provider'] == 'aws':
config['aws_ssh_key_name'] = f"c2deploy_{config['deployment_id']}"
# Print configuration (excluding sensitive data) # Print configuration (excluding sensitive data)
for key, value in config.items(): for key, value in config.items():
@@ -1609,7 +1629,7 @@ def run_tests(config):
def ssh_to_instance(config): def ssh_to_instance(config):
"""SSH into the deployed instance with improved AWS key handling""" """SSH into the deployed instance with improved key handling"""
logging.info("Connecting to instance via SSH...") logging.info("Connecting to instance via SSH...")
# Determine which IP to use based on deployment type # Determine which IP to use based on deployment type
@@ -1635,78 +1655,62 @@ def ssh_to_instance(config):
print(f"{COLORS['RED']}No IP address found for {instance_type}. Cannot SSH.{COLORS['RESET']}") print(f"{COLORS['RED']}No IP address found for {instance_type}. Cannot SSH.{COLORS['RESET']}")
return False return False
# Get SSH key and user - with AWS-specific handling # Get the correct SSH key and user based on provider and deployment ID
ssh_key = config.get('ssh_key') deployment_id = config.get('deployment_id')
if config.get('provider') == 'aws': ssh_key = os.path.expanduser(f"~/.ssh/c2deploy_{deployment_id}")
# For AWS, always look for the .pem extension key
deployment_id = config.get('deployment_id', '')
aws_key_path = os.path.expanduser(f"~/.ssh/c2deploy_{deployment_id}.pem")
if os.path.exists(aws_key_path):
ssh_key = aws_key_path
logging.info(f"Using AWS key at {ssh_key}")
else:
# Try adding .pem to existing key path if it exists
potential_pem_key = f"{ssh_key}.pem" if ssh_key else ""
if potential_pem_key and os.path.exists(potential_pem_key):
ssh_key = potential_pem_key
logging.info(f"Found AWS key with .pem extension: {ssh_key}")
if not ssh_key: # Handle specific provider variations
logging.error("No SSH key specified") if config.get('provider') == 'aws':
print(f"{COLORS['RED']}No SSH key specified. Cannot SSH.{COLORS['RESET']}") # AWS-specific key handling - check with .pem suffix
pem_key = f"{ssh_key}.pem"
if os.path.exists(pem_key):
ssh_key = pem_key
if not os.path.exists(ssh_key):
logging.error(f"SSH key not found at {ssh_key}")
print(f"{COLORS['RED']}SSH key not found at {ssh_key}. Cannot SSH.{COLORS['RESET']}")
return False return False
# Fix key permissions # Fix key permissions
os.chmod(ssh_key, 0o600) os.chmod(ssh_key, 0o600)
# Try multiple possible usernames # Determine the correct username based on provider and instance type
if config.get('ssh_user'): if config.get('ssh_user'):
ssh_users = [config.get('ssh_user')] ssh_user = config.get('ssh_user')
elif config['provider'] == 'aws': elif config['provider'] == 'aws':
# For AWS, try multiple common usernames ssh_user = config.get('ami_ssh_user', 'kali')
ssh_users = ['kali']
elif config['provider'] == 'linode': elif config['provider'] == 'linode':
ssh_users = ['root'] ssh_user = 'root'
else: else:
ssh_users = [DEFAULT_SSH_USER.get(config['provider'], 'root')] ssh_user = DEFAULT_SSH_USER.get(config['provider'], 'root')
# Print SSH connection information # Print SSH connection information
print(f"\n{COLORS['CYAN']}SSH Connection Information:{COLORS['RESET']}") print(f"\n{COLORS['CYAN']}SSH Connection Information:{COLORS['RESET']}")
print(f" Host: {ip}") print(f" Host: {ip}")
print(f" User: {ssh_user}")
print(f" Key: {ssh_key}") print(f" Key: {ssh_key}")
print(f" Will try users: {', '.join(ssh_users)}") print(f" Manual command: ssh -i {ssh_key} {ssh_user}@{ip}")
# Try each SSH user until one works # Build SSH command
for ssh_user in ssh_users: ssh_cmd = [
print(f"\n{COLORS['YELLOW']}Trying SSH with user: {ssh_user}{COLORS['RESET']}") "ssh",
print(f" Manual SSH command: ssh -i {ssh_key} {ssh_user}@{ip}") "-t",
"-o", "StrictHostKeyChecking=no",
# Build SSH command "-o", "UserKnownHostsFile=/dev/null",
ssh_cmd = [ "-o", "IdentitiesOnly=yes",
"ssh", "-o", "ConnectTimeout=10",
"-t", "-i", ssh_key,
"-o", "StrictHostKeyChecking=no", f"{ssh_user}@{ip}",
"-o", "UserKnownHostsFile=/dev/null", "tmux"
"-o", "IdentitiesOnly=yes", ]
"-o", "ConnectTimeout=10",
"-i", ssh_key,
f"{ssh_user}@{ip}",
"tmux"
]
# Execute SSH command with timeout
try:
subprocess.run(ssh_cmd, timeout=60)
return True
except subprocess.TimeoutExpired:
print(f"{COLORS['YELLOW']}Connection with user {ssh_user} timed out, trying next user...{COLORS['RESET']}")
continue
except Exception as e:
print(f"{COLORS['YELLOW']}Connection with user {ssh_user} failed: {e}{COLORS['RESET']}")
continue
print(f"{COLORS['RED']}Failed to connect with any user. Check instance security group and key.{COLORS['RESET']}") # Execute SSH command
return False try:
subprocess.run(ssh_cmd)
return True
except Exception as e:
print(f"{COLORS['RED']}SSH connection failed: {e}{COLORS['RESET']}")
return False
def cleanup_resources(config, interactive=True): def cleanup_resources(config, interactive=True):
"""Clean up resources if deployment fails""" """Clean up resources if deployment fails"""