
Scanner di rilevamento Modbus/TCP multithread scritto in C utilizzando libmodbus.
Uno scanner C multithread per il rilevamento di servizi Modbus/TCP che utilizza libmodbus.
Lo scanner non si basa esclusivamente sulla porta TCP 502 aperta. Invece, stabilisce una connessione Modbus/TCP e invia una richiesta Modbus a livello applicativo. Una risposta Modbus valida viene utilizzata come indicatore principale della presenza di un servizio Modbus.
Modbus è un protocollo di comunicazione industriale comunemente utilizzato da PLC, RTU, HMI, sistemi SCADA, sensori, contatori e altri dispositivi industriali.
Modbus/TCP trasporta il protocollo applicativo Modbus su TCP.
La porta Modbus/TCP standard è:
TCP/502
Un flusso di comunicazione tipico è:
Scanner
|
| Connessione TCP → 502
|
| Richiesta Modbus/TCP
v
Dispositivo Modbus
|
| Risposta Modbus/TCP
v
Scanner
A differenza dei protocolli che forniscono un banner immediatamente dopo la connessione, Modbus/TCP richiede generalmente che il client invii una richiesta Modbus valida prima che il dispositivo produca una risposta a livello applicativo.
Lo scanner esegue il rilevamento in due fasi.
Lo scanner tenta di stabilire una connessione TCP verso:
<target>:502
Se la connessione non può essere stabilita, il target viene considerato come non rispondente a Modbus/TCP.
Tuttavia, una porta TCP/502 aperta di per sé non è considerata prova sufficiente della presenza di Modbus.
Dopo la connessione, lo scanner invia una richiesta Modbus utilizzando libmodbus.
La sonda principale è:
modbus_read_input_registers(ctx, 0, 1, ®);
Questo genera un Codice di Funzione Modbus:
0x04 - Lettura Registri di Ingresso
La richiesta chiede al target un registro di ingresso a partire dall'indirizzo 0.
Se il target restituisce una risposta Modbus valida, lo scanner considera il servizio rilevato.
Un pacchetto Modbus/TCP è composto da:
+----------------------+----------------------+
| Intestazione MBAP | PDU |
+----------------------+----------------------+
Intestazione MBAP:
+------------------+
| ID Transazione | 2 byte
| ID Protocollo | 2 byte
| Lunghezza | 2 byte
| Identificatore | 1 byte
| Unità |
+------------------+
PDU:
+------------------+
| Codice Funzione | 1 byte
| Dati | N byte
+------------------+
L'intestazione MBAP è specifica di Modbus/TCP.
La prima sonda dello scanner utilizza il Codice di Funzione 0x04.
Una richiesta rappresentativa è:
00 01 00 00 00 06 01 04 00 00 00 01
Scomposizione:
00 01 Identificatore Transazione
00 00 Identificatore Protocollo
00 06 Lunghezza
01 Identificatore Unità
04 Codice Funzione
00 00 Indirizzo di Partenza
00 01 Quantità
00 01
Identifica la transazione.
Il valore può variare perché l'identificatore di transazione è normalmente gestito dalla libreria client Modbus.
00 00
Un valore di 0 identifica Modbus.
00 06
Specifica il numero di byte successivi al campo lunghezza.
01
Identifica l'unità Modbus target.
04
Il Codice di Funzione 0x04 significa:
Lettura Registri di Ingresso
00 00
Lo scanner parte dall'indirizzo di registro 0.
00 01
Lo scanner richiede un registro.
Una risposta di successo alla richiesta contiene il Codice di Funzione 0x04 e i dati del registro richiesto.
Una risposta rappresentativa potrebbe essere:
00 01 00 00 00 05 01 04 02 00 00
Scomposizione:
00 01 Identificatore Transazione
00 00 Identificatore Protocollo
00 05 Lunghezza
01 Identificatore Unità
04 Codice Funzione
02 Conteggio Byte
00 00 Valore Registro
La parte importante per il rilevamento è che il target elabori con successo la richiesta Modbus e restituisca una risposta Modbus valida a livello applicativo.
Il valore effettivo del registro dipende dal dispositivo.
Semplicemente verificare:
TCP/502 = APERTA
non dimostra necessariamente che il servizio sia Modbus.
I numeri di porta sono convenzioni. Un'applicazione diversa può essere in ascolto su TCP/502, e un dispositivo Modbus può anche comportarsi diversamente a seconda della sua configurazione.
Lo scanner utilizza quindi:
Connettività TCP
+
Risposta protocollo Modbus
=
Rilevamento Modbus
Questo rende il rilevamento a livello applicativo più significativo di una semplice scansione delle porte.
Alcuni dispositivi potrebbero non rispondere alla richiesta iniziale 0x04 a causa della loro configurazione dei registri o dei codici di funzione supportati.
Lo scanner tenta quindi una seconda richiesta se la prima fallisce:
modbus_read_bits(ctx, 0, 1, bits);
Questo utilizza il Codice di Funzione:
0x01 - Lettura Bobine
Una richiesta rappresentativa è:
00 02 00 00 00 06 01 01 00 00 00 01
Scomposizione:
00 02 Identificatore Transazione
00 00 Identificatore Protocollo
00 06 Lunghezza
01 Identificatore Unità
01 Codice Funzione
00 00 Indirizzo di Partenza
00 01 Quantità
Lo scanner considera il target rilevato quando una delle due operazioni Modbus riceve una risposta di successo.
IP Target
|
v
Connessione TCP
porta 502
|
+------+------+
| |
Fallita Connessa
| |
v v
Ignora Funzione 0x04
|
+------+------+
| |
Valida Fallita
| |
v v
MODBUS TROVATO Funzione 0x01
|
+------+------+
| |
Valida Fallita
| |
v v
MODBUS TROVATO Nessun rilevamento
Lo scanner utilizza libmodbus per costruire e analizzare i pacchetti Modbus/TCP invece di costruire manualmente i frame del protocollo.
L'operazione principale è:
modbus_read_input_registers(ctx, 0, 1, ®);
Se questa fallisce:
modbus_read_bits(ctx, 0, 1, bits);
La connessione viene quindi chiusa e il contesto libmodbus viene liberato.
Questo mantiene la gestione del protocollo all'interno della libreria Modbus mentre lo scanner gestisce:
Lo scanner utilizza timeout brevi per la connessione e la risposta:
#define TIMEOUT_SEC 2
Questo impedisce a un singolo host irraggiungibile o non reattivo di bloccare un worker per un periodo di tempo eccessivo.
Le reti industriali possono contenere dispositivi con risposte relativamente lente, quindi i valori di timeout potrebbero dover essere regolati a seconda dell'ambiente.
I target vengono suddivisi tra più thread worker.
Ad esempio:
Thread 1 → target 1–64
Thread 2 → target 65–128
Thread 3 → target 129–192
Thread 4 → target 193–254
Ogni worker tenta indipendentemente il rilevamento Modbus/TCP.
Questo consente di testare più host contemporaneamente invece di attendere ogni target in sequenza.
Un risultato positivo significa che il target ha risposto con successo a una richiesta Modbus compresa dallo scanner.
Non identifica necessariamente:
Queste sono attività separate di fingerprinting o valutazione.
Lo scanner è principalmente uno strumento di rilevamento del servizio Modbus/TCP.
Il metodo di rilevamento è intenzionalmente conservativo.
Un dispositivo può essere in grado di supportare Modbus ma fallire il rilevamento se:
Pertanto:
Nessuna risposta ≠ Definitivamente non Modbus
Significa che lo scanner non ha potuto ottenere una risposta di successo utilizzando le sonde che ha tentato.
Installa le dipendenze richieste e compila con:
make
Oppure direttamente:
gcc -Wall -Wextra -O2 -o modbus modbus.c -lmodbus -lpthread
Esegui:
./modbus -i 192.168.1.0 -s /24 -t 10 -o results.txt
Esempio:
[+] Modbus rilevato: 192.168.1.20:502
[+] Modbus rilevato: 192.168.1.42:502
[+] Scansionati: 254 | Trovati: 2 Modbus
[+] Risultati salvati in: results.txt
Lo scanner rileva i servizi Modbus/TCP eseguendo un'interazione effettiva con il protocollo piuttosto che affidandosi esclusivamente al rilevamento della porta TCP.
Il processo di rilevamento è:
Connetti a TCP/502
↓
Invia Codice di Funzione Modbus 0x04
↓
Ricevi risposta Modbus valida?
↓
SÌ → Modbus rilevato
|
NO
↓
Invia Codice di Funzione Modbus 0x01
↓
Ricevi risposta Modbus valida?
↓
SÌ → Modbus rilevato
|
NO
↓
Nessun rilevamento
Il principio chiave è semplice:
Rileva il protocollo, non solo la porta.