Skip to content

Instantly share code, notes, and snippets.

@r4z0r5
Last active October 24, 2024 18:00
Show Gist options
  • Save r4z0r5/caee7f1325b96fd2baec0c76dab6e071 to your computer and use it in GitHub Desktop.
Save r4z0r5/caee7f1325b96fd2baec0c76dab6e071 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>.Nmap report parser</title>
<style>/* Fancy inline style not damaging your eyes*/
body {
font-family: Arial, sans-serif;
margin: 20px;
background-color: #2C2C2C;
color: #E0E0E0;
}
h1, h2 {
text-align: center;
color: #E0E0E0;
}
.input-container, .export-container, .filter-container, .export-ips-container {
margin-bottom: 20px;
text-align: center;
}
table {
width: 100%;
border-collapse: collapse;
margin: 20px 0;
background-color: #3C3C3C;
color: #E0E0E0;
}
table, th, td {
border: 1px solid #555555;
}
th, td {
padding: 8px;
text-align: left;
}
th {
background-color: #4D4D4D;
}
.file-input {
display: block;
margin: 0 auto;
background-color: #555555;
color: #E0E0E0;
padding: 5px;
border: 1px solid #777777;
}
.file-input:hover {
background-color: #666666;
}
.error {
color: red;
text-align: center;
}
button {
background-color: #444444;
color: #E0E0E0;
padding: 10px 20px;
border: none;
cursor: pointer;
transition: background-color 0.3s;
}
button:hover {
background-color: #555555;
}
.ips-output {
background-color: #333333;
color: #E0E0E0;
padding: 10px;
border: 1px solid #555555;
width: 80%;
margin: 0 auto;
white-space: pre-wrap;
overflow-wrap: break-word;
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script>
</head>
<body>
<h1>.Nmap report parser</h1>
<div class="input-container">
<input type="file" id="fileInput" class="file-input" accept=".nmap" />
</div>
<div id="error" class="error"></div>
<h2 id="hostCount">0 Hosts loaded</h2>
<div class="filter-container">
<input type="text" id="filterInput" placeholder="Enter IP or Port to filter">
<button id="filterButton">Filter</button>
</div>
<div class="export-container">
<button id="exportButton">Export to xlsx</button>
</div>
<div class="export-ips-container" style="display: none;">
<button id="exportIpsButton">Export IPS</button>
</div>
<table id="nmapTable">
<thead>
<tr>
<th>IP</th>
<th>Open ports</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<div id="ipsOutput" class="ips-output" style="display: none;"></div>
<script>/* Fancy bare JS for building the table, sorting, exporting and filtering ;d */
let parsedData = [];
let hostCount = 0;
document.getElementById('fileInput').addEventListener('change', function(event) {
const file = event.target.files[0];
if (!file) return;
const reader = new FileReader();
reader.onload = function(e) {
const content = e.target.result;
parseNmapReport(content);
};
reader.onerror = function() {
showError("Error reading file");
};
reader.readAsText(file);
});
function parseNmapReport(report) {
const lines = report.split('\n');
const tableBody = document.querySelector('#nmapTable tbody');
tableBody.innerHTML = '';
parsedData = [];
hostCount = 0;
let currentIP = null;
let openPorts = [];
lines.forEach(line => {
const ipMatch = line.match(/Nmap scan report for (.+)/);
if (ipMatch) {
if (currentIP) {
parsedData.push({ ip: currentIP, ports: openPorts });
hostCount++;
}
currentIP = ipMatch[1];
openPorts = [];
}
const portMatch = line.match(/(\d+\/tcp)\s+open\s+(\S+)/);
if (portMatch) {
openPorts.push(portMatch[1] + ' (' + portMatch[2] + ')');
}
});
if (currentIP) {
parsedData.push({ ip: currentIP, ports: openPorts });
hostCount++;
}
document.getElementById('hostCount').textContent = `${hostCount} Hosts loaded`;
updateTable(parsedData);
}
function updateTable(data) {
const tableBody = document.querySelector('#nmapTable tbody');
tableBody.innerHTML = '';
let hasPorts = false;
data.forEach(item => {
const row = document.createElement('tr');
const ipCell = document.createElement('td');
const portsCell = document.createElement('td');
ipCell.textContent = item.ip;
portsCell.textContent = item.ports.length ? item.ports.join(', ') : 'No open ports';
if (item.ports.length > 0) {
hasPorts = true;
}
row.appendChild(ipCell);
row.appendChild(portsCell);
tableBody.appendChild(row);
});
const exportIpsContainer = document.querySelector('.export-ips-container');
if (hasPorts) {
exportIpsContainer.style.display = 'block';
} else {
exportIpsContainer.style.display = 'none';
}
}
document.getElementById('filterButton').addEventListener('click', function() {
const filterValue = document.getElementById('filterInput').value.toLowerCase();
const filteredData = parsedData.filter(item =>
item.ip.toLowerCase().includes(filterValue) ||
item.ports.some(port => port.toLowerCase().includes(filterValue))
);
updateTable(filteredData);
});
document.getElementById('exportButton').addEventListener('click', function() {
exportTableToExcel('nmapTable', 'Nmap_Report.xlsx');
});
document.getElementById('exportIpsButton').addEventListener('click', function() {
const ips = getUniqueIpsFromTable();
const ipsOutput = document.getElementById('ipsOutput');
ipsOutput.textContent = ips.join('\n');
ipsOutput.style.display = 'block';
});
function getUniqueIpsFromTable() {
const table = document.getElementById('nmapTable');
const rows = table.querySelectorAll('tbody tr');
const ips = new Set();
rows.forEach(row => {
const ip = row.cells[0].textContent;
const ports = row.cells[1].textContent;
if (ports !== 'No open ports') {
ips.add(ip);
}
});
return Array.from(ips);
}
function exportTableToExcel(tableID, filename = '') {
const table = document.getElementById(tableID);
const workbook = XLSX.utils.table_to_book(table, {sheet: "Sheet1"});
XLSX.writeFile(workbook, filename || 'excel_data.xlsx');
}
function showError(message) {
document.getElementById('error').textContent = message;
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment