Phishing to oszutwo, w którym przestępca podszywa się pod inną osobę lub instytucję w celu wyłudzenia poufnych informacji lub pieniędzy. Zespół CERT Polska chroni nas przed niebezpiecznymi stronami publikując listy. Dostępne są w wielu formatach. jeżeli znajdziesz złośliwą stronę, możesz zgłosić to do CSIRT NASK. W artykule wykorzystamy wymieniony feed w SIEM Elastic Stack i spróbujemy coś wykryć .
A komu to potrzebne? A dlaczego?
Domeny phishingowe Cie nie przekonują? Ten wpis to tylko przykład wrzucania feeda do Elastica. Wiele mechanizmów wzbogacania i detekcji może być częścią czegoś większego. Równie dobrze może to być zaufane źródło dotyczące grup APT.
Nawet jeżeli takie domeny są blokowane na Firewall’ach, warto takie przypadki monitorować i reagować. Może użytkownik nawet nie zdaje sobie sprawy przed czym go obroniliśmy?
Środowisko
W przykładzie korzystałem z
- Elasticsearch + Kibana 8.0.0 – możesz posłużyć się moim repozytorium: zorteran/elastic-stack-docker-boilerplate utworzonym na ptorzeby mojego Kursu Elastic Stack
- Logstash 8.0.0 – Zainstalowany wg dokumentacji. Logstashem będziemy wrzucać dane od CERT Polska.
- Packetbeat 8.0.0 – Zainstalowany wg dokumentacji. Uzyłem tylko po to by wygenerować jakiś ruch na którym możemy sprawdzić feed.
- Filebeat 8.0.0 – Zainstalowany wg dokumentacji. Włączyłem moduł Threat Intel, aby dopasować CERT’owy feed to adekwatnego schematu.
Feed Cert Polska
Feed znajduje się pod adresem Lista ostrzeżeń przed niebezpiecznymi stronami | CERT Polska. Interesuje nas wersja w postaci JSON.
[ { "RegisterPositionId": 47292, "DomainAddress": "olx-pl.potwierdzenie594.com", "InsertDate": "2022-02-13T17:32:58", "DeleteDate": null }, ... ]Threat Intel
W świecie cyberbezpieczeństwa istnieje takie pojęcie jak Cyber Threat Intelligence (CTI). Jest to obszar zajmujący się kolekcją i analizą informacji o potencjalnych zagrożeniach.
Filebeat posiada moduł Threat Intel za pomocą którego możemy pobierać podejrzane IoC (Indicator of Compromise), czyli potencjalne artefakty świadczące np. o włamaniu o naszej sieci. Takie artefakty to najczesciej adresy IP, domeny, ścieżki, hashe i techniki używane przez adwersaży. Poniżej przykład dokumentu z serwisu URLhaus | Malware URL exchange (abuse.ch)
{ "fileset": { "name": "abuseurl" }, "@timestamp": "2022-02-13T16:15:26.579Z", "service": { "type": "threatintel" }, "abusech": { "url": { "larted": true, "url_status": "online", "blacklists": { "surbl": "not listed", "spamhaus_dbl": "not listed" }, "id": "2042489", "threat": "malware_download", "tags": [ "32-bit", "elf", "mips", "Mozi" ] } }, "threat": { "indicator": { "reference": "https://urlhaus.abuse.ch/url/2042489/", "first_seen": "2022-02-13T16:07:05.000Z", "provider": "geenensp", "ip": "117.194.160.219", "type": "url", "url": { "path": "/bin.sh", "extension": "sh", "original": "http://117.194.160.219:43792/bin.sh", "scheme": "http", "port": 43792, "domain": "117.194.160.219", "full": "http://117.194.160.219:43792/bin.sh" } }, "feed": { "name": "[Filebeat] AbuseCH URL", "dashboard_id": "ad9c7430-72de-11eb-a3e3-b3cc7c78a70f" } }, "event": { "...":"..." } }Biorąc pod uwagę powyższy dokument oraz dokumentacje ECS dla pola Threat, wymyśliłem formę widoczną poniżej. Ważna jest zgodność z ECS. Zachowanie spójności w nazewnictwie upraszcza pracę analitykom oraz umożliwia wykorzystanie wszystkich funkcjonalności Kibany.
{ "event": { "category": "threat", "id": 47286, "kind": "enrichment", "type": "indicator", "module": "threatintel", "dataset": "threatintel.cert_pl" }, "related": { "hosts": "www.p24.auction" }, "@timestamp": "2022-02-13T15:14:43Z", "@version": "1", "tags": [ "nask" ], "threat": { "indicator": { "url": { "domain": "www.p24.auction" }, "marking": { "tlp": "WHITE" }, "confidence": "High", "modified_at": "2022-02-13T16:21:00.322801Z", "deleted_on": null, "first_seen": "2022-02-13T15:14:43Z", "type": "domain-name", "provider": "CERT Polska" } } }Logstash
Logika przetwarzania jest dość prosta. Dokumenty pobierane są dzięki http_pooler (lista od CERT Polska odświeżana jest co 5 minut), a po żąglerce polami i datami, dokumenty zapisywane są do Elasticsearch’a. Należy zwrócić uwagę na tryb upsert oraz wskazanie id dokumentu. Ten sposób załatwia nam sprawę z duplikatami. Domen nie ma aż tak dużo, więc pod kątem wydajnościowym nie powinno być problemu.
input { http_poller { urls => { myurl => "https://hole.cert.pl/domains/domains.json" } schedule => { cron => "*/5 * * * * UTC"} } } filter { mutate { rename => {"DomainAddress" => "[threat][indicator][url][domain]"} rename => {"InsertDate" => "[threat][indicator][first_seen]"} rename => {"DeleteDate" => "[threat][indicator][deleted_on]"} rename => {"RegisterPositionId" => "[event][id]"} copy => {"[threat][indicator][url][domain]" => "[related][hosts]"} copy => {"@timestamp" => "[threat][indicator][modified_at]"} add_field => { "[threat][indicator][provider]" => "CERT Polska" } add_field => { "[threat][indicator][type]" => "domain-name" } add_field => { "[threat][indicator][confidence]" => "High" } add_field => { "[threat][indicator][marking][tlp]" => "WHITE" } add_field => { "[event][kind]" => "enrichment" } add_field => { "[event][category]" => "threat" } add_field => { "[event][module]" => "threatintel" } add_field => { "[event][type]" => "indicator" } add_field => { "[event][dataset]" => "threatintel.cert_pl" } add_tag => [ "nask" ] } date { match => ["[threat][indicator][first_seen]", "yyyy-MM-dd'T'HH:mm:ss"] } mutate { copy => {"@timestamp" => "[threat][indicator][first_seen]"} } if [threat][indicator][deleted_on] { date { match => ["[threat][indicator][deleted_on]", "yyyy-MM-dd'T'HH:mm:ss"] target => "[threat][indicator][deleted_on]" } } } output { #stdout {} elasticsearch { hosts => ["https://192.168.63.134:9200"] user => "some_user" password => "some_password" index => "threatintel-cert_pl-v1" manage_template => false doc_as_upsert => true document_id => "%{[event][id]}" ssl_certificate_verification => false # :-) } }Template
Logstash zapisuje dokumenty w indeksie threatintel-cert_pl-v1. Na podstawie index template wygenerowanego przez Filebeat utworzyłem swoją, okrojoną wersję. Głownym powodem wykorzystania index template jest:
- Zgodność z ECS (mapping)
- Alias filebeat-threatintel-cert_pl, aby indeks łapał się pod standardowy index pattern filebeat-*
- Powtarzalność
Github Gist: CERT Polska Elasticsearch index template (github.com)
Kibana
Threat Intelligence
W zakładce Overview modułu Security widać efekty naszej pracy. Source o nazwie Others to właśnie nasz nowy feed.

Zgodność z ECS oraz alias na filebeat-threatintel-cert_pl robi robotę również w dashboardzie z modułu Theat Intel w Filebeat.

Detekcja
Wykorzystamy w tym przypadku regułę typu Indicator Match. Szuka wystąpień wartości zdefiniowanych pól we indeksach. W tym przypadku oparlem się o zapytania dns czyli dns.question.name (indeks packetbet-*) oraz threat.indicator.url.domain (indeks threatintel-cert-v1).

A więc czas wejść w sidła phishingu… Wybrałem pierwszą lepszą stronę. Okazało się, iż podszywa się pod KGHM.
 seems legit
seems legit Jak widac poniżej, reguła wystrzeliła. Pierwsza linia może zakładać incydent. Świat ponowanie został uratowany .

 W szczegółach alertu widzimy IoC i jego adekwatności.
W szczegółach alertu widzimy IoC i jego adekwatności.Uwaga!
Regułą typu Threat Intel jest dość kosztowna obliczeniowo. Elastic nie jest dobry JOIN’ach, więc wykonanie obsługiwane jest na poziomie węzła typu coordinate (a adekwatnie tym z którym ‘rozmawia’ Kibana).
 Dopiero po zwiększeniu stosu JVM Kibana reguła zaczęła poprawnie działać.
Dopiero po zwiększeniu stosu JVM Kibana reguła zaczęła poprawnie działać.Czy mozna to zrobić lepiej?
Ależ oczywiście! W dużej skali reguła może znacznie obciążać klaster. IoC’ki z czasem sie deaktualizują, więc warto brac te najświeższe: @timestamp >= "now-30d". Feed od CERT Polska jest trochę inny. Można odfiltrować domeny które mają wartość threat.indicator.deleted_on.
Można do tematu podejść od drugiej strony, czyli wzbogacać dokumenty przed zapisaniem ich w klastrze Elasticsearch. Oto lista alternatwynych podejść:
- Logstash – posiada wiele filtrów do wzbogacania danych. Nie chcesz stawiać osobnej bazy z IoC? Może wystarczy zwykły plik YAML? Filtr translate radzi sobie choćby z 100k klucz/wartość.
- ksqlDB – o możliościach tego rozwiązania wspominałem w tym wpisie.
- Enrich processor – możemy wzbogacać dane choćby na poziomie Elasticsearch’a. Mniej usług do utrzymywania
Podsumowanie

















