Felhívjuk az Olvasók figyelmét arra, hogy ez a cikk azért született meg, hogy felhívjuk a figyelmet a titkosított protokollok alkalmazására. Nem célunk, és határozottan elzárkózunk attól, hogy segítsünk bárkinek számítógépes bűncselekmények elkövetésében.
Az OT protokollok olyan kommunikációs protokollok, amelyeket ipari hálózatokon történő vezérlőüzenetek, adatok cseréjére terveztek. A Modicon által a programozható logikai vezérlőkhöz (PLC-khez) kifejlesztett Modbus protokoll kliens/szerver kommunikációt biztosít a különböző típusú buszokon vagy hálózatokon csatlakoztatott eszközök között.
Ahhoz, hogy a virtuális PLC-nken Modbus szerver legyen, el kellett végezni a korábbi cikkben ismertetett telepítési folyamatot. Ez még önmagában nem elég, szükség van egy olyan szerver programra is, amely a különböző kéréseket kiszolgálja. Az Interneten több ilyen alkalmazás is található, az általunk használt (minimálisan módosított) program itt érhető el:
https://github.com/riptideio/pyModbus
A cikk írásakor a következő program került alkalmazásra. Kiegészítésre került a logolással, ezért a különböző műveletek láthatók a virtuális PLC-t megvalósító Ubuntu operációs rendszer terminálablakában.
#!/usr/bin/env python
'''
Asynchronous Modbus Server Built in Python using the pyModbus module
'''
# Import the libraries we need
from pymodbus.server.asynchronous import StartTcpServer
from pymodbus.device import ModbusDeviceIdentification
from pymodbus.datastore import ModbusSequentialDataBlock
from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext
import logging
# Create a datastore and populate it with test data
store = ModbusSlaveContext(
di = ModbusSequentialDataBlock(0, [17]*100), # Discrete Inputs initializer
co = ModbusSequentialDataBlock(0, [17]*100), # Coils initializer
hr = ModbusSequentialDataBlock(0, [17]*100), # Holding Register initializer
ir = ModbusSequentialDataBlock(0, [17]*100)) # Input Registers initializer
context = ModbusServerContext(slaves=store, single=True)
# Populate the Modbus server information fields, these get returned as
# response to identity queries
identity = ModbusDeviceIdentification()
identity.VendorName = 'Webelektronika'
identity.ProductCode = 'online'
identity.VendorUrl = 'https://github.com/riptideio/pyModbus'
identity.ProductName = 'Modbus Server'
identity.ModelName = 'PyModbus'
identity.MajorMinorRevision = '1.0'
FORMAT = ('%(asctime)-15s %(threadName)-15s' '%(levelname)-8s %(module)-15s:%(lineno)-8s %(message)s')
logging.basicConfig(format=FORMAT)
log = logging.getLogger()
log.setLevel(logging.DEBUG)
# Start the listening server
print ('Starting Modbus server...')
StartTcpServer(context, identity=identity, address=("0.0.0.0", 502))
Fontos az, hogy a vizsgálógépünk ugyanabban a hálózatban legyen, mint a virtuális PLC. Nézzük meg a Kali Linux VM IP címét, ehhez adjuk ki a következő parancsot.
ipconfig
Az első ábrán látható a Kali Linux operációs rendszert futtató virtuális gép IP címe, amely a következő: 192.168.1.107
1. ábra Kali Linux vizsgálógép IP címének a lekérése
Nézzük most meg, hogy milyen egyéb gépek, stb találhatók az otthoni, saját (!) hálózaton. Használjuk erre a célra szintén az "nmap"-ot és az ICMP protokollt, ezért alkalmazzuk az "-sP" kapcsolót.
sudo nmap -sP 192.168.1.1/24
Az ICMP protokoll segítségével (pingelés) megkeressük a hálózaton lévő eszközöket, és természetesen a virtuális PLC-t is (2. ábra).
2. ábra A hálózaton lévő eszközök felderítése
A virtuális PLC-nk a 192.168.1.105-ös IP címen található. Megtaláltuk tehát a PLC-t a hálózaton, a következő lépés most az, hogy megnézzük, hogy ezen az IP címen milyen szolgáltatások találhatók (azaz, milyen portok vannak nyitva).
(ahhoz, hogy a Modbus működjön, indítsuk el az Ubuntu virtuális gépen a cikk elején közölt python kódot)
sudo python3 server2.py
Elindult a Modbus szerver az Ubuntu virtuális gépen, ez látható a következő ábrán.
3. ábra Az Ubuntu operációs rendszeren elindításra kerül a Modbus szerver
Most már megnézhetjük a Kali Linux alatt, hogy a virtuális PLC-n milyen szolgáltatások találhatók. Tekintettel arra, hogy a Modbus portja (502, 5020) az "nmap"-nál nem tartozik a default portok közé, célszerű teljes port scan-t végezni, azaz, alkalmaznunk kell a "-p-" kapcsolót.
sudo nmap -p- 192.168.1.105
Látható a 4. ábrán a teljes port scan eredménye, az 502-es porton üzemel az "mbap".
4. ábra A virtuális PLC-t megvalósító Ubuntu operációs rendszeren feldeítésre kerül az összes nyitott TCP port
Kérjünk most le verziószámokat, ehhez a következő utasítás kiadása szükséges. (Egyébként felesleges most már a teljes port scan alkalmazása, ez feleslegesen növeli a scan futási idejét.)
sudo nmap -sV -p- 192.168.1.105
Az 5. ábrán láthatók a szolgáltatások a hozzájuk tartozó verziószámokkal. Sajnos a Modbusról nem kaptunk érdemi információt.
5. ábra A virtuális PLC nyitott portokkal, és a portokon lévő szolgáltatások a verziószámaikkal
Próbáljunk meg egy másik scanbeállítást. Alkalmazzuk a "-O" és a "-A" kapcsolókat, illetve már csak nyitott portokat használjuk.
sudo nmap -p 21,22,23,80,502 -O -A 192.168.1.105
Sajnos most sem sikerült érdemi információkat szerezni a Modbusról.
6. ábra Újabb port scan a virtuális PLC nyitott portjain
Az "nmap" port scan-nél használhatók különböző script-ek is, amelyek az adott szolgáltatás megismerésénél segíthetnek. Az "nmap" rendelkezik olyan script-tel, amely a Modbus felderítésénél használható. Adjuk ki a következő parancsot.
sudo nmap -p 502 --script modbus-discover 192.168.1.105
Az 502-es TCP porton található Modbus szerverről már több információ áll rendelkezésünkre (7. ábra), látható a "WebElektronika-online-1.0". (Emlékeztetőül, ezt írtuk be a korábban elindított Python alkalmazásban.)
7. ábra A Modbus szerver adatainak a lekérdezése
A lekérdezés által generált hálózati forgalom megtekinthető a Wireshark grafikus felületén is. Ahhoz, hogy a Modbushoz tartozó hálózati csomagok kerüljenek csak megjelenítésre, alkalmazzuk a "modbus" filtert.
8. ábra A "modbus-discover" script által generált hálózati forgalom, a forgalomban titkosítás nélkül kiolvashatók az érzékeny adatok
Könnyen észrevehető a Modbus/TCP protokoll hibája, ez a kommunikációs megoldás nem rendelkezik titkosítással. Az érzékeny adatok könnyen kiolvashatók a hálózati forgalomból.
Írjuk/olvassuk most a Modbus szerver regisztereit. Ezekre a műveletekre az Interneten több megoldás is található, mi az "mbtget" alkalmazást fogjuk használni. Ezért a Github-ról le kell tölteni az "mbtget"-et, ezért a Kali Linux terminálablakában adjuk ki a következő utasítást.
gti clone https://github.com/sourceperl/mbtget.git
Látható a 9. ábrán, hogy az "mbtget" könyvtár tartalmát lemásoljuk a Kali Linux VM-re.
9. ábra Az "mbtget" klónozása
Most már alkalmazható az "mbtget" script, és először kérjük le a helpet, hogy megismerjük ennek az alkalmazásnak a paraméterezését,
./mbtget -h
A script futtatása után a következő felsorolás lesz a terminál ablakban.
usage : mbtget [-hvdsf] [-2c]
[-u unit_id] [-a address] [-n number_value]
[-r[12347]] [-w5 bit_value] [-w6 word_value]
[-p port] [-t timeout] serveur
command line :
-h : show this help message
-v : show version
-d : set dump mode (show tx/rx frame in hex)
-s : set script mode (csv on stdout)
-r1 : read bit(s) (function 1)
-r2 : read bit(s) (function 2)
-r3 : read word(s) (function 3)
-r4 : read word(s) (function 4)
-w5 bit_value : write a bit (function 5)
-w6 word_value : write a word (function 6)
-f : set floating point value
-2c : set "two's complement" mode for register read
-hex : show value in hex (default is decimal)
-u unit_id : set the modbus "unit id"
-p port_number : set TCP port (default 502)
-a modbus_address : set modbus address (default 0)
-n value_number : number of values to read
-t timeout : set timeout seconds (default is 5s)
Először olvassuk ki a 0. címen lévő memóriarekesz tartalmát, majd írjunk bele ellentétes tartalmat, azután újra olvassuk ki ugyanazt a memóriarekeszt. Ehhez el kell indítani a "mbtget/scripts" könyvátr alatt található "mbtget" script-et a következő paraméterezéssel.
Először kiolvassuk a 0. memóriarekesz tartalmát. (Az eredmény 0 lesz (10. ábra).
./mbtget -r1 -a 0 192.168.1.105
Ezután 1-et írunk be a kérdéses memóriarekeszbe.
./mbtget -w5 1 -a 0 192.168.1.105
Most újra kiolvassuk ugyanazt a memóriarekeszt. Látható a 10. ábrán, hogy az előbb beírt érték került kiolvasásra.
./mbtget -r1 -a 0 192.168.1.105
Ez az írás/olvasás folyamat látható a 10. ábrán.
10. ábra Kiolvasásra kerül a 0. cím tartalma, majd ide logikai 1-et írunk, majd újra kiolvassuk az adott memóriaterület értékét
Nézzük meg ez a folyamatot a hálózati forgalomban. A Wireshark grafikus megjelenítési felületén látható, hogy mindig egy "query" történt, azután pedig egy "Response". Történik tehát egy kérés (pl.: Read Colls"), majd erre a kérésre érkezik a válasz (11. ábra).
11. ábra Kérés-válasz a Modbus protokollnál
Nézzük meg a Wiresharkban most a memóriarekesz első olvasásánál a "Modbus" csomag tartalmát (12. ábra). Látható a "Bit 0" értéke, amely "0".
12. ábra Első olvasás, a kiolvasott érték "0"
Nézzük most meg a hálózati forgalomban azt az olvasási folyamatot, amely az írás után történt. Látható a hálózati forgalomban, hogy a kérdéses bit értéke már nem "0", hanem "1".
13. ábra A kiolvasott érték "1", tehát az írás művelete is sikeres volt
Könnyen észrevehető tehát az, hogy az ipari környezetben széles körben alkalmazott Modbus protokoll nem rendelkezik semmilyen titkosítással. A kezelése egyszerű, könnyen elsajátítható a használata, de az alkalmazásával nagy árat fizetünk az IT biztonság területén.
Az érzékeny adatok kényelmesen megismerhetők/módosíthatók.
Egy diagnosztikai parancs, amelyet a támadó használhat, a Read Device Identification (eszközazonosítás olvasása), amellyel megpróbál információkat gyűjteni a Modbus eszközről: A 43-as funkciókóddal ellátott MODBUS-kérelem Read Device Identification (Eszközazonosítás olvasása) arra készteti a Modbus kiszolgálót, hogy visszaadja a gyártó nevét, a termék nevét és a verziószámot. A támadó elküldi a 43-as funkciókóddal ellátott Modbus kérelmi csomagot a hálózat összes rendszerének, és olyan információkat gyűjt, amelyek hasznosak lehetnek a későbbi támadások során.
Még egyszer felhívjuk az Olvasók figyelmét arra, hogy ez a cikk azért született meg, hogy rámutassunk a Modbus protokoll használatának a veszélyére, és a védekezés fontosságára. Határozottan elhatárolódunk bármilyen bűncselekmény elkövetésének a segítésében.
Az információs rendszer vagy adat megsértése bűncselekmény (423. §).
Az nmap (grafikus megjelenítésnél a ZenMap) használata az IT biztonság, illetve az üzemeltetés területén dolgozó szakembereknél szinte elkerülhetetlen. Az ingyenes szoftver segítségével tesztelhetők a számítógépeink, a számítógéphálózatunk, vizsgálha. . . .
A Python programozási nyelv nagyon elterjedt a fejlesztők körében. Használják beágyazott rendszereknél, webes alkalmazásoknál, IT biztonság különböző területein, stb. Látható, hogy nagyon széles a felhasználási területe ennek a nyelvnek, ideje volt m. . . .
Elkezdjük most részletesebben megismerni az nmap használatát. Az nmap nagyon fontos eszköz az IT biztonsággal, illetve az üzemeltetéssel foglalkozó szakembereknél. De hogyan működik? Hogyan lehet és érdemes a scannelési tulajdonságokat beállítani? M. . . .