Podczas prezentacji na DotnetConfPL zabrakło mi demo podłączenia się do bazy danych. Zostało już mało czasu, a ja chciałem pokazać kawałek kodu, więc otworzyłem działający projekt. Wszystko fajnie, ale w F# z SQLProviderem trzeba wpisać hasło do bazy bezpośrednio w kodzie. Więc hasło do produkcyjnej bazy danych wyciekło mi niechcący na żywo.
W tym poście opiszę kroki jakie atakujący mógłby przedsięwziąć, żeby dostać się do moich danych.
1. Analizowanie wideo
Z tego co pokazałem dowiemy się, że dla mojej aplikacji widoczny jest host o IP 172.17.0.2
. Jest to prywatne IP w sieci dockera, więc niewiele nam to dało. Po drugie zdobyliśmy hasło.
2. Szukanie aplikacji
Teraz mając hasło, wejdziemy na mojego GitHuba i znajdziemy tam projekt, któremu to hasło odpowiada. Notka dla mnie: zmień hasło na takie, żeby nie dało się z niego wywnioskować aplikacji, do której ono pasuje.
Z projektu na GitHubie dowiemy się jaki jest adres strony: https://ref.polskaligaquidditcha.pl
3. Analizowanie aplikacji
Możemy sprawdzić czy na tym serwerze działa istancja bazy MySQL (poprzez nmap, albo klienta mysql), o tym że jej używam widać w kodzie. Ale nie działa. Możemy przypuścić, że dostęp do bazy danych będzie ograniczony z zewnątrz.
A co jeśli działa tam instancja serwisu administracyjnego tej bazy danych? Przypuśćmy, że jest na innym serwerze (jak na tym samym to byśmy próbowali enumerować różne ścieżki). Więc rzucimy zapytanie DNS do głównej domeny:
host -l polskaligaquidditcha.pl
Oczywiście nie dostaniemy tak żadnego wyniku, bo serwery DNS mają domyślnie wyłączony mechanizm AXFR, który na to pozwala. Jedynie kilka podrzędnych serwerów DNS jest na liście IP, które mogą wyciągać informacje strefy z głównego serwera DNS.
Kolejnym krokiem jest sprawdzenie subdomen w serwisie do testów penetracyjnych https://pentest-tools.com/reconnaissance/find-subdomains-of-domain.
Co ciekawe, wylistowane są wszystkie domeny, które mam podpięte pod proxy w Cloudflare. Ale akurat tej mojej strony do administracji bazy danych tam nie ma.
Można dalej próbować zrobić odpowiednie zapytanie do googli (brak wyników).
Zasięgnąłem dalszych porad w internecie na security.stackexchange i znalazłem narzędzie knock
napisane w pythonie: https://github.com/guelfoweb/knock
W gruncie rzeczy używa ono ataku słownikowego na domenę. Po lekkiej modyfikacji (dla każdego słowa z listy sprawdzamy również konkatenację tego słowa ze wszystkimi innymi), co wydłużyło czas sprawdzania kwadratowo, udało mi się w końcu natrafić na wszystkie rekordy. Jeśli słownik nie zawierałby właściwej nazwy to mógłbym jeszcze pokusić się o atak brute-force.
Sporo zachodu, żeby znaleźć subdomeny i o ile w tym przypadku próbujemy zaatakować mało istotny portal, to w przypadku gdy atakujemy poważną instytucję, odpowiednio spreparowany atak, w krótkim czasie (albo długim, ale realnym do wykonania) znajdzie nasz cel.
4. Wejście na portal adminstracyjny
Mamy już w rękach naszą domenę z dostępem do portalu administracyjnego bazy danych. Pozostało już tylko wejść i wpisać login i hasło i dostać pełny dostęp do bazy danych.
Ja oczywiście jak tylko sobie uzmysłowiłem, co zrobiłem, to wyłączyłem ten portal, żeby nikt mi się do bazy nie wkradł. Sama baza ma dostęp tylko z sieci lokalnej, więc bezpośrednio nie sposób się do niej włamać.
Kolejnym krokiem będzie zmienić hasło i zdeployować aktualizację na produkcję.
Podsumowanie
Mam nadzieję, że dowiedzieliście się z tego postu o tym jak znaleźć czyjś serwer, na którym może być luka do wykorzystania, i o tym jak istotne jest odpowiednio się zabezpieczyć przed stratą hasła.
Plusem ASP.NET z Entity Framework nad Suave z SQLProviderem jest to, że ASP.NET trzyma hasło w oddzielnym pliku konfiguracyjnym, a przynajmniej jest taka łatwa w użyciu opcja.
Jeszcze raz zachęcam do obejrzenia mojej prezentacji i śledzenia bloga przez kolejne tygodnie 😉