mirror of
https://github.com/jokob-sk/NetAlertX.git
synced 2025-12-07 01:26:11 -08:00
NMAP plugin conversion v0.1
This commit is contained in:
11
front/plugins/nmap_scan/README.md
Executable file
11
front/plugins/nmap_scan/README.md
Executable file
@@ -0,0 +1,11 @@
|
||||
## Overview
|
||||
|
||||
This plugin scans your network for open ports. Only IPs are scanned that are accessible by the app container.
|
||||
|
||||
### Usage
|
||||
|
||||
- TBD
|
||||
|
||||
### Notes
|
||||
|
||||
- N/A
|
||||
11
front/plugins/nmap_scan/README_ES.md
Executable file
11
front/plugins/nmap_scan/README_ES.md
Executable file
@@ -0,0 +1,11 @@
|
||||
## Descripción general
|
||||
|
||||
Este plugin muestra todos los servicios descubiertos mediante análisis NMAP regulares. También es un complemento de muestra que muestra cómo usar una consulta SQL para mostrar datos existentes de la base de datos PiAlert.
|
||||
|
||||
### Uso
|
||||
|
||||
- La consulta SQL de la configuración `NMAPSRV_CMD` se utiliza para crear datos de origen para este complemento. El orden de las columnas y los valores deben cumplir con los especificados en la [documentación](https://github.com/jokob-sk/Pi.Alert/tree/main/front/plugins).
|
||||
|
||||
### Notas
|
||||
|
||||
- N / A
|
||||
459
front/plugins/nmap_scan/config.json
Executable file
459
front/plugins/nmap_scan/config.json
Executable file
@@ -0,0 +1,459 @@
|
||||
{
|
||||
"code_name": "nmap_scan",
|
||||
"unique_prefix": "NMAP",
|
||||
"enabled": true,
|
||||
"data_source": "script",
|
||||
"data_filters": [
|
||||
{
|
||||
"compare_column" : "ForeignKey",
|
||||
"compare_operator" : "==",
|
||||
"compare_field_id": "txtMacFilter",
|
||||
"compare_js_template": "'{value}.toString()'",
|
||||
"compare_use_quotes": true
|
||||
}
|
||||
],
|
||||
"show_ui": true,
|
||||
"localized": ["display_name", "description", "icon"],
|
||||
"display_name" : [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Services & Ports (NMAP)"
|
||||
},
|
||||
{
|
||||
"language_code":"es_es",
|
||||
"string" : "Servicios & Puertos (NMAP)"
|
||||
}],
|
||||
"icon":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "<i class=\"fa-solid fa-satellite-dish\"></i>"
|
||||
},
|
||||
{
|
||||
"language_code":"es_es",
|
||||
"string" : "<i class=\"fa-solid fa-satellite-dish\"></i>"
|
||||
}],
|
||||
"description": [{
|
||||
"language_code":"en_us",
|
||||
"string" : "This plugin shows all services discovered by NMAP scans."
|
||||
},
|
||||
{
|
||||
"language_code":"es_es",
|
||||
"string" : "Este complemento muestra todos los servicios descubiertos por escaneos NMAP."
|
||||
}],
|
||||
"params" : [
|
||||
{
|
||||
"name" : "ips",
|
||||
"type" : "sql",
|
||||
"value" : "SELECT dev_LastIP from DEVICES",
|
||||
"timeoutMultiplier" : true
|
||||
},
|
||||
{
|
||||
"name" : "macs",
|
||||
"type" : "sql",
|
||||
"value" : "SELECT dev_MAC from DEVICES"
|
||||
},
|
||||
{
|
||||
"name" : "timeout",
|
||||
"type" : "setting",
|
||||
"value" : "NMAP_RUN_TIMEOUT"
|
||||
},
|
||||
{
|
||||
"name" : "args",
|
||||
"type" : "setting",
|
||||
"value" : "NMAP_ARGS",
|
||||
"base64" : true
|
||||
}
|
||||
],
|
||||
"database_column_definitions":
|
||||
[
|
||||
{
|
||||
"column": "Index",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "N/A"
|
||||
}]
|
||||
} ,
|
||||
{
|
||||
"column": "Plugin",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "N/A"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "device_name_mac",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Device name"
|
||||
},
|
||||
{
|
||||
"language_code":"es_es",
|
||||
"string" : "Nombre del dispositivo"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "url",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Port"
|
||||
},
|
||||
{
|
||||
"language_code":"es_es",
|
||||
"string" : "Puerto"
|
||||
}]
|
||||
} ,
|
||||
{
|
||||
"column": "DateTimeCreated",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Created"
|
||||
},
|
||||
{
|
||||
"language_code":"es_es",
|
||||
"string" : "Creado"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeChanged",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Changed"
|
||||
},
|
||||
{
|
||||
"language_code":"es_es",
|
||||
"string" : "Cambiado"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "State"
|
||||
},
|
||||
{
|
||||
"language_code":"es_es",
|
||||
"string" : "Estado"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Service"
|
||||
},
|
||||
{
|
||||
"language_code":"es_es",
|
||||
"string" : "Servicio"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value3",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "N/A"
|
||||
},
|
||||
{
|
||||
"language_code":"es_es",
|
||||
"string" : "N/A"
|
||||
}]
|
||||
} ,
|
||||
{
|
||||
"column": "Watched_Value4",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "N/A"
|
||||
},
|
||||
{
|
||||
"language_code":"es_es",
|
||||
"string" : "N/A"
|
||||
}]
|
||||
} ,
|
||||
{
|
||||
"column": "Extra",
|
||||
"css_classes": "col-sm-3",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Extra"
|
||||
},
|
||||
{
|
||||
"language_code":"es_es",
|
||||
"string" : "Extra"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "ForeignKey",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "device_mac",
|
||||
"default_value":"",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "MAC"
|
||||
},
|
||||
{
|
||||
"language_code":"es_es",
|
||||
"string" : "MAC"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"column": "Status",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "replace",
|
||||
"default_value":"",
|
||||
"options": [
|
||||
{
|
||||
"equals": "watched-not-changed",
|
||||
"replacement": "<div style='text-align:center'><i class='fa-solid fa-square-check'></i><div></div>"
|
||||
},
|
||||
{
|
||||
"equals": "watched-changed",
|
||||
"replacement": "<div style='text-align:center'><i class='fa-solid fa-triangle-exclamation'></i></div>"
|
||||
},
|
||||
{
|
||||
"equals": "new",
|
||||
"replacement": "<div style='text-align:center'><i class='fa-solid fa-circle-plus'></i></div>"
|
||||
},
|
||||
{
|
||||
"equals": "missing-in-last-scan",
|
||||
"replacement": "<div style='text-align:center'><i class='fa-solid fa-question'></i></div>"
|
||||
}
|
||||
],
|
||||
"localized": ["name"],
|
||||
"name":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Status"
|
||||
},
|
||||
{
|
||||
"language_code":"es_es",
|
||||
"string" : "Estado"
|
||||
}]
|
||||
}
|
||||
],
|
||||
"settings":[
|
||||
{
|
||||
"function": "RUN",
|
||||
"type": "text.select",
|
||||
"default_value":"disabled",
|
||||
"options": ["disabled", "once", "schedule", "always_after_scan", "on_new_device"],
|
||||
"localized": ["name", "description"],
|
||||
"name" :[{
|
||||
"language_code":"en_us",
|
||||
"string" : "When to run"
|
||||
},
|
||||
{
|
||||
"language_code":"es_es",
|
||||
"string" : "Cuando ejecutar"
|
||||
}],
|
||||
"description": [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Enable a regular Nmap scan on your network on all devices. The scheduling settings can be found below. If you select <code>once</code> Nmap is run only once on start for the time specified in <a href=\"#NMAP_TIMEOUT\"><code>NMAP_TIMEOUT</code> setting</a>."
|
||||
},
|
||||
{
|
||||
"language_code":"es_es",
|
||||
"string" : "Habilite un escaneo regular de Nmap en su red en todos los dispositivos. Los ajustes de programación se pueden encontrar a continuación. Si selecciona <code>una vez</code>, Nmap se ejecuta solo una vez al inicio durante el tiempo especificado en la configuración de <a href=\"#NMAP_TIMEOUT\"><code>NMAP_TIMEOUT</code></a>"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"function": "CMD",
|
||||
"type": "text",
|
||||
"default_value":"python3 /home/pi/pialert/front/plugins/nmap_scan/script.py ips={ips} macs={macs} timeout={timeout} args={args}",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name" : [{
|
||||
"language_code":"en_us",
|
||||
"string" : "SQL to run"
|
||||
},
|
||||
{
|
||||
"language_code":"es_es",
|
||||
"string" : "Consulta SQL"
|
||||
}],
|
||||
"description": [{
|
||||
"language_code":"en_us",
|
||||
"string" : "This calls the script responsible for executing the NMAP scan."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "ARGS",
|
||||
"type": "text",
|
||||
"default_value":"-p -10000",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name" : [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Arguments"
|
||||
},
|
||||
{
|
||||
"language_code":"es_es",
|
||||
"string" : "Argumentos"
|
||||
}],
|
||||
"description": [
|
||||
{
|
||||
"language_code":"en_us",
|
||||
"string" : "Arguments used to run the Nmap scan. Be careful to specify <a href=\"https://linux.die.net/man/1/nmap\" target=\"_blank\">the arguments</a> correctly. For example <code>-p -10000</code> scans ports from 1 to 10000."
|
||||
},
|
||||
{
|
||||
"language_code":"es_es",
|
||||
"string" : "Argumentos utilizados para ejecutar el análisis de Nmap. Tenga cuidado de especificar <a href=\"https://linux.die.net/man/1/nmap\" target=\"_blank\">los argumentos</a> correctamente. Por ejemplo, <code>-p -10000</code> escanea los puertos del 1 al 10000."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "RUN_SCHD",
|
||||
"type": "text",
|
||||
"default_value":"0 2 * * *",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name" : [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Schedule"
|
||||
},
|
||||
{
|
||||
"language_code":"es_es",
|
||||
"string" : "Schedule"
|
||||
}],
|
||||
"description": [{
|
||||
"language_code":"en_us",
|
||||
"string" : "Only enabled if you select <code>schedule</code> in the <a href=\"#NMAP_RUN\"><code>NMAP_RUN</code> setting</a>. Make sure you enter the schedule in the correct cron-like format."
|
||||
},
|
||||
{
|
||||
"language_code":"es_es",
|
||||
"string" : "Solo está habilitado si selecciona <code>programar</code> en la configuración de <a href=\"#NMAP_RUN\"><code>NMAP_RUN</code></a>. Asegúrese de ingresar el cronograma en el formato tipo cron correcto."
|
||||
}]
|
||||
},
|
||||
{
|
||||
"function": "RUN_TIMEOUT",
|
||||
"type": "integer",
|
||||
"default_value": 300,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Run timeout"
|
||||
},
|
||||
{
|
||||
"language_code": "es_es",
|
||||
"string": "Tiempo límite de ejecución"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Max run time per device in seconds."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "WATCH",
|
||||
"type": "text.multiselect",
|
||||
"default_value":["Watched_Value1"],
|
||||
"options": ["Watched_Value1","Watched_Value2","Watched_Value3","Watched_Value4"],
|
||||
"localized": ["name", "description"],
|
||||
"name" :[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Watched"
|
||||
},
|
||||
{
|
||||
"language_code":"es_es",
|
||||
"string" : "Visto"
|
||||
}] ,
|
||||
"description":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Send a notification if selected values change. Use <code>CTRL + Click</code> to select/deselect. <ul> <li><code>Watched_Value1</code> is service type (e.g.: http, ssh)</li><li><code>Watched_Value2</code> is Status (open or closed)</li><li><code>Watched_Value3</code> unused </li><li><code>Watched_Value4</code> unused </li></ul>"
|
||||
},
|
||||
{
|
||||
"language_code":"es_es",
|
||||
"string" : "Envíe una notificación si los valores seleccionados cambian. Utilice <code>CTRL + clic</code> para seleccionar/deseleccionar. <ul> <li><code>Watched_Value1</code> es el tipo de servicio (p. ej., http, ssh)</li><li><code>Watched_Value2</code> es el estado (abierto o cerrado)</li> <li><code>Watched_Value3</code> no utilizado </li><li><code>Watched_Value4</code> no utilizado </li></ul>"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"function": "REPORT_ON",
|
||||
"type": "text.multiselect",
|
||||
"default_value":["new","watched-changed"],
|
||||
"options": ["new","watched-changed","watched-not-changed"],
|
||||
"localized": ["name", "description"],
|
||||
"name" :[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Report on"
|
||||
},
|
||||
{
|
||||
"language_code":"es_es",
|
||||
"string" : "Informar sobre"
|
||||
}] ,
|
||||
"description":[{
|
||||
"language_code":"en_us",
|
||||
"string" : "Send a notification only on these statuses. <code>new</code> means a new unique (unique combination of PrimaryId and SecondaryId) object was discovered. <code>watched-changed</code> means that selected <code>Watched_ValueN</code> columns changed."
|
||||
},
|
||||
{
|
||||
"language_code":"es_es",
|
||||
"string" : "Envíe una notificación solo en estos estados. <code>new</code> significa que se descubrió un nuevo objeto único (combinación única de PrimaryId y SecondaryId). <code>watched-changed</code> significa que seleccionó <code>Watched_ValueN Las columnas </code> cambiaron."
|
||||
}]
|
||||
}
|
||||
]
|
||||
}
|
||||
280
front/plugins/nmap_scan/script.py
Executable file
280
front/plugins/nmap_scan/script.py
Executable file
@@ -0,0 +1,280 @@
|
||||
|
||||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
import pathlib
|
||||
import argparse
|
||||
import sys
|
||||
import re
|
||||
import base64
|
||||
import subprocess
|
||||
from time import strftime
|
||||
|
||||
sys.path.append("/home/pi/pialert/front/plugins")
|
||||
sys.path.append('/home/pi/pialert/pialert')
|
||||
|
||||
from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64
|
||||
from logger import mylog, append_line_to_file
|
||||
from helper import timeNowTZ
|
||||
from const import logPath, pialertPath
|
||||
|
||||
CUR_PATH = str(pathlib.Path(__file__).parent.resolve())
|
||||
LOG_FILE = os.path.join(CUR_PATH, 'script.log')
|
||||
RESULT_FILE = os.path.join(CUR_PATH, 'last_result.log')
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
def main():
|
||||
# sample
|
||||
# /home/pi/pialert/front/plugins/nmap_scan/script.py ips=192.168.1.66,192.168.1.9'
|
||||
parser = argparse.ArgumentParser(description='Scan ports of devices specified by IP addresses')
|
||||
parser.add_argument('ips', nargs='+', help="list of IPs to scan")
|
||||
parser.add_argument('macs', nargs='+', help="list of MACs related to the supplied IPs in the same order")
|
||||
parser.add_argument('timeout', nargs='+', help="timeout")
|
||||
parser.add_argument('args', nargs='+', help="args")
|
||||
values = parser.parse_args()
|
||||
|
||||
# Plugin_Objects is a class that reads data from the RESULT_FILE
|
||||
# and returns a list of results.
|
||||
results = Plugin_Objects(RESULT_FILE)
|
||||
|
||||
# Print a message to indicate that the script is starting.
|
||||
mylog('debug', ['[NMAP Scan] In script '])
|
||||
|
||||
# Printing the params list to check its content.
|
||||
mylog('debug', ['[NMAP Scan] values.ips: ', values.ips])
|
||||
mylog('debug', ['[NMAP Scan] values.macs: ', values.macs])
|
||||
mylog('debug', ['[NMAP Scan] values.timeout: ', values.timeout])
|
||||
mylog('debug', ['[NMAP Scan] values.args: ', values.args])
|
||||
|
||||
argsDecoded = decodeBase64(values.args)
|
||||
|
||||
mylog('debug', ['[NMAP Scan] argsDecoded: ', argsDecoded])
|
||||
|
||||
entries = performNmapScan(values.ips.split('=')[1].split(','), values.macs.split('=')[1].split(',') , values.timeout.split('=')[1], argsDecoded)
|
||||
|
||||
for entry in entries:
|
||||
|
||||
results.add_object(
|
||||
primaryId = entry.mac, # MAC (Device Name)
|
||||
secondaryId = entry.port, # IP Address (always 0.0.0.0)
|
||||
watched1 = entry.state, # Device Name
|
||||
watched2 = entry.service,
|
||||
watched3 = entry.ip + ":" + entry.port,
|
||||
watched4 = "",
|
||||
extra = "",
|
||||
foreignKey = entry.extra
|
||||
)
|
||||
|
||||
entries.write_result_file()
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
class nmap_entry:
|
||||
def __init__(self, ip, mac, time, port, state, service, name = '', extra = '', index = 0):
|
||||
self.ip = ip
|
||||
self.mac = mac
|
||||
self.time = time
|
||||
self.port = port
|
||||
self.state = state
|
||||
self.service = service
|
||||
self.extra = extra
|
||||
self.index = index
|
||||
self.hash = str(mac) + str(port)+ str(state)+ str(service)
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
def performNmapScan(deviceIPs, deviceMACs, timeoutSec, args):
|
||||
"""
|
||||
run nmap scan on a list of devices
|
||||
discovers open ports and keeps track existing and new open ports
|
||||
"""
|
||||
if len(deviceIPs) > 0:
|
||||
|
||||
devTotal = len(deviceIPs)
|
||||
|
||||
updateState(db,"Scan: Nmap")
|
||||
|
||||
mylog('verbose', ['[NMAP Scan] Scan: Nmap for max ', str(timeoutSec), 's ('+ str(round(int(timeoutSec) / 60, 1)) +'min) per device'])
|
||||
mylog('verbose', ["[NMAP Scan] Estimated max delay: ", (devTotal * int(timeoutSec)), 's ', '(', round((devTotal * int(timeoutSec))/60,1) , 'min)' ])
|
||||
|
||||
# collect ports / new Nmap Entries
|
||||
newEntriesTmp = []
|
||||
|
||||
devIndex = 0
|
||||
for ip in deviceIPs:
|
||||
# Execute command
|
||||
output = ""
|
||||
# prepare arguments from user supplied ones
|
||||
nmapArgs = ['nmap'] + args.split() + [ip]
|
||||
|
||||
progress = ' (' + str(devIndex+1) + '/' + str(devTotal) + ')'
|
||||
|
||||
try:
|
||||
# try runnning a subprocess with a forced (timeout) in case the subprocess hangs
|
||||
output = subprocess.check_output (nmapArgs, universal_newlines=True, stderr=subprocess.STDOUT, timeout=(timeoutSec))
|
||||
except subprocess.CalledProcessError as e:
|
||||
# An error occured, handle it
|
||||
mylog('none', ["[NMAP Scan] " ,e.output])
|
||||
mylog('none', ["[NMAP Scan] Error - Nmap Scan - check logs", progress])
|
||||
except subprocess.TimeoutExpired as timeErr:
|
||||
mylog('verbose', ['[NMAP Scan] Nmap TIMEOUT - the process forcefully terminated as timeout reached for ', ip, progress])
|
||||
|
||||
if output == "": # check if the subprocess failed
|
||||
mylog('minimal', ['[NMAP Scan] Nmap FAIL for ', ip, progress ,' check logs for details'])
|
||||
else:
|
||||
mylog('verbose', ['[NMAP Scan] Nmap SUCCESS for ', ip, progress])
|
||||
|
||||
|
||||
|
||||
# check the last run output
|
||||
newLines = output.split('\n')
|
||||
|
||||
# regular logging
|
||||
for line in newLines:
|
||||
append_line_to_file (logPath + '/pialert_nmap.log', line +'\n')
|
||||
|
||||
|
||||
|
||||
index = 0
|
||||
startCollecting = False
|
||||
duration = ""
|
||||
for line in newLines:
|
||||
if 'Starting Nmap' in line:
|
||||
if len(newLines) > index+1 and 'Note: Host seems down' in newLines[index+1]:
|
||||
break # this entry is empty
|
||||
elif 'PORT' in line and 'STATE' in line and 'SERVICE' in line:
|
||||
startCollecting = True
|
||||
elif 'PORT' in line and 'STATE' in line and 'SERVICE' in line:
|
||||
startCollecting = False # end reached
|
||||
elif startCollecting and len(line.split()) == 3:
|
||||
newEntriesTmp.append(nmap_entry(ip, deviceMACs[devIndex], timeNowTZ(), line.split()[0], line.split()[1], line.split()[2]))
|
||||
elif 'Nmap done' in line:
|
||||
duration = line.split('scanned in ')[1]
|
||||
|
||||
index += 1
|
||||
devIndex += 1
|
||||
|
||||
mylog('verbose', ['[NMAP Scan] Ports found by NMAP: ', len(newEntriesTmp)])
|
||||
|
||||
#end for loop
|
||||
|
||||
return newEntriesTmp
|
||||
|
||||
#===============================================================================
|
||||
# BEGIN
|
||||
#===============================================================================
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
# def process_discovered_ports(db, device, discoveredPorts):
|
||||
# """
|
||||
# process ports discovered by nmap
|
||||
# compare to previosu ports
|
||||
# update DB
|
||||
# raise notifications
|
||||
# """
|
||||
# sql = db.sql # TO-DO
|
||||
# # previous Nmap Entries
|
||||
# oldEntries = []
|
||||
# changedPortsTmp = []
|
||||
|
||||
# mylog('verbose', ['[NMAP Scan] Process ports found by NMAP: ', len(discoveredPorts)])
|
||||
|
||||
# if len(discoveredPorts) > 0:
|
||||
|
||||
# # get all current NMAP ports from the DB
|
||||
# rows = db.read(sql_nmap_scan_all)
|
||||
|
||||
# for row in rows:
|
||||
# # only collect entries matching the current MAC address
|
||||
# if row["MAC"] == device["dev_MAC"]:
|
||||
# oldEntries.append(nmap_entry(row["MAC"], row["Time"], row["Port"], row["State"], row["Service"], device["dev_Name"], row["Extra"], row["Index"]))
|
||||
|
||||
# newEntries = []
|
||||
|
||||
# # Collect all entries that don't match the ones in the DB
|
||||
# for discoveredPort in discoveredPorts:
|
||||
|
||||
# found = False
|
||||
|
||||
# # Check the new entry is already available in oldEntries and remove from processing if yes
|
||||
# for oldEntry in oldEntries:
|
||||
# if discoveredPort.hash == oldEntry.hash:
|
||||
# found = True
|
||||
|
||||
# if not found:
|
||||
# newEntries.append(discoveredPort)
|
||||
|
||||
|
||||
# mylog('verbose', ['[NMAP Scan] Nmap newly discovered or changed ports: ', len(newEntries)])
|
||||
|
||||
# # collect new ports, find the corresponding old entry and return for notification purposes
|
||||
# # also update the DB with the new values after deleting the old ones
|
||||
# if len(newEntries) > 0:
|
||||
|
||||
# # params to build the SQL query
|
||||
# params = []
|
||||
# indexesToDelete = ""
|
||||
|
||||
# # Find old entry matching the new entry hash
|
||||
# for newEntry in newEntries:
|
||||
|
||||
# foundEntry = None
|
||||
|
||||
# for oldEntry in oldEntries:
|
||||
# if oldEntry.hash == newEntry.hash:
|
||||
# indexesToDelete = indexesToDelete + str(oldEntry.index) + ','
|
||||
# foundEntry = oldEntry
|
||||
|
||||
# columnNames = ["Name", "MAC", "Port", "State", "Service", "Extra", "NewOrOld" ]
|
||||
|
||||
# # Old entry found
|
||||
# if foundEntry is not None:
|
||||
# # Build params for sql query
|
||||
# params.append((newEntry.mac, newEntry.time, newEntry.port, newEntry.state, newEntry.service, oldEntry.extra))
|
||||
# # Build JSON for API and notifications
|
||||
# changedPortsTmp.append({
|
||||
# "Name" : foundEntry.name,
|
||||
# "MAC" : newEntry.mac,
|
||||
# "Port" : newEntry.port,
|
||||
# "State" : newEntry.state,
|
||||
# "Service" : newEntry.service,
|
||||
# "Extra" : foundEntry.extra,
|
||||
# "NewOrOld" : "New values"
|
||||
# })
|
||||
# changedPortsTmp.append({
|
||||
# "Name" : foundEntry.name,
|
||||
# "MAC" : foundEntry.mac,
|
||||
# "Port" : foundEntry.port,
|
||||
# "State" : foundEntry.state,
|
||||
# "Service" : foundEntry.service,
|
||||
# "Extra" : foundEntry.extra,
|
||||
# "NewOrOld" : "Old values"
|
||||
# })
|
||||
# # New entry - no matching Old entry found
|
||||
# else:
|
||||
# # Build params for sql query
|
||||
# params.append((newEntry.mac, newEntry.time, newEntry.port, newEntry.state, newEntry.service, ''))
|
||||
# # Build JSON for API and notifications
|
||||
# changedPortsTmp.append({
|
||||
# "Name" : "New device",
|
||||
# "MAC" : newEntry.mac,
|
||||
# "Port" : newEntry.port,
|
||||
# "State" : newEntry.state,
|
||||
# "Service" : newEntry.service,
|
||||
# "Extra" : "",
|
||||
# "NewOrOld" : "New device"
|
||||
# })
|
||||
|
||||
# conf.changedPorts_json_struc = json_struc({ "data" : changedPortsTmp}, columnNames)
|
||||
|
||||
# # Delete old entries if available
|
||||
# if len(indexesToDelete) > 0:
|
||||
# sql.execute ("DELETE FROM Nmap_Scan where \"Index\" in (" + indexesToDelete[:-1] +")")
|
||||
# db.commitDB()
|
||||
|
||||
# # Insert new values into the DB
|
||||
# sql.executemany ("""INSERT INTO Nmap_Scan ("MAC", "Time", "Port", "State", "Service", "Extra") VALUES (?, ?, ?, ?, ?, ?)""", params)
|
||||
# db.commitDB()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user