Skip to main content

CSVToMarkdown.py

This script takes a CSV output of an nmap scan (created with something like Nmap-XML-to-CSV) and converts it into a markdown document for easier copying-and-pasting into something like sysreptor.

Fire up a venv and then

pip install pandas
import pandas as pd
import ipaddress
import readline
import glob
import os
from datetime import datetime

def complete(text, state):
"""Tab completion function"""
return (glob.glob(text+'*')+[None])[state]

# Set up readline with tab completion
readline.set_completer_delims(' \t\n;')
readline.parse_and_bind("tab: complete")
readline.set_completer(complete)

def process_csv(input_file, output_file):
# Read the CSV file - changed delimiter to comma
df = pd.read_csv(input_file, sep=',')

# Drop the Host and OS columns
df = df.drop(['Host', 'OS', 'Product', 'Service FP', 'NSE Script ID', 'NSE Script Output', 'Notes'], axis=1)

# Convert IP strings to IP objects for proper sorting
df['IP_obj'] = df['IP'].apply(ipaddress.ip_address)

# Sort by IP first, then by Port
df = df.sort_values(['IP_obj', 'Port'])

# Drop the temporary IP_obj column
df = df.drop('IP_obj', axis=1)

# Save to CSV
df.to_csv(output_file, sep=',', index=False)

# Create markdown output with bold headers
markdown_output = "| " + " | ".join(f"**{col}**" for col in df.columns) + " |\n"
markdown_output += "|" + "|".join(["---"] * len(df.columns)) + "|\n"

for _, row in df.iterrows():
markdown_output += "| " + " | ".join(str(x) for x in row) + " |\n"

# Add unique IPs as H3 headers with their ports and services
markdown_output += "\n\n# IP List\n" # Section header
unique_ips = sorted(df['IP'].unique(), key=lambda x: ipaddress.ip_address(x))

for ip in unique_ips:
markdown_output += f"\n### {ip}\n"
# Get all ports and services for this IP
ip_data = df[df['IP'] == ip][['Port', 'Service']].sort_values('Port')
for _, row in ip_data.iterrows():
markdown_output += f"**Port {row['Port']} ({row['Service'].upper()})** \n\n"
markdown_output += '<figure style="border: 1px solid #0099dc;">\n'
markdown_output += ' <img src="/images/name/image-.png">\n'
markdown_output += ' <figcaption>TODO</figcaption>\n'
markdown_output += '</figure>\n\n'

return df, markdown_output

# Get filenames from user with tab completion enabled
input_file = input("Enter the input CSV filename: ")

# Generate timestamped output filename
timestamp = datetime.now().strftime('%Y-%m-%d-%H%M')
base_name = os.path.splitext(input_file)[0] # Get filename without extension
output_file = f"{base_name}_{timestamp}.md"

# Process the files
try:
df, markdown = process_csv(input_file, output_file)
print(f"\nFile successfully processed!")
print(f"Markdown output saved to: {output_file}")

# Save markdown content to file
with open(output_file, 'w') as f:
f.write(markdown)

except FileNotFoundError:
print(f"\nError: Could not find input file '{input_file}'")
except Exception as e:
print(f"\nError processing file: {str(e)}")