Skip to main content

Snaffler cleaner

Tweeze out just lines with "hostname" and "id" and "password" from Snaffler log

This is a cool script to take a snaffler file and pull out a log file of just hostnames, ids and passwords. This is helpful when you want to take output from snaffler and trim it down even more from the view you see in efflanrs:

import re
import readline
import glob
import os

# Function to perform tab completion for file paths
def complete_path(text, state):
if '~' in text:
text = os.path.expanduser(text)
return [x for x in glob.glob(text + '*')][state]

# Enable tab completion for file paths
readline.parse_and_bind("tab: complete")
readline.set_completer(complete_path)

# Prompt the user for the input file path with tab completion
input_file = input("Enter the path to the input file: ")

# Suggest 'output.txt' as the default output file name
default_output_file = "output.txt"

# Check if the default output file exists
if os.path.exists(default_output_file):
overwrite = input(f"'{default_output_file}' already exists. Do you want to overwrite it? (y/n): ").strip().lower()
if overwrite not in ['y', 'yes']:
# If the user does not want to overwrite, prompt for a new file name
output_file = input("Enter the path to save the output file: ")
else:
output_file = default_output_file
else:
output_file = default_output_file

# Generate the '_short' version of the output file name
output_short_file = output_file.rsplit('.', 1)
output_short_file = f"{output_short_file[0]}_short.{output_short_file[1]}" if len(output_short_file) > 1 else f"{output_file}_short"

# Regular expressions to extract id and password, case-insensitive
id_regex = re.compile(r'id=([^;]+)', re.IGNORECASE)
password_regex = re.compile(r'password=([^;]+)', re.IGNORECASE)
path_regex = re.compile(r'\((\\\\[^)]+)\)', re.IGNORECASE)

# Set to store unique entries for both outputs
unique_entries_full = set()
unique_entries_short = set()

# Open the input file
with open(input_file, 'r') as infile:
for line in infile:
# Check if the line contains both "id=" and "password=" case-insensitively
if re.search(id_regex, line) and re.search(password_regex, line):
# Extract the id
id_match = re.search(id_regex, line)
user_id = f'id={id_match.group(1)}' if id_match else None

# Extract the password
password_match = re.search(password_regex, line)
password = f'password={password_match.group(1)}' if password_match else None

# Process for the full output
path_match = re.search(path_regex, line)
full_path = path_match.group(1) if path_match else None
if full_path:
server_name = re.search(r'\\\\[^\\]+', full_path)
full_path = server_name.group(0) if server_name else full_path

if full_path and user_id and password:
entry_full = f'{full_path}, {user_id}, {password}'
unique_entries_full.add(entry_full)

# Automatically process for the short output
if user_id and password:
entry_short = f'{user_id}, {password}'
unique_entries_short.add(entry_short)

# Sort the entries alphabetically
sorted_entries_full = sorted(unique_entries_full)
sorted_entries_short = sorted(unique_entries_short)

# Write the sorted, de-duplicated entries to the full output file
with open(output_file, 'w') as outfile:
for entry in sorted_entries_full:
outfile.write(entry + '\n')

# Write the id and password results to the short file
with open(output_short_file, 'w') as shortfile:
for entry in sorted_entries_short:
shortfile.write(entry + '\n')

print(f'Processing complete. The full results have been saved to {output_file}.')
print(f'The id and password results have been saved to {output_short_file}.')