Jednym z prostszych do wyeliminowania zagrożeń w sieciach firmowych są łatwo dostępne interfejsy webowe służące do zarządzania elementami infrastruktury. Mimo to, z mojego doświadczenia wynika, że znalezienie takiego interfejsu i to często z domyślnym hasłem to wciąż pewniak w prawie każdym teście bezpieczeństwa.
Kilka przykładów:
- Interfejs UPSa dający możliwość wyłączenia zasilania, nierzadko dla całej szafy lub serwerowni. Często spotykany domyślny użytkownik i hasło: apc, apc.
- Interfejsy zdalnego zarządzania serwerami np. HP iLO, Dell iDRAC, IBM IMM pozwalające na wyłączenie lub przejęcie konsoli. Często dają dostęp do serwera wirtualizacji na którym działa od kilku do kilkunastu maszyn wirtualnych. Często spotykany domyślny użytkownik i hasło to dla serwerów Dell: root, calvin oraz dla serwerów IBM: USERID, PASSW0RD
- Interfejsy pamięci masowych – często nieaktualizowane i z podatnościami
- Interfejsy systemów do monitoringu wizyjnego (często spotykane stare i podatne wersje Dahua z domyślnym użytkownikiem i hasłem 888888, 888888 lub 666666, 666666)
- Interfejsy urządzeń sieciowych (switche, routery, kontrolery WLAN, firewalle)
- Interfejsy telefonów VOIP, często bez żadnych zabezpieczeń
- Interfejsy drukarek
- Interfejsy systemów OT (np. sterowniki fotowoltaiki, klimatyzacji)
W dużym środowisku sieciowym znaleźć można często setki lub nawet tysiące urządzeń udostępniających webowe interfejsy administracyjne. Ich obecność często wiąże się z problemem nazywanym shadow IT, polegającym na tym, że do sieci podłączane są urządzenia, w których zakupie i wdrożeniu nie bierze udziału dział IT.
Często też o obecności takich interfejsów po prostu się zapomina. Wynika to z faktu, że są one potrzebne na etapie wdrożenia, ale gdy już wszystko zostanie skonfigurowane rzadko się do nich zagląda.
Rekonesans przez skanowanie
W tym artykule chciałbym się z wami podzielić metodą na szybkie znalezienie i identyfikację takich interfejsów w dużym środowisku. Pierwszym narzędziem, które przychodzi nam do głowy jest oczywiście skaner portów nmap. Możemy za jego pomocą znaleźć np. wszystkie otwarte porty 80 i 443 w danej podsieci:
nmap -p80,443 192.168.1.0/24
Ale wyobraźmy sobie, że takich podsieci mamy kilka lub jest to podsieć z maską /16 i skaner zwraca nam kilkaset znalezionych adresów IP z otwartym portem 80 lub 443. Musielibyśmy odwiedzić przeglądarką każdy z tych adresów aby ustalić jaka zawartość serwowana jest przez usługę http lub https.
Można tutaj posłużyć się tzw. banner grabbingiem, czyli próbą ustalenia typu i wersji aplikacji za pomocą zwracanych przez usługę komunikatów powitalnych (banerów), poprzez dodanie do parametrów skanowania opcji -sV:
nmap -p80,443 -sV 192.168.1.0/24
Nie zawsze jednak zwrócone wyniki pozwolą nam w prosty sposób ustalić z jakim urządzeniem lub aplikacją mamy do czynienia:
Nmap scan report for 192.168.1.66
Host is up (0.0026s latency).
PORT STATE SERVICE VERSION
80/tcp open http GoAhead WebServer
W takim wypadku konieczne będzie jednak odwiedzenie powyższej strony i naoczne ustalenie jaki system odpowiedzialny jest za jej udostępnianie.
I tutaj z pomocą przychodzi nam mechanizm skryptów dostępny w narzędziu nmap. W domyślnym katalogu /usr/share/namap/scripts znajdziemy setki skryptów, które wykorzystać możemy podczas skanowania sieci nmap-em. Nie ma jednak wśród nich skryptu, który ułatwiłby nam automatyczne obejrzenie każdej strony serwowanej na portach 80 lub 443. Skrypt taki spróbujemy zatem stworzyć sami. I zobaczycie za moment, że nie jest to wcale takie skomplikowane, jak by się mogło wydawać.
Web screenshot
Zacznijmy od znalezienia narzędzia, które będziemy mogli wykorzystać w skrypcie, a którego głównym zadaniem będzie wykonanie zrzutu ekranu ze strony www. Chcemy wygenerować obrazek, na którym znajdzie się zawartość odwiedzanej strony bez konieczności odwiedzania jej przeglądarką. Narzędzi, które pozwalają wykonać taką operację za pomocą komendy wywoływanej z linii poleceń jest co najmniej kilka. Ja po krótkim przeglądzie wymaganych zależności, oferowanych możliwości i łatwości użycia wybrałem aplikację 'webscreenshot’ napisaną w pythonie. Można ją znaleźć na githubie: https://github.com/maaaaz/webscreenshot albo zainstalować za pomocą managera bibliotek python:
pipx install webscreenshot
W powyższym przykładzie użyłem polecenia 'pipx’ zamiast 'pip’ ponieważ korzystam z dystrybucji Kali Linux, która zarządza pakietami pythona za pomocą apt. W domyślnym repozytorium Kali Linuxa nie ma jednak pakietu apt dla narzędzia webscreenshot. 'Pipx’ zainstaluje je więc nie psując zależności w pythonowym środowisku venv użytkownika. Polecenie będzie dostępne w ścieżce /home/nazwa_uzytkownika/.local/bin/webscreenshot. Wywołując aplikację jako parametry podać musimy adres ip i numer portu, na którym dostępna jest usługa http(s) oraz silnik za pomocą którego wyrenderowana zostanie zawartość strony (np. chrome, chromium, firefox, edgechromium):
/home/kali/.local/bin/webscreenshot -r chromium http://192.168.1.66:80
webscreenshot.py version 2.94
[+] 1 URLs to be screenshot
[+] 1 actual URLs screenshot
[+] 0 error(s)
Wynik działania powyższego polecenia zapisany został do pliku pod nazwą screenshot/http_192.168.1.66_80.png. Szybki rzut oka na zapisany obrazek pozwala nam z łatwością stwierdzić co kryło się pod tajemniczą nazwą usługi „GoAhead WebServer” zwracaną wcześniej przez nmap-a:

Tworzymy skrypt nmap
Teraz pozostaje już nam tylko zautomatyzować poprzedni krok tworząc skrypt dla nmap-a. Jego zadaniem będzie wywołanie polecenia webscreenshot dla każdego adresu IP, na którym zidentyfikowany zostanie otwarty port 80 lub 443. Cały skrypt prezentuje się następująco:
description = [[
Get a screenshot of the URL
]]
license = "GPLv2"
categories = {"discovery", "safe"}
local shortport = require "shortport"
local stdnse = require "stdnse"
portrule = shortport.http
action = function(host, port)
local prefix = "http"
if port.number == 443 then
prefix = "https"
end
local filename = "" .. prefix .. "_" .. host.ip .. "_" .. port.number .. ".png"
local cmd = "/home/kali/.local/bin/webscreenshot -r chromium " .. prefix .. "://" .. host.ip .. ":" .. port.number .. " 2> /dev/null >/dev/null"
local ret = os.execute(cmd)
local result = "failed (something went wrong)"
if ret then
result = "Saved to ./screenshots/" .. filename
end
return stdnse.format_output(true, result)
end
W pierwszych liniach skryptu definiujemy opis, licencję, kategorie pod którymi skrypt zostanie skatalogowany przez nmapa (discovery, safe) oraz wymagane biblioteki (shortport, stdnse). Następnie przypisujemy zmiennej prefix wartość http lub https w zależności od tego czy mamy do czynienia z portem 80 czy 443. Z jej pomocą definiujemy kolejną zmienną filename, pod którą przechowywana będzie nazwa pliku wynikowego. Składnia polecenia webscreenshot definiowana jest w zmiennej cmd, która jest następnie wywoływana przez funkcję os.execute. Wynik uruchomienia zwracany jest natomiast do zmiennej ret. I w zależności od jej zawartości skrypt kończy się komunikatem o błędzie: something went wrong lub informacją o miejscu zapisania pliku wynikowego „saved to ./screenshots/nazwa_pliku„.
Aby móc korzystać ze skryptu należy go zapisać w domyślnym katalogu np. pod nazwą /usr/share/nmap/scripts/webscreenshot.nse, a następnie wywołać polecenie:
nmap --script-updatedb
Od teraz do parametrów skanowania nmap-em możemy dołączyć wywołanie naszego skryptu:
nmap -p80,443 --script webscreenshot 192.168.1.0/24
Wynikiem takiego skanowania będzie folder screenshots zawierający obrazy z wszystkimi znalezionymi interfejsami webowymi:

Ich przejrzenie nawet przy sporej ilości wyników będzie dużo łatwiejsze niż analizowanie zwracanych przy zwykłym skanowaniu banerów lub ręczne odwiedzanie każdej strony.
Karygodnym błędem jest również obecność takich interfejsów w domyślnym, a często też jedynym vlanie. Ale tym zajmiemy się już w innym artykule.
Zostaw e-mail aby otrzymać powiadomienia o nowych wpisach oraz dostęp do bonusowych materiałów przygotowanych wyłącznie dla subskrybentów.