Koparka na Twoim serwerze?Usuwanie malware
← Blog
Bezpieczeństwo

kinsing i kdevtmpfsi w kontenerze WordPress: dlaczego pkill w cronie nie wystarcza

Na serwerze ktoś ustawił cron, który co 2 minuty zabijał koparkę. Objaw zniknął, przyczyna została. Co sprawdzić i jak zamknąć porty, których UFW nie widzi.

Proces kdevtmpfsi w kontenerze z WordPressem to koparka kryptowalut z rodziny kinsing. Zabijanie jej cronem z pkill tylko ukrywa objaw, bo furtka, którą weszła, zostaje otwarta. Trzeba ustalić wektor wejścia, zamknąć porty, które Docker wystawia z pominięciem UFW, i zmienić sekrety. Poniżej opisujemy dwa serwery, na których znaleźliśmy ten sam cron, i co z niego wynikło.

Co to jest kinsing i proces kdevtmpfsi?

kinsing to malware znane z atakowania usług wystawionych do internetu: niezabezpieczonego Docker API, Redisa bez hasła, źle skonfigurowanych aplikacji. Po wejściu uruchamia koparkę, która w liście procesów zwykle widnieje jako kdevtmpfsi. Objaw jest prosty. Serwer zwalnia, a jeśli na jednym VPS-ie stoi kilka sklepów w osobnych kontenerach, zwalniają wszystkie naraz, bo koparka w jednym kontenerze zabiera procesor całej maszynie.

Dlaczego pkill kinsing w cronie nie wystarcza?

Na pierwszym serwerze koparka siedziała w kontenerze WordPressa, na VPS-ie współdzielonym z innymi sklepami. Ktoś przed nami dodał na hoście wpis, który w uproszczeniu wyglądał tak:

*/2 * * * * pkill kinsing; pkill kdevtmpfsi

Objaw zniknął z widoku. Przyczyna nie została jednak usunięta, wektora nikt nie ustalił, a cron przy okazji zacierał jedyny sygnał, że atakujący wciąż ma dostęp. Koparka między kolejnymi uruchomieniami crona miała do 2 minut pracy, a każdy, kto potrafił ją wgrać, mógł wgrać też coś innego.

Przegląd reszty serwera pokazał, dlaczego wejście było łatwe:

  • panel Nginx Proxy Manager dostępny publicznie na porcie 81, po HTTP,
  • origin osiągalny z pominięciem Cloudflare,
  • Ubuntu po końcu wsparcia, bez łatek bezpieczeństwa od około roku,
  • 357 katalogów zapisywalnych dla wszystkich (o+w),
  • UFW nieaktywne, brak fail2ban,
  • codzienny docker restart wszystkich kontenerów jako „łatka”.

Jak sprawdzić, czy koparka nadal działa?

Na drugim serwerze był dokładnie ten sam cron. Tu audyt dał inny wynik: infekcja historyczna. Sprawdziliśmy:

  1. Plik /etc/ld.so.preload. Rootkity używają go do ukrywania procesów przed ps i top. Tu go nie było.
  2. Klucze SSH. Pliki authorized_keys wszystkich kont. Obcych kluczy brak.
  3. Procesy i połączenia wychodzące. Nic podejrzanego w ps ani w ss -tunp.
  4. Katalogi tymczasowe. /tmp czyste.
  5. Logi. Wpisy z „kinsing” w syslogu okazały się echem samego crona z pkill, a nie śladem aktywnej koparki.

Zarekomendowaliśmy zamianę crona zabijającego na taki, który tylko loguje. Działa jak kanarek: jeśli koparka wróci, zobaczysz to w logach, zamiast ją po cichu zabijać.

*/2 * * * * pgrep -a 'kinsing|kdevtmpfsi' | logger -t miner-canary

Uwaga: cron z pkill nie jest dowodem infekcji, ale jego brak w logach też nic nie mówi. Rozstrzyga dopiero audyt hosta i kontenerów.

Masz ten sam problem? Widzisz kdevtmpfsi albo cron z pkill na swoim serwerze? Sprawdzimy, czy infekcja jest aktywna i którędy weszła. Opisz sytuację →

Dlaczego Docker omija UFW?

Publikacja portu w docker-compose (ports:) dodaje regułę prosto do iptables. Ruch do kontenera nie przechodzi przez reguły UFW, a ufw status tej reguły nie pokazuje. Administrator widzi zamkniętą zaporę i uważa temat za załatwiony, podczas gdy baza danych, Redis czy panel phpMyAdmin odpowiadają na połączenia z dowolnego adresu w internecie.

Każdy port, który nie musi być publiczny, bindujemy na localhost:

services:
  db:
    ports:
      - "127.0.0.1:3306:3306"

Druga warstwa to reguły DROP w łańcuchu DOCKER-USER, który Docker sprawdza przed własnymi regułami. Na jednym serwerze zablokowaliśmy tak porty PHP-FPM 9000–9300:

iptables -I DOCKER-USER -i eth0 -p tcp -m conntrack --ctorigdstport 9000:9300 -j DROP

Te reguły nie przeżywają restartu serwera, dlatego zapisaliśmy je w skrypcie uruchamianym z crona przez @reboot. Na innym VPS-ie podobne DROP-y objęły Redis, phpMyAdmin, Typesense, serwer vite i API.

IPv6: druga furtka obok zapory

W innym audycie zapora dla IPv4 była w porządku, ale IPv6 omijał ją całkowicie. Po IPv6 otwarte były Redis bez hasła, MariaDB, Typesense i phpMyAdmin, a aplikacja łączyła się z bazą jako root. Reguły iptables nie obejmują IPv6, do tego służy osobne ip6tables, więc serwer trzeba skanować z zewnątrz po obu adresach, a nie tylko po tym, który widnieje w DNS sklepu.

Jak sprawdzić, czy Redis w kontenerze ma hasło?

redis-cli -h <adres-serwera> ping

Dwa kontenery na jednym z audytowanych serwerów odpowiedziały PONG bez autoryzacji. Firewall je osłaniał, ale requirepass nie był ustawiony, więc jeden błąd w regułach wystarczyłby do pełnego dostępu. Docelowo ustawiamy hasło i bindujemy Redisa na 127.0.0.1 albo nie publikujemy portu wcale, jeśli korzysta z niego tylko aplikacja w tej samej sieci Dockera.

Co zrobić po wykryciu kinsinga na serwerze?

  1. Zabezpiecz dowody przed sprzątaniem: listę procesów, crontaby, logi.
  2. Ustal wektor. Sprawdź każdą usługę dostępną z internetu: Docker API, Redis, bazy danych, PHP-FPM na 0.0.0.0, panele administracyjne.
  3. Zamknij porty. Bind na 127.0.0.1, DROP w DOCKER-USER, osobno IPv6.
  4. Postaw kontenery od nowa z czystych obrazów zamiast sprzątać działające.
  5. Zaktualizuj system. Ubuntu bez wsparcia to otwarte znane luki.
  6. Panel proxy i origin schowaj za VPN albo ogranicz do adresów Cloudflare.
  7. Zamień pkill na kanarka, żeby wiedzieć, czy koparka wraca.
  8. Zmień sekrety: hasło bazy, klucze API, dane SMTP, hasła administratorów, i wyczyść sesje.

Rotację sekretów zalecamy także wtedy, gdy audyt pokazuje infekcję historyczną. Nie wiadomo, co atakujący odczytał, zanim cron zaczął zabijać koparkę.

Jeśli na tym samym serwerze stoją strony WordPress, sprawdź też je. Objawy włamania od strony aplikacji opisaliśmy w artykule o tym, jak rozpoznać wirusa na stronie WordPress.

Kiedy zlecić to specjalistom?

Gdy na jednym VPS-ie działa kilka sklepów, a nikt nie wie, co publikuje Docker i dlaczego cron zabija procesy. W ASAPDevs zaczynamy od audytu hosta i kontenerów, potem zamykamy porty i sprzątamy. Tak wygląda nasze usuwanie malware i zabezpieczenie serwera WordPress. Jeśli wolisz, żeby ktoś stale pilnował aktualizacji i reguł zapory, zobacz opiekę nad serwerem w Pogotowiu IT.

Kamil Perzowski
Kamil Perzowski
CEO i co-founder ASAPDevs. Programuje i utrzymuje sklepy, aplikacje webowe i serwery klientów. LinkedIn · Usuwanie malware
Masz ten sam problem?

Koparka na Twoim serwerze?

Kamil Perzowski, ASAPDevs
Kamil Perzowski
CEO & Co-founder, ASAPDevs
Ustalamy, którędy weszło malware, zamykamy porty wystawione przez Dockera i sprzątamy serwer z WordPressem. Pilne? Zadzwoń: +48 884 220 764.
★★★★★
Pan Kamil wspaniale pomógł nam i stworzył nasz sklep internetowy! Lepiej nie mogliśmy trafić! Serdecznie polecamy :)
Kwiaciarnia M., opinia w Google
  1. Czytam zgłoszenie i odpisuję z pytaniami albo propozycją terminu rozmowy.
  2. Krótka rozmowa o zakresie, dostępach i terminie.
  3. Dostajesz plan i wycenę. Decydujesz, bez zobowiązań.

Wolisz od razu porozmawiać? +48 884 220 764 · [email protected]

Wysyłając formularz, przekazujesz nam dane, żebyśmy mogli odpowiedzieć. Szczegóły w polityce prywatności.

FAQ

Pytania i odpowiedzi

Czy kdevtmpfsi to wirus?

+
To koparka kryptowalut uruchamiana przez malware kinsing. Sama nie kradnie danych, ale zjada procesor serwera. Gorsze jest to, że jej obecność oznacza, że ktoś obcy uruchomił kod na Twojej maszynie.

Czy wystarczy usunąć pliki kinsing i kdevtmpfsi?

+
Nie. Jeśli furtka, przez którą weszła koparka, zostaje otwarta, infekcja wraca. Najpierw trzeba ustalić wektor i zamknąć wystawione usługi, potem posprzątać i zmienić hasła.

Dlaczego ufw status nie pokazuje portów otwartych przez Dockera?

+
Docker dopisuje własne reguły bezpośrednio do iptables, z pominięciem UFW. Port opublikowany w docker-compose działa z internetu, choć UFW o nim nie wie. Sprawdzaj porty skanem z zewnątrz, a nie tylko poleceniem ufw status.

Jak sprawdzić, czy Redis w kontenerze ma hasło?

+
Połącz się z innej maszyny przez redis-cli i wyślij PING. Odpowiedź PONG bez podawania hasła oznacza, że każdy, kto dotrze do portu, może czytać i zapisywać dane.

Czy restart kontenerów usuwa koparkę?

+
Nie. Restart zabija proces, ale nie zamyka drogi, którą weszło malware. Na serwerze z kinsingiem codzienny docker restart wszystkich kontenerów służył jako „łatka”, a przyczyna została na miejscu.

Przeczytaj też