Zapobieganie wirusom i przypadkowym błędom w oprogramowaniu SCADA/HMI

Przeanalizowanie niektórych koncepcji technicznych może pomóc użytkownikowi końcowemu w zrozumieniu i zapobieganiu usterkom oprogramowania, zagrażającym bezpieczeństwu, powstałym podczas tworzenia aplikacji programowych SCADA/HMI oraz architektur sieci leżących u ich podstaw.
14 lipca 2010 r. fikcja zeszła z ekranu filmowego i stała się rzeczywistością. Tego dnia słynny już dziś Stuxnet – pierwszy wirus atakujący systemy SCADA, nadzorujące przebieg procesu technologicznego lub produkcyjnego, został użyty do wyłączenia i uszkodzenia znacznej części irańskiej infrastruktury nuklearnej. Wiedza o tym wydarzeniu miała początkowo wpływ głównie na osoby związane z branżą automatyki, jednak gdy doszło do kolejnych przypadków naruszenia bezpieczeństwa danych w znanych na rynku firmach, takich jak Sony czy Target, świadomość zagrożenia cyberbezpieczeństwa stała się powszechna w korporacjach na całym świecie.
Trzeba jednak pamiętać, że obok celowych, zaplanowanych ataków pojawiają się również takie zdarzenia, jak niezamierzona nieprawidłowa konfiguracja lub rozmaite nieadekwatne działania pracowników, grup serwisowych itp., przez które powstają luki w zabezpieczeniach. Obecne systemy są bowiem wysoce zintegrowane i złożone z wielu warstw oprogramowania, zaś w większości przypadków osoba tworząca je i obsługująca niekoniecznie do końca rozumie, w jaki sposób dochodzi między nimi do interakcji.
Tworzenie scenariuszy dla cyberataku
Jak zaobserwowano w ostatnich latach, takie elementy, jak wysoki poziom integracji w systemach rozproszonych, stopień złożoności architektury sieci oraz istnienie wielu warstw oprogramowania wykorzystywanego w obecnych systemach automatyki i technologii informacyjnej (IT) tworzą środowisko ułatwiające prowadzenie cybernetycznych ataków.
W przypadku przedsiębiorstw odnosi się to również do systemów SCADA, musi więc istnieć zabezpieczenie nie tylko przed zamierzonymi zagrożeniami. Często bowiem osoby tworzące i obsługujące fabryczne systemy automatyki nie są wystarczająco zaznajomione z istniejącą kompleksową infrastrukturą i wieloma warstwami architektury sieci oraz współpracującego z nią oprogramowania. A zatem dopóki nie zostaną stworzone dobre standardy zabezpieczeń, może się zdarzyć (a nawet jest to bardzo prawdopodobne), że błędy w działaniu czy niepoprawnie prowadzone procedury konserwacji i aktualizacji wpłyną na niezawodność i stabilność systemu, skutecznie tworząc w nim niezamierzonego wirusa lub otwierając furtkę podmiotom zewnętrznym, mającym złe zamiary.
Dla systematycznej identyfikacji potencjalnych zagrożeń oraz ich unikania potrzebna jest matryca weryfikacji. W jednym jej wymiarze użytkownik powinien zabezpieczać oprogramowanie oraz infrastrukturę IT, w oparciu o które działa oprogramowanie typu SCADA i HMI. W drugim wymiarze analizy wymaga sam projekt automatyki, w szczególności konfiguracja i działanie platformy SCADA.
Pierwszym wymiarem analizy zabezpieczeń jest więc podstawowa infrastruktura sprzętowa, programowa oraz sieciowa, która zajmuje się procedurami aktualizacji łatek bezpieczeństwa systemów operacyjnych, zabezpieczaniem dostępu za pomocą loginów i haseł, pracą w sieci itd. Ta analiza nie jest jednak specyficzna dla systemów SCADA lub HMI i powinna być realizowana według ustanowionych standardów IT – istnieje już w tym zakresie wiele dostępnych źródeł i dobrych praktyk. Należy zatem skoncentrować się na drugim wymiarze: opracowaniu samego projektu automatyki programowej, obejmującego konfigurację SCADA/HMI, działanie i wdrażanie oprogramowania.
Zagrożenia zamierzone
Sprawą kluczową jest oczywiście potrzeba zabezpieczenia przed zagrożeniami zamierzonymi. Nie tylko z powodu scenariusza, w którym jacyś wrogowie z zewnątrz ingerują w infrastrukturę produkcyjną, ale także z bardziej prozaicznych przyczyn: jeśli jest możliwe wywołanie zagrożenia, ktoś w końcu na pewno tego dokona. Nawet gdy powodem będzie wyłącznie wyzwanie techniczne, tak jak w przypadku wielu wirusów komputerowych – stworzonych nie dla zysku, ani w celu dokonania specyficznego ataku, a tylko po to, aby ich autor miał satysfakcję.
Ewolucja umiejętności programistycznych, technologii oprogramowania i komunikacyjnych, jaka nastąpiła w ciągu ostatnich piętnastu lat, posunęła się daleko poza możliwe aktualizacje większości dostępnych narzędzi programowych i produktów automatyki. Nawet ci użytkownicy, którzy zaktualizowali swoje narzędzia do najnowszych wersji, tak naprawdę nie byli i nie są zabezpieczeni. Większość z tych rozwiązań jest bowiem oparta na istniejących, przestarzałych technologiach, które może złamać każdy obeznany w sprawach technicznych nastolatek.
Zagrożenia niezamierzone
Wraz z postępującą zwiększoną złożonością systemów wykonanie kompletnej symulacji każdego wyobrażalnego scenariusza w fazie testowania, podczas odbioru technicznego, może okazać się niemożliwe. Jakość i stabilność działania systemów muszą więc być zapewnione podczas testowania urządzeń za pomocą technologii i architektur samoistnie bezpiecznych. Faktem jest, że wiele systemów wcale nie wykorzystuje najnowszych i bezpiecznych technologii. Zamiast tego, aby chronić istniejącą już infrastrukturę i platformy systemowe, tworzą one wokół własnego kodu i technologii odziedziczonych swego rodzaju „opakowania” oraz warstwy kodu i modułów.
Ten scenariusz jest wielce ryzykowny, ponieważ pozostawia wiele kluczowych komponentów systemu i jego jądra ekstremalnie podatnych na zagrożenia podczas pojawiania się potencjalnych problemów losowych, gdy czynione są próby uruchamiania starszych programów na nowych komputerach, w nowych systemach operacyjnych, nowych sieciach i nowych procedurach operacyjnych. W tym środowisku prawdopodobne jest wystąpienie błędów. Być może nawet nie w czasie normalnego działania, gdy są łatwe do wykrycia, ale wtedy, gdy sprawą najważniejszą staje się to, aby system sterowania i nadzoru nie uległ awarii. Czyli np. podczas stresu towarzyszącego aktywności na wysokim poziomie lub w sytuacjach nieprawidłowej realizacji procesu, awarii sieci czy komputerów, generowania wielu alarmów, wykonywania poprzednio niewykonanego kodu błędu braku dostępu do ścieżki lub kodu odzyskiwania systemu albo w efekcie nieprawidłowo wykonanych poleceń. Użytkownicy końcowi mogą się spodziewać, że te potencjalne błędy pojawią się więc dokładnie w najgorszym możliwym momencie, w sytuacji nieprawidłowej realizacji procesu o kluczowym znaczeniu dla firmy.
Przykładem niezamierzonej przerwy w działaniu systemu była sytuacja, która występowała podczas nocnych zmian w pewnej fabryce. Błąd aplikacji powodował przypadkowe wyłączenia komunikacji pomiędzy systemami SCADA/HMI a kluczowymi sterownikami logicznymi PLC, co powodowało zatrzymywanie całego procesu technologicznego. System działał przedtem przez wiele miesięcy doskonale, a problemy zaczęły się ujawniać bez żadnych modyfikacji konfiguracji projektu. Powstało zatem podejrzenie pojawienia się wirusa lub zamierzonego sabotażu.
Po długim okresie nocnego monitorowania działań operatorów i przebiegu procesu odkryto, że ktoś uruchamiał wygaszacz ekranu w komputerze operatora. Z powodu problemu sprzętowego w tym komputerze podczas wyłączenia ekranu wyłączał się także chip 8250 – wykorzystywany do komunikacji za pomocą portu RS232 – w taki sposób, że tylko wyłączenie i włączenie zasilania mogło przywrócić działanie tego portu. Problem nie był przypadkowy czy złośliwy, występował tylko podczas nocnych zmian, gdy operator opuszczał swoje stanowisko na wystarczająco długo, aby włączył się wygaszacz ekranu. Technik, który postanowił uaktywnić ów wygaszacz, aby zaoszczędzić i sam ekran, i trochę energii, był całkowicie nieświadomy efektów ubocznych, które pojawiały się w obsługiwanym przez niego sprzęcie.
Podany przykład dobrze opisuje sytuację i typowe kroki podejmowane w przypadku niezamierzonych zagrożeń. Zauważmy bowiem, że:
a) operatorzy urządzeń fabrycznych oraz informatycy firmy nie mieli pełnej znajomości wielu warstw złożonego systemu, obejmowanych przez interakcję automatyki programowej i sprzętowej. To całkowicie normalne: ani nie jest to możliwe, ani nie można oczekiwać, aby pracownicy na tych stanowiskach posiadali całą tę wiedzę;
b) modyfikacje systemu podrzędnego lub środowiska albo zmiany w procedurach operacyjnych, które, jak przypuszczano, były całkowicie nieszkodliwe, spowodowały niepożądane efekty uboczne;
c) efekty uboczne mogą się rozwinąć w większe problemy z powodu niewykrytych błędów opóźnienia (latency error) i z powodu nieprzewidzianych sytuacji, mających miejsce w przyłączonych warstwach;
d) wynikający z tego błąd lub problem może pozostać niewykryty w krótkich okresach lub sprawiać wrażenie przypadkowego zachowania.

<—newpage—>Bezpieczeństwocyklu realizacji projektu
Aby systematycznie identyfikować potencjalne zagrożenia, należy przeanalizować cykl realizacji projektu. W uproszczonym modelu składa się on z czterech etapów:
1. Wybór technologii, architektury i narzędzi.
2. Konfiguracja projektu i programowanie.
3. Wdrożenie i przekazanie do eksploatacji.
4. Eksploatacja i konserwacja.
Pozyskanie większej wiedzy na temat każdego z tych etapów pomaga we włączeniu procedur i narzędzi bezpieczeństwa do projektu. Etap obejmujący wdrożenie projektu i przekazanie go do eksploatacji jest dla większości systemów jednym z momentów najbardziej podatnych na zagrożenia.
1. Technologie i bezpieczeństwo architektury systemu
Wyobraźmy sobie próbę znacznego zwiększenia bezpieczeństwa kierowcy i pasażerów samochodu wyprodukowanego w latach 80. ubiegłego wieku poprzez zamontowanie w nim takich akcesoriów, jak poduszki powietrzne i czujniki czy wykorzystanie innych nowoczesnych rozwiązań. To nie zadziała. Podobnie we współczesnych systemach automatyki – konieczna jest modernizacja od podstaw oprogramowania sterującego, aby systemy te były bezpieczne w dzisiejszych środowiskach operacyjnych. Zastosowanie nowoczesnych technologii przyniesie wówczas również wszystkie potencjalne zyski, które nie są dostępne w rozwiązaniach opartych na przestarzałych jądrach systemów operacyjnych. W rzeczywistych aplikacjach istnieją i wciąż działają niebezpieczne, przestarzałe technologie, których należy unikać, takie jak interpretowane skrypty utworzone w językach VBScript i VBA oraz językach firmowych, takich jak C lub C++ – z powodu braku wskaźników i narzędzi ochrony pamięci, komponentów ActiveX, interfejsów COM, DCOM oraz otwartych gniazd TCP/IP. Preferowane technologie obejmują: języki kompilowane z ochroną pamięci do pisania skryptów, takie jak C#, VB.NET oraz klientów sieci Web z czystymi technologiami internetowymi (z zabezpieczeniami typu security sand-box – „piaskownica” albo partial-trust – „z częściowym zaufaniem”), WCF (Windows Communication Foundation – platformę do tworzenia aplikacji), usługi internetowe i bazy danych SQL. Na str. 50 podano zestawienie starszych i współczesnych technologii.
2. Konfiguracja projektu i bezpieczeństwo programowania
Dobre praktyki w konfigurowaniu i obsługiwaniu projektów obejmują centralizację różnych konfiguracji w bazie danych SQL lub na serwerze, co pozwala użytkownikom na bezpieczny dostęp, wbudowane zarządzanie zmianami i kontrolę wersji podczas aktualizacji projektu oraz możliwość zdalnego uruchamiania diagnostyki, przeprowadzania pełnych testów nowych aplikacji i aktualizowania systemu bez przerywania jego pracy.
Stary wzorzec testowania projektu został opracowany tylko w celu zwykłego uruchomienia aplikacji. Współczesne standardy wymagają wyższego poziomu walidacji w fazie konfigurowania oraz użycia specyficznych narzędzi do symulacji, profilowania i analizy działania.
Potencjalne problemy spowodowane przez wirusa lub przypadkowy błąd aplikacji są do siebie podobne. Matematyka analizy pokrycia kodu uczy, że zapewnienie niezawodności wyłącznie za pomocą scenariuszy testowych jest niemożliwe. Na przykład wyczerpujące testowanie aplikacji tylko dziesięciu instrukcji If-Then-Else powinno wymagać uruchomienia aż 1024 scenariuszy. A zatem walidacje zabezpieczeń i niezawodności powinny być wbudowane w architekturę, technologie i procedury programowania. Ponadto zainstalowany system SCADA powinien mieć wbudowany jakiś system śledzenia i zarządzania wersją, tak aby narzędzie automatycznie samo zapisywało wszelkie zmiany konfiguracji.
3. Wdrożenie projektu i bezpieczeństwo podczas przekazania go do eksploatacji
Wdrożenie projektu jest jednym z obszarów najbardziej podatnych na zagrożenia bezpieczeństwa, co stwierdzono w wyniku analizy działania najnowszych wirusów.
Wiele systemów nadal funkcjonujących w produkcji przemysłowej jest opartych na technologiach oprogramowania pochodzących z lat 90. lub nawet 80. ubiegłego wieku, w których pakiety oprogramowania HMI/SCADA były zależne w swoim działaniu od setek niezależnych plików konfiguracyjnych i bibliotek komunikacyjnych DLL (Dynamic-Link Library – biblioteka łączona dynamicznie). W tych systemach może wystąpić jakiś niezamierzony błąd, zaś programowanie wirusów wymaga tylko podstawowych umiejętności programistycznych na najniższym poziomie, typu „wrzucenie kilku plików do folderu”. Nawet gdy wiele pojedynczych plików mogło być zaszyfrowanych lub istnieć w formie binarnej, nie było żadnych więzów pomiędzy nimi a ich projektem macierzystym. Każdy mógł utworzyć dodatkowe pliki na dowolnym komputerze i zwyczajnie wkleić je do odpowiedniego folderu, aby zmodyfikować działanie projektu. Co prawda uzyskanie informacji na temat tego, które alarmy należy wyłączyć albo które punkty nastaw sterowników trzeba zmienić, aby wygenerować zagrożenie dla realizacji procesu technologicznego, może być zadaniem złożonym, ale samo programowanie wirusów wymaga tylko podstawowych umiejętności programistycznych, a ryzyko przypadkowego pozostawienia lub skopiowania nieprawidłowych plików jest bardzo wysokie. Nowa generacja współczesnych narzędzi opiera się natomiast na zaszyfrowanych plikach tylko do odczytu, utworzonych w strukturalnym języku zapytań (Structured Query Language – SQL), aby zapewnić bezpieczne wdrożenie ich konfiguracji.
Oto prosta lista zaleceń, pomocna w redukowaniu zagrożeń w starszych systemach oraz przy wyborze i wdrażaniu nowych:
-> starsze produkty i instalacje – pliki konfiguracyjne powinny być skopiowane do nowych folderów, które na pewno przedtem były puste, a zwykły użytkownik, logujący się podczas uruchomienia projektu do systemu Microsoft Windows, powinien mieć tylko prawa do odczytu tych folderów. Systemy o największym znaczeniu dla fabryki powinny być wyposażone w zewnętrzny program użytkowy, który sprawdza całkowity rozmiar i sumę kontrolną plików zainstalowanych do sterowania procesem produkcji, z plikami utworzonymi zdalnie przez firmę, która realizowała integrację systemów;
-> wybór i wdrożenie nowych systemów – w idealnej wersji cała konfiguracja projektu powinna być przechowywana w jednym pliku wdrożenia systemu, takim jak zaszyfrowana baza danych SQL tylko do odczytu. Zarządzanie wersją oraz zmianami powinno się opierać na wbudowanych cechach, a nie narzędziach zewnętrznych czy procedurach ręcznych.
Innym obszarem podatności na zagrożenia w starszych systemach jest model sterownika protokołu komunikacyjnego. W wielu systemach protokół taki opiera się na zewnętrznych plikach DLL, utworzonych za pomocą otwartych narzędzi programowych, które da się łatwo zastępować innymi plikami DLL, co może wstrzymać działanie systemu. W narzędziach nowej generacji sterowniki działają jako odizolowane procesy, bez bezpośredniego dostępu do pozostałej części aplikacji. Są w nich wdrożone narzędzia do weryfikacji wartości oraz nadające status „tylko do odczytu”, co zabezpiecza te pliki przed modyfikowaniem po zakończeniu procesu przekazania systemu do eksploatacji.
4. Działanie i konserwacja systemów
Dobre systemy zabezpieczające użytkowników, zawierające funkcje kontroli dostępu oparte na rolach oraz grupach, są już dostępne w większości systemów poprzedniej generacji. Większość systemów mogła także wykazywać parametry, na podstawie których były one zgodne z wymaganiami odpowiednich przepisów (takichjak np. amerykański Kodeks Przepisów Federalnych, FDA CFR 21 Część 11). Te nowe ulepszone cechy działania i konserwacji mają na celu eliminację niebezpiecznych elementów typu runtime, takich jak Active-X, dodając wbudowane zabezpieczenia i kontrolę zarządzania zmianami podczas aktualizowania projektu oraz możliwość zdalnego uruchamiania diagnostyki lub aktualizacji systemu bez przerywania jego działania. Ponadto sprawą kluczową jest zarówno kontrola wersji w projektach (ścieżki audytu), jak i zdolność do zarządzania wieloma wersjami na tym samym komputerze. Zabezpieczenie dostępu do danych powinno być możliwe do zdefiniowania na wyświetlaczach graficznych oraz przy każdym znaczniku, w tabeli definicji bazy danych podstawowych znaczników, podobnie jak zabezpieczenia interfejsu użytkownika.
Aktualizacja narzędzi programowych jest powszechną przyczyną wymuszonych przerw w działaniu systemu, co wywołuje nieprzewidziane zachowanie uruchomionej aplikacji. Nowoczesne systemy powinny także pozwalać na instalację nowej wersji projektu i narzędzi programowych bez usuwania poprzedniej, przy jednoczesnym działaniu obu wersji obok siebie, na tym samym serwerze oraz uruchomionym oprogramowaniu typu execution engine (silnik wykonawczy) poprzedniego systemu i nowej planowanej aktualizacji. W ten sposób możliwe jest uruchomienie testu walidacyjnego przed zastosowaniem zmian w aplikacji sterującej procesem produkcyjnym.
Odnawianie fundamentów
Podsumowując – koncepcja, zgodnie z którą dodanie do samochodu sprzed kilku dekad współczesnych akcesoriów nie uczyniłoby go równie bezpiecznym dla kierowcy jak najnowsze modele aut, odnosi się także do infrastruktury oprogramowania, używanej w przemysłowych aplikacjach automatyki. Wiele starszych systemów opiera się na fundamentach oprogramowania stworzonych w latach 80. i 90. ubiegłego wieku. Chociaż w tamtych czasach były one bardzo solidne, to nie mogą spełniać dzisiejszych wymagań dotyczących zabezpieczeń. Nie są w stanie obsługiwać większości nowych technologii oprogramowania, które zostały opracowane w ostatniej dekadzie i nieustannie ewoluują.
W ostatnich latach rozwój technologii oprogramowania, komunikacji oraz interfejsów użytkownika przyspieszył, a zatem w większości fabryk nie jest konieczne odnawianie całego systemu automatyki. Odnowienie systemów SCADA/HMI może przynieść wiele natychmiastowych korzyści dla bezpieczeństwa systemu, stabilności działania, niezawodności i elastyczności, zapewniając optymalizację informacji i umożliwiając osiągnięcie zwrotu z inwestycji, co pozwala na działania, które nie polegają wyłącznie na potrzebie zwiększania bezpieczeństwa. Oczekiwane zyski z odnowienia oprogramowania do poziomu prawdziwie nowoczesnej technologii nie są wyrażane w procentach. Widzimy je poprzez zestawienie złożonych czynników, które zapobiegają potencjalnym problemom dotyczącym bezpieczeństwa, mogącym poważnie wpłynąć na proces produkcji oraz umożliwiają osiągnięcie większej wydajności zasobów zarządzanych przez te systemy.
Autor: Marcos Taccolini jest dyrektorem generalnym firmy Tatsoft LLC.
Tekst pochodzi ze specjalnego wydania “Bezpieczeństwo 2017“. Jeśli Cię zainteresował, ZAREJESTRUJ SIĘ w naszym serwisie, a uzyskasz dostęp do darmowej prenumeraty w formie drukowanej i/lub elektronicznej.