NMAP plugin conversion v0.1

This commit is contained in:
Jokob-sk
2023-08-27 18:45:07 +10:00
parent b114de1fd9
commit e6644ad3ec
23 changed files with 612 additions and 499 deletions

View File

@@ -659,16 +659,16 @@
highlightedCss = nodeData.data.mac == selectedNodeMac ? " highlightedNode" : "";
return result = "<div class='box pointer "+statusCss+" "+highlightedCss+"' data-mytreemacmain='"+nodeData.data.mac+"' \
style='height:"+nodeData.settings.nodeHeight+"px;\
" + fontSize + "\
>\
return result = `<div class='box ${(nodeData.data.hasChildren)? "pointer":""} ${statusCss} ${highlightedCss}'
data-mytreemacmain='${nodeData.data.mac}'
style='height:${nodeData.settings.nodeHeight}px;${fontSize}
>
<div class='netNodeText '>\
<strong>" + devicePort + deviceIcon +
"<span class='spanNetworkTree anonymizeDev'>"+nodeData.data.name+"</span>\
</strong>"
+collapseExpandHtml+
"</div></div>";
<strong>${devicePort} ${deviceIcon}
<span class='spanNetworkTree anonymizeDev'>${nodeData.data.name}</span>\
</strong>
${collapseExpandHtml}
</div></div>`;
},
onNodeClick: nodeData => {

View File

@@ -572,18 +572,6 @@
"DDNS_PASSWORD_description" : "",
"DDNS_UPDATE_URL_name" : "DynDNS update URL",
"DDNS_UPDATE_URL_description" : "Update URL starting with <code>http://</code> or <code>https://</code>.",
"Nmap_display_name" : "Nmap",
"Nmap_icon" : "<i class=\"fa fa-ethernet\"></i>",
"NMAP_ACTIVE_name" : "Cycle run",
"NMAP_ACTIVE_description" : "If enabled this will execute a scan on a newly found device. For a scheduled or one-off scan, check the <a href=\"#NMAP_RUN\"><code>NMAP_RUN</code> setting</a>.",
"NMAP_TIMEOUT_name" : "Run timeout",
"NMAP_TIMEOUT_description" : "Maximum time in seconds to wait for an Nmap scan to finish on any device.",
"NMAP_RUN_name" : "Scheduled run",
"NMAP_RUN_description" : "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>.",
"NMAP_RUN_SCHD_name" : "Schedule",
"NMAP_RUN_SCHD_description" : "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.",
"NMAP_ARGS_name" : "Arguments",
"NMAP_ARGS_description" : "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.",
"API_display_name" : "API",
"API_icon" : "<i class=\"fa fa-arrow-down-up-across-line\"></i>",
"API_CUSTOM_SQL_name" : "Custom endpoint",

View File

@@ -565,17 +565,6 @@
"DDNS_PASSWORD_description" : "",
"DDNS_UPDATE_URL_name" : "URL de actualización de DynDNS",
"DDNS_UPDATE_URL_description" : "Actualice la URL que comienza con <code>http://</code> o <code>https://</code>.",
"Nmap_display_name" : "Nmap",
"Nmap_icon" : "<i class=\"fa fa-ethernet\"></i>",
"NMAP_ACTIVE_name" : "Ejecución del ciclo",
"NMAP_ACTIVE_description" : "Si está habilitado, ejecutará un escaneo en un dispositivo recién encontrado. Para un análisis programado o único, verifique la configuración de <a href=\"#NMAP_RUN\"><code>NMAP_RUN</code></a>.",
"NMAP_TIMEOUT_description" : "Tiempo máximo en segundos para esperar a que finalice un escaneo de Nmap en cualquier dispositivo.",
"NMAP_RUN_name" : "Ejecución programada",
"NMAP_RUN_description" : "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>.",
"NMAP_RUN_SCHD_name" : "Programar",
"NMAP_RUN_SCHD_description" : "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.",
"NMAP_ARGS_name" : "Argumentos",
"NMAP_ARGS_description" : "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.",
"API_display_name" : "API",
"API_icon" : "<i class=\"fa fa-arrow-down-up-across-line\"></i>",
"API_CUSTOM_SQL_name" : "Endpoint personalizado",

View File

@@ -15,9 +15,12 @@
- [undiscoverables (UNDIS)](/front/plugins/undiscoverables/)
- [pholus_scan (ARPSCAN)](/front/plugins/pholus_scan/)
- [set_password (SETPWD)](/front/plugins/set_password/)
- [nmap_scan (NMAP)](/front/plugins/nmap_scan/)
### SQL query based plugins
- [nmap_services (NMAPSERV)](/front/plugins/nmap_services/)
- N/A, but the External SQLite based plugins work very similar
### template based plugins
- [newdev_template (NEWDEV)](/front/plugins/newdev_template/)

View File

@@ -50,7 +50,8 @@
{
"name" : "subnets",
"type" : "setting",
"value" : "SCAN_SUBNETS"
"value" : "SCAN_SUBNETS",
"base64": true
}],
"settings": [

View File

@@ -28,9 +28,7 @@ def main():
# the script expects a parameter in the format of userSubnets=subnet1,subnet2,...
parser = argparse.ArgumentParser(description='Import devices from settings')
parser.add_argument('userSubnets', nargs='+', help="list of subnets with options")
values = parser.parse_args()
import base64
values = parser.parse_args()
# Assuming Plugin_Objects is a class or function that reads data from the RESULT_FILE
# and returns a list of objects called 'devices'.

View 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

View File

@@ -1,8 +1,8 @@
{
"code_name": "nmap_services",
"unique_prefix": "NMAPSRV",
"code_name": "nmap_scan",
"unique_prefix": "NMAP",
"enabled": true,
"data_source": "pialert-db-query",
"data_source": "script",
"data_filters": [
{
"compare_column" : "ForeignKey",
@@ -38,7 +38,30 @@
"language_code":"es_es",
"string" : "Este complemento muestra todos los servicios descubiertos por escaneos NMAP."
}],
"params" : [],
"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":
[
{
@@ -71,7 +94,7 @@
"column": "Object_PrimaryID",
"css_classes": "col-sm-2",
"show": true,
"type": "label",
"type": "device_name_mac",
"default_value":"",
"options": [],
"localized": ["name"],
@@ -94,17 +117,17 @@
"localized": ["name"],
"name":[{
"language_code":"en_us",
"string" : "Ip and Port"
"string" : "Port"
},
{
"language_code":"es_es",
"string" : "IP y puerto"
"string" : "Puerto"
}]
} ,
{
"column": "DateTimeCreated",
"css_classes": "col-sm-2",
"show": false,
"show": true,
"type": "label",
"default_value":"",
"options": [],
@@ -141,22 +164,6 @@
"show": true,
"type": "label",
"default_value":"",
"localized": ["name"],
"name":[{
"language_code":"en_us",
"string" : "Service"
},
{
"language_code":"es_es",
"string" : "Servicio"
}]
},
{
"column": "Watched_Value2",
"css_classes": "col-sm-1",
"show": true,
"type": "label",
"default_value":"",
"options": [],
"localized": ["name"],
"name":[{
@@ -168,6 +175,22 @@
"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",
@@ -272,75 +295,119 @@
}
],
"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" : "Specify when the SQL query is executed."
},
{
"language_code":"es_es",
"string" : "Especificar cuándo se ejecuta la consulta SQL."
}]
{
"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"
},
{
"function": "CMD",
"type": "text",
"default_value":"SELECT ns.MAC as Object_PrimaryID, cast('http://' || dv.dev_LastIP as VARCHAR(100)) || ':' || cast( SUBSTR(ns.Port ,0, INSTR(ns.Port , '/')) as VARCHAR(100)) as Object_SecondaryID, datetime() as DateTime, ns.Service as Watched_Value1, ns.State as Watched_Value2, dv.dev_Name as Watched_Value3, 'null' as Watched_Value4, ns.Extra as Extra, ns.MAC as ForeignKey FROM (SELECT * FROM Nmap_Scan) ns left JOIN (SELECT dev_Name, dev_MAC, dev_LastIP FROM Devices) dv ON ns.MAC = dv.dev_MAC",
"options": [],
"localized": ["name", "description"],
"name" : [{
"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" : "SQL to run"
"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" : "Consulta SQL"
}],
"description": [{
"language_code":"en_us",
"string" : "This SQL query is used to populate the coresponding UI tables under the Plugins section."
},
{
"language_code":"es_es",
"string" : "Esta consulta SQL se usa para completar las tablas de IU correspondientes en la sección Complementos."
"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"
},
{
"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" : "Schedule"
}],
"description": [{
"language_code":"en_us",
"string" : "Only enabled if you select <code>schedule</code> in the <a href=\"#NMAPSRV_RUN\"><code>NMAPSRV_RUN</code> setting</a>. Make sure you enter the schedule in the correct cron-like format (e.g. validate at <a href=\"https://crontab.guru/\" target=\"_blank\">crontab.guru</a>). For example entering <code>0 4 * * *</code> will run the scan after 4 am in the <a onclick=\"toggleAllSettings()\" href=\"#TIMEZONE\"><code>TIMEZONE</code> you set above</a>. Will be run NEXT time the time passes."
},
{
"language_code":"es_es",
"string" : "Solo está habilitado si selecciona <code>schedule</code> en la configuración <a href=\"#NMAPSRV_RUN\"><code>NMAPSRV_RUN</code> setting</a>. Asegúrese de ingresar la programación en el formato similar a cron correcto (por ejemplo, valide en <a href=\"https://crontab.guru/\" target=\"_blank\">crontab.guru</a>). Por ejemplo, ingresar <code>0 4 * * *</code> ejecutará el escaneo después de las 4 a.m. en el <a onclick=\"toggleAllSettings()\" href=\"#TIMEZONE\"><code>TIMEZONE</ código> que configuró arriba</a>. Se ejecutará la PRÓXIMA vez que pase el tiempo."
}]
{
"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",
@@ -352,7 +419,7 @@
"language_code":"en_us",
"string" : "Watched"
},
{
{
"language_code":"es_es",
"string" : "Visto"
}] ,
@@ -360,7 +427,7 @@
"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>"
}]
@@ -375,7 +442,7 @@
"language_code":"en_us",
"string" : "Report on"
},
{
{
"language_code":"es_es",
"string" : "Informar sobre"
}] ,
@@ -383,7 +450,7 @@
"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
View 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()

View File

@@ -1,11 +0,0 @@
## Overview
This plugin shows all Services discovered by regular NMAP scans. It's also a sample plugin showcasing how to use a SQL Query to show existing data from the PiAlert database.
### Usage
- The sql query from the `NMAPSRV_CMD` setting is used to create source data for this plugin. Column order and values need to adhere to the ones specified in the [documentation](https://github.com/jokob-sk/Pi.Alert/tree/main/front/plugins).
### Notes
- N/A

View File

@@ -2,6 +2,11 @@ from time import strftime
import pytz
from datetime import datetime
sys.path.append("/home/pi/pialert/front/plugins")
sys.path.append('/home/pi/pialert/pialert')
from logger import mylog
#-------------------------------------------------------------------------------
def read_config_file():
"""
@@ -20,14 +25,35 @@ def read_config_file():
confDict = {} # config dictionary
exec(code, {"__builtins__": {}}, confDict)
return confDict
# -------------------------------------------------------------------
pialertConfigFile = read_config_file()
timeZoneSetting = pialertConfigFile['TIMEZONE']
timeZone = pytz.timezone(timeZoneSetting)
# -------------------------------------------------------------------
def decodeBase64(input):
# Printing the input list to check its content.
mylog('debug', ['[Plugins] Helper base64 input: ', input])
# Extract the base64-encoded subnet information from the first element
# The format of the element is assumed to be like 'param=b<base64-encoded-data>'.
inputParamBase64 = input.split('=b')[1]
# Printing the extracted base64-encoded information.
mylog('debug', ['[Plugins] Helper base64 inputParamBase64: ', inputParamBase64])
# Decode the base64-encoded subnet information to get the actual subnet information in ASCII format.
result = base64.b64decode(inputParamBase64).decode('ascii')
# Print the decoded subnet information.
mylog('debug', ['[Plugins] Helper base64 result: ', result])
return result
# -------------------------------------------------------------------
class Plugin_Object: