logging works dont change run_ansible_playbook
This commit is contained in:
@@ -1249,23 +1249,10 @@ def run_ansible_playbook(playbook, inventory, config, debug=False):
|
||||
# Convert config dict to JSON for extra-vars
|
||||
extra_vars = {k: v for k, v in config.items() if v is not None and not isinstance(v, (dict, list, tuple))}
|
||||
|
||||
# Ensure consistent region parameter handling
|
||||
if 'region' in extra_vars:
|
||||
extra_vars['selected_region'] = extra_vars['region']
|
||||
elif 'linode_region' in extra_vars:
|
||||
extra_vars['selected_region'] = extra_vars['linode_region']
|
||||
extra_vars['region'] = extra_vars['linode_region'] # Added for consistency
|
||||
|
||||
# Other setup code stays the same...
|
||||
extra_vars_json = json.dumps(extra_vars)
|
||||
|
||||
# Set PYTHONPATH to include site-packages
|
||||
env = os.environ.copy()
|
||||
current_python = sys.executable
|
||||
python_path = subprocess.check_output(
|
||||
[current_python, "-c", "import sys; import site; print(':'.join(sys.path + site.getsitepackages()))"],
|
||||
text=True
|
||||
).strip()
|
||||
env["PYTHONPATH"] = python_path
|
||||
# PYTHONPATH setup...
|
||||
|
||||
# Build command with output JSON facts format
|
||||
cmd = [
|
||||
@@ -1273,85 +1260,60 @@ def run_ansible_playbook(playbook, inventory, config, debug=False):
|
||||
"-i", inventory,
|
||||
playbook,
|
||||
"-e", extra_vars_json,
|
||||
"--extra-vars", "ansible_facts_callback=json" # Get facts in JSON format
|
||||
"--extra-vars", "ansible_facts_callback=json"
|
||||
]
|
||||
|
||||
# Add verbosity if debug mode is enabled
|
||||
# Add verbosity flag
|
||||
if debug:
|
||||
cmd.append("-vvv")
|
||||
# Set ANSIBLE_STDOUT_CALLBACK for human-readable output
|
||||
env["ANSIBLE_STDOUT_CALLBACK"] = "debug"
|
||||
else:
|
||||
cmd.append("-v")
|
||||
|
||||
# Log the command
|
||||
if debug:
|
||||
logging.debug(f"Running Ansible command: {' '.join(cmd)}")
|
||||
else:
|
||||
logging.info(f"Running Ansible playbook: {playbook}")
|
||||
if debug:
|
||||
logging.debug(f"Command: {' '.join(cmd)}")
|
||||
|
||||
# Run the command with enhanced output capture
|
||||
# Run the command with output capture
|
||||
try:
|
||||
process = subprocess.Popen(
|
||||
cmd,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
text=True,
|
||||
bufsize=1, # Line buffered
|
||||
bufsize=1,
|
||||
env=env
|
||||
)
|
||||
|
||||
# Stream output in real-time
|
||||
# Capture output in real-time
|
||||
stdout_output = []
|
||||
stderr_output = []
|
||||
|
||||
# Create separate threads to read stdout and stderr
|
||||
def read_output(pipe, output_list, is_stdout=True):
|
||||
prefix = COLORS['GREEN'] if is_stdout else COLORS['RED']
|
||||
for line in iter(pipe.readline, ''):
|
||||
output_list.append(line)
|
||||
# Log every line to file regardless of debug mode
|
||||
if is_stdout:
|
||||
# Read stdout in real-time and log every line
|
||||
for line in iter(process.stdout.readline, ''):
|
||||
stdout_output.append(line)
|
||||
# Log every line to the file
|
||||
logging.debug(line.rstrip())
|
||||
else:
|
||||
# Also print to terminal with color
|
||||
print(f"{COLORS['GREEN']}{line.rstrip()}{COLORS['RESET']}")
|
||||
|
||||
# Read stderr in real-time and log every line
|
||||
for line in iter(process.stderr.readline, ''):
|
||||
stderr_output.append(line)
|
||||
# Log errors to file
|
||||
logging.error(line.rstrip())
|
||||
# Always display in terminal, but use filtering if not in debug mode
|
||||
if debug or ('TASK' in line or 'PLAY' in line or 'changed=' in line or 'ok=' in line or 'failed=' in line):
|
||||
print(f"{prefix}{line.rstrip()}{COLORS['RESET']}")
|
||||
pipe.close()
|
||||
|
||||
from threading import Thread
|
||||
stdout_thread = Thread(target=read_output, args=(process.stdout, stdout_output, True))
|
||||
stderr_thread = Thread(target=read_output, args=(process.stderr, stderr_output, False))
|
||||
|
||||
stdout_thread.daemon = True
|
||||
stderr_thread.daemon = True
|
||||
stdout_thread.start()
|
||||
stderr_thread.start()
|
||||
# Print to terminal with color
|
||||
print(f"{COLORS['RED']}{line.rstrip()}{COLORS['RESET']}")
|
||||
|
||||
# Wait for process to complete
|
||||
return_code = process.wait()
|
||||
|
||||
# Wait for output threads to complete
|
||||
stdout_thread.join()
|
||||
stderr_thread.join()
|
||||
|
||||
# Join the output
|
||||
stdout_result = ''.join(stdout_output)
|
||||
stderr_result = ''.join(stderr_output)
|
||||
|
||||
# Extract IP addresses from output
|
||||
if "C2 Server IP:" in stdout_result:
|
||||
ip_match = re.search(r"C2 Server IP: ([0-9.]+)", stdout_result)
|
||||
if ip_match:
|
||||
config['c2_ip'] = ip_match.group(1)
|
||||
logging.info(f"Extracted C2 IP: {config['c2_ip']}")
|
||||
|
||||
if "Redirector IP:" in stdout_result:
|
||||
ip_match = re.search(r"Redirector IP: ([0-9.]+)", stdout_result)
|
||||
if ip_match:
|
||||
config['redirector_ip'] = ip_match.group(1)
|
||||
logging.info(f"Extracted Redirector IP: {config['redirector_ip']}")
|
||||
# Extract IPs, etc. as before...
|
||||
|
||||
if return_code == 0:
|
||||
logging.info(f"Playbook {playbook} executed successfully")
|
||||
|
||||
@@ -12,7 +12,19 @@
|
||||
elif inventory_hostname in groups['sharedrives'] | default([]) %}sharedrive{%
|
||||
else %}unknown{% endif %}
|
||||
|
||||
- name: Configure C2 server routing
|
||||
# Determine if we're using AWS provider
|
||||
- name: Determine if using AWS provider
|
||||
set_fact:
|
||||
is_aws_provider: "{{ provider | default('unknown') == 'aws' }}"
|
||||
|
||||
# Skip firewall configuration for AWS instances
|
||||
- name: Skip firewall configuration for AWS instances
|
||||
debug:
|
||||
msg: "Skipping host-based firewall configuration for AWS instance. Security Groups are handling this at the infrastructure level."
|
||||
when: is_aws_provider
|
||||
|
||||
# UFW Configuration Block (non-AWS only)
|
||||
- name: Configure C2 server routing with UFW
|
||||
block:
|
||||
- name: Allow SSH only from operator IP
|
||||
ufw:
|
||||
@@ -39,13 +51,15 @@
|
||||
- { ip: "{{ redirector_ip }}", port: "443" }
|
||||
- { ip: "{{ redirector_ip }}", port: "{{ havoc_http_port | default('8080') }}" }
|
||||
- { ip: "{{ redirector_ip }}", port: "{{ havoc_https_port | default('443') }}" }
|
||||
- { ip: "{{ logserver_ip | default(omit) }}", port: "5144" } # Logstash port
|
||||
- { ip: "{{ payloadserver_ip | default(omit) }}", port: "8888" } # Payload sync port
|
||||
- { ip: "{{ logserver_ip | default(omit) }}", port: "5144" }
|
||||
- { ip: "{{ payloadserver_ip | default(omit) }}", port: "8888" }
|
||||
when: item.ip != omit
|
||||
when:
|
||||
- server_role == 'c2'
|
||||
- not is_aws_provider
|
||||
|
||||
when: server_role == 'c2'
|
||||
|
||||
- name: Configure redirector routing
|
||||
# Rest of the original file for non-AWS providers only
|
||||
- name: Configure redirector routing with UFW
|
||||
block:
|
||||
- name: Allow SSH only from operator IP
|
||||
ufw:
|
||||
@@ -68,7 +82,9 @@
|
||||
rule: allow
|
||||
port: "{{ shell_handler_port | default('4444') }}"
|
||||
proto: tcp
|
||||
when: server_role == 'redirector'
|
||||
when:
|
||||
- server_role == 'redirector'
|
||||
- not is_aws_provider
|
||||
|
||||
- name: Configure logging server routing
|
||||
block:
|
||||
@@ -91,4 +107,6 @@
|
||||
- "{{ payloadserver_ip | default(omit) }}"
|
||||
- "{{ phishingserver_ip | default(omit) }}"
|
||||
when: item != omit
|
||||
when: server_role == 'logserver'
|
||||
when:
|
||||
- server_role == 'logserver'
|
||||
- not is_aws_provider
|
||||
Reference in New Issue
Block a user