Creating the App Link to heading
from flask import Flask, render_template
import pymysql
app = Flask(__name__)
# Database connection
def get_db_connection():
connection = pymysql.connect(
host='localhost',
user='USER',
password='PASSWORD',
database='nmap_scans',
cursorclass=pymysql.cursors.DictCursor
)
return connection
@app.route('/')
def index():
connection = get_db_connection()
cursor = connection.cursor()
# Fetch scan results
cursor.execute('SELECT * FROM scans ORDER BY scanned_at DESC')
scans = cursor.fetchall()
connection.close()
return render_template('index.html', scans=scans)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
Create the Nmap scanner Link to heading
import pymysql
import subprocess
import json
# Database connection
connection = pymysql.connect(
host='localhost',
user='USER',
password='PASSWORD',
database='nmap_scans',
cursorclass=pymysql.cursors.DictCursor
)
def parse_nmap_output(output):
# Dummy parser - you need to parse your nmap output appropriately
results = {
'ip': '',
'hostname': '',
'status': '',
'os_detection': '',
'service_versions': '',
'open_ports': '',
'services': '',
'scan_type': '',
'traceroute': '',
}
# Parse your actual nmap output here
return results
def insert_scan_results(results):
try:
with connection.cursor() as cursor:
sql = """INSERT INTO scan_results
(ip, hostname, status, os_detection, service_versions, open_ports, services, scan_type, traceroute)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)"""
cursor.execute(sql, (results['ip'], results['hostname'], results['status'],
results['os_detection'], results['service_versions'],
results['open_ports'], results['services'],
results['scan_type'], results['traceroute']))
connection.commit()
finally:
connection.close()
# Run the nmap scan
nmap_command = "nmap -A -T4 -p- 192.168.1.0/24"
result = subprocess.run(nmap_command, shell=True, capture_output=True, text=True)
# Parse and insert results
scan_results = parse_nmap_output(result.stdout)
insert_scan_results(scan_results)
SQL Database Link to heading
Login to the database:
mysql -u USER -p
Connect the to the required table:
USE nmap_scans;
Add the following fields:
CREATE TABLE scans (
id INT AUTO_INCREMENT PRIMARY KEY,
ip VARCHAR(45), -- IP address (supports both IPv4 and IPv6)
status VARCHAR(20), -- Host status (e.g., up or down)
os VARCHAR(100), -- Detected operating system
ports TEXT, -- Open ports (list of ports)
services TEXT, -- Services running on the open ports
scan_type VARCHAR(50), -- Type of scan (e.g., full scan, version scan)
scanned_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP -- Timestamp of when the scan was performed
);
Added these extra fields later:
ADD COLUMN hostname VARCHAR(255), -- Hostname from reverse DNS resolution
ADD COLUMN os_detection TEXT, -- Detailed OS detection results
ADD COLUMN service_versions TEXT, -- Versions of detected services
ADD COLUMN traceroute TEXT, -- Traceroute information
ADD COLUMN hostnames TEXT; -- Additional hostnames (if multiple)```
And exit:
EXIT;
Create the webpage in /templates/index.html Link to heading
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Nmap Scan Results</title>
<style>
body {
font-family: 'Arial', sans-serif;
background-color: #f0f8ff;
color: #333;
text-align: center;
margin: 0;
padding: 0;
}
h1 {
background: linear-gradient(90deg, #ff6f61, #ffcc00);
color: white;
padding: 20px;
font-size: 2.5em;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
border-radius: 0 0 10px 10px;
margin-bottom: 20px;
}
table {
margin: 20px auto;
border-collapse: collapse;
width: 90%;
max-width: 1200px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
background-color: white;
}
th, td {
padding: 15px;
border: 1px solid #ddd;
}
th {
background-color: #ff6f61;
color: white;
text-transform: uppercase;
font-size: 1.1em;
}
tr:nth-child(even) {
background-color: #f9f9f9;
}
tr:hover {
background-color: #ffcc00;
cursor: pointer;
transform: scale(1.02);
transition: transform 0.3s ease;
}
td {
font-size: 0.9em;
}
</style>
</head>
<body>
<h1>Nmap Scan Results</h1>
<table>
<thead>
<tr>
<th>ID</th>
<th>IP Address</th>
<th>Hostname</th>
<th>Status</th>
<th>OS Detection</th>
<th>Service Versions</th>
<th>Open Ports</th>
<th>Services</th>
<th>Scan Type</th>
<th>Traceroute</th>
<th>Scanned At</th>
</tr>
</thead>
<tbody>
{% for scan in scans %}
<tr>
<td>{{ scan.id }}</td>
<td>{{ scan.ip }}</td>
<td>{{ scan.hostname }}</td>
<td>{{ scan.status }}</td>
<td>{{ scan.os_detection }}</td>
<td>{{ scan.service_versions }}</td>
<td>{{ scan.open_ports }}</td>
<td>{{ scan.services }}</td>
<td>{{ scan.scan_type }}</td>
<td>{{ scan.traceroute }}</td>
<td>{{ scan.scanned_at }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>
Run the Nmap scanner then the webserver Link to heading
python3 nmap_scan.py
python3 app.py
Find the port scan in Splunk Link to heading
index=* sourcetype="pfsense:filterlog"
| stats count by src_ip, dest_ip, dest_port
| eventstats dc(dest_port) as port_count by src_ip, dest_ip
| where port_count > 20
| table src_ip, dest_ip, port_count
| sort -port_count