Malware persistence cPanelen: amikor a takarítás után is marad hátsó ajtó

English version: cPanel malware persistence: cron jobs, backdoors and recurring infections
Egy cPanel frissítés ellenőrzéséből lett incidensvizsgálat
2026. szeptember 8-án eredetileg nem malware-incidenst vizsgáltunk. Egy bejelentett kritikus cPanel & WHM biztonsági frissítés miatt több production szerveren ellenőriztük, hogy megfelelően működik-e az automatikus security update mechanizmus.
Az egyik CloudLinux alapú cPanel szerveren az óránként futó biztonsági frissítés ellenőrzése közben azonban olyan felhasználói cron bejegyzések kerültek elő, amelyeknek semmi keresnivalójuk nem volt egy normál tárhelyfiókban.
Az egyik bejegyzés leegyszerűsítve így nézett ki:
*/5 * * * * test -f /home/USER/public_html/.sys-mta-XXXX.php || cp /tmp/.cache/.sys_XXXX.php /home/USER/public_html/.sys-mta-XXXX.php 2>/dev/null # SYSCHKA cron ötpercenként ellenőrizte, hogy létezik-e egy rejtett PHP-fájl a webrootban. Ha nem találta, egy másik rejtett helyről próbálta volna visszamásolni.
Ez már nem egyszerű fertőzött fájl volt, hanem persistence mechanizmus: a célja az volt, hogy a rosszindulatú állomány egy takarítás után ismét létrejöhessen.
Az Imunify takarított, de a cron megmaradt
A következő lépésben megnéztük a cron által hivatkozott fájlokat.
A .sys-mta-*.php és .sys_*.php állományok egy része már 0 bájtos volt, más fájlokban pedig az Imunify korábbi malware-cleanupjának jelölése szerepelt.
Vagyis a biztonsági rendszer a veszélyes kódot már korábban eltávolította vagy semlegesítette.
A cron azonban ott maradt.
Ez az incidens egyik legfontosabb tanulsága: egy rosszindulatú fájl megtisztítása még nem feltétlenül jelenti a teljes fertőzés megszüntetését.
Ha a webshellt létrehozó cron, egy második backdoor vagy más persistence mechanizmus megmarad, a támadó kód később újra megjelenhet.
A CloudLinux az Imunify cleanup működéséről külön dokumentációban is leírja, hogy a megtisztított állományban maradhat olyan jelölés, amely arra utal, hogy a fájl korábban rosszindulatú kódot tartalmazott.
CloudLinux: Imunify malware cleanup artifacts
Nem csak egy tárhelyfiók volt érintett
Az első találat után már nem egyetlen weboldalt vizsgáltunk.
Szerver-szinten kerestünk rá ugyanazokra a persistence mintákra:
grep -RniE \
'SYSCHK|defunct-kernel|/tmp/\.cache|\.sys-mta|\.sys_[A-Za-z0-9]+\.php' \
/var/spool/cronA rejtett PHP-fájlokat külön is ellenőriztük:
find /home -xdev -type f \
\( -name '.sys-mta-*.php' -o -name '.sys_*.php' \) \
-lsA keresés több, egymástól Unix user szinten elkülönített cPanel accountban is kompromittálódásra utaló nyomokat talált.
Ez azért fontos, mert ilyen helyzetben már nem szabad automatikusan arra következtetni, hogy egyetlen sérülékeny Joomla vagy WordPress oldal fertőzte meg saját magát.
Vizsgálni kell a közös tényezőket is:
- újrahasznált vagy kompromittált jelszavakat,
- cPanel-, FTP- és SSH-hozzáféréseket,
- mentett hitelesítő adatokat,
- fertőzött fejlesztői számítógépet,
- közös, elavult webalkalmazásokat vagy bővítményeket.
A rendelkezésünkre álló bizonyítékok ugyanakkor nem igazolták a szerver root szintű kompromittálódását.
Előkerült a defunct-kernel persistence is
A vizsgálat során egy másik minta is megjelent.
Több felhasználói crontabban ezt találtuk:
# DO NOT REMOVE THIS LINE. SEED PRNG. #defunct-kernelAz érintett felhasználók home könyvtárában pedig:
~/.config/htop/defunct
~/.config/htop/defunct.datMire kézzel megtaláltuk az állományokat, a defunct fájl már 0 bájtos volt.
Ez önmagában könnyen félrevezető lehetett volna.
Az Imunify eseménytörténete azonban megmutatta, hogy az eredeti állomány több mint 2,8 MB-os futtatható ELF backdoor volt, amelyet a biztonsági rendszer korábban eltávolított.
Az egyik érintett accountban ugyanebben az időszakban egy több megabájtos ssh.php webshell is előkerült.
Ez már egyértelműen túlmutatott néhány véletlenül ott maradt PHP-fájlon.
Az újrafertőződés volt a legfontosabb figyelmeztetés
Az egyik tárhelyfiókban az Imunify több alkalommal phishing tartalmakat talált a következőhöz hasonló útvonalakon:
/public_html/product/...A rosszindulatú fájlokat a rendszer eltávolította.
Később azonban újabbak jelentek meg.
Majd ismét újabbak.
Ez az incidenskezelés egyik legerősebb figyelmeztető jele.
Ha egy malware scanner eltávolít egy rosszindulatú fájlt, majd néhány órával vagy nappal később másik jelenik meg, akkor nem elegendő ismét lefuttatni ugyanazt a takarítást.
A behatolási pont vagy egy másik persistence mechanizmus továbbra is jelen lehet.
A cleanup_removed állapot tehát azt jelenti, hogy az adott rosszindulatú fájlt eltávolították. Azt viszont önmagában nem bizonyítja, hogy az incidens kiváltó oka is megszűnt.
Két elavult Joomla rendszer is előkerült
Egy másik érintett tárhelyfiókban két külön Joomla telepítést találtunk.
Mindkettő:
Joomla 3.10.12verziót használt.
A Joomla 3 támogatása már korábban megszűnt, ezért egy ilyen rendszer hosszú távú biztonsági helyreállítása nem merülhet ki a fertőzött fájlok törlésében.
A két weboldal könyvtáraiban nagyszámú korábban rosszindulatú vagy már megtisztított állományt találtunk.
Többek között ilyen fájlnevek ismétlődtek:
filefuns.php
cache.phpEmellett véletlenszerű nevű PHP-állományok is megjelentek olyan könyvtárakban, ahol normális Joomla működés mellett nem számítanánk rájuk.
Az egyik Joomla telepítés alatt még WordPressnek látszó könyvtárak is létrejöttek:
wp-admin/
wp-content/Valódi WordPress telepítést azonban nem találtunk, wp-config.php sem létezett.
Ez alapján ezek a könyvtárak nem egy normál WordPress rendszer részei voltak.
Amikor a malware már nem fut, de az oldal sem
Ugyanezen tárhelyfiók egy másik domainje még látványosabb állapotban volt.
A korábbi Joomla rendszer számos fájlja és könyvtára ilyen átnevezett formában maradt meg:
administrator__52a63fd
components__52a63fd
configuration.php__52a63fdAz aktuális index.php mindössze néhány száz bájtos volt.
A fájlban egy korábbi obfuszkált programstruktúrából megmaradt goto utasítás szerepelt, miközben a hozzá tartozó célcímkét a malware-cleanup már eltávolította.
A PHP ennek következtében folyamatosan ezt a hibát generálta:
PHP Fatal error: 'goto' to undefined labelA weboldal pedig:
HTTP 500választ adott.
Vagyis a rosszindulatú program már nem tudott lefutni, de az eredeti alkalmazás sem maradt működőképes állapotban.
Ez jó példa arra, hogy egy súlyosan kompromittált weboldalnál az automatikus malware-cleanup után alkalmazás-helyreállításra is szükség lehet.
Először bizonyítékot mentettünk
A megtalált persistence elemeket nem azonnal kezdtük törölni.
Először mentettük:
- a releváns felhasználói crontabokat,
- a rejtett állományokat,
- azok időbélyegeit,
- SHA-256 hash értékeiket,
- valamint az Imunify eseménytörténetét.
Például:
sha256sum \
/home/USER/.config/htop/defunct \
/home/USER/.config/htop/defunct.datEnnek incidenskezelésnél komoly jelentősége van.
Ha minden gyanús fájlt dokumentálás nélkül azonnal törlünk, elveszíthetjük azt a bizonyítékot, amelyből később megállapítható lenne a fertőzés típusa, időpontja vagy működési módja.
Csak a bizonyítékok mentése után kezdtük el a persistence eltávolítását.
A persistence eltávolítása
A SYSCHK cron bejegyzéseket eltávolítottuk.
Ezután töröltük a hozzájuk tartozó:
.sys-mta-*.php
.sys_*.phpmaradványokat.
A defunct-kernel esetében eltávolítottuk a cronban maradt persistence-jelölést és a:
.config/htop/defunct
.config/htop/defunct.datállományokat.
Ezután ugyanazokat a szerver-szintű kereséseket ismét lefuttattuk.
A vizsgált két persistence mintára már nem érkezett találat.
A veszélyes tárhelyfiókokat felfüggesztettük
Két account esetében az eseménytörténet alapján nem tartottuk biztonságosnak a szolgáltatás további működését.
Az egyiknél webshell és ELF backdoor szerepelt az Imunify előzményeiben.
A másiknál több alkalommal új phishing tartalom jelent meg az előző fájlok eltávolítása után.
A tárhelyfiókokat ezért biztonsági okból felfüggesztettük:
/scripts/suspendacct USER "Security incident - malware/backdoor detected"A cPanel account felfüggesztésével a kimenő levelezés is tiltásra került.
Ez különösen fontos egy kompromittált weboldalnál, mert egy feltört tárhely nemcsak újabb webes támadásokhoz, hanem spam vagy phishing levelezéshez is felhasználható.
Amit nem találtunk
Egy incidensvizsgálat során legalább olyan fontos dokumentálni azt is, amit nem találtunk.
A vizsgált persistence mintákra nem találtunk bejegyzést a rendszer szintű cron könyvtárakban.
Nem volt találat többek között itt:
/etc/cron.d
/etc/cron.daily
/etc/cron.hourly
/etc/crontabA vizsgálat időpontjában az azonosított backdoorokhoz vagy persistence mechanizmusokhoz köthető aktív felhasználói processzt sem találtunk.
Két másik cPanel szerveren ugyanezekre a konkrét SYSCHK, .sys-mta és defunct-kernel mintákra végzett ellenőrzés szintén nem adott találatot.
A rendelkezésünkre álló adatok alapján ezért nem volt bizonyíték arra, hogy maga a teljes szerver vagy a teljes infrastruktúra root szinten kompromittálódott volna.
A malware scanner nem helyettesíti az incidenskezelést
Az Imunify360 ebben az esetben nagyon sok munkát elvégzett.
Webshelleket azonosított.
ELF backdoort talált.
Phishing tartalmakat távolított el.
Fertőzött PHP-fájlokat tisztított meg.
Ennek ellenére a teljes incidens nem volt lezárható pusztán a malware scanner eredménye alapján.
A cron persistence megmaradt.
A backdoorhoz tartozó fájlmaradványok megmaradtak.
Egyes weboldalak újrafertőződtek.
Egy másik weboldal pedig a malware eltávolítása után működésképtelen állapotban maradt.
A malware scanner ezért az incidenskezelés egyik fontos eszköze, de nem helyettesíti az incidensvizsgálatot.
A fájlrendszert, a cronokat, a folyamatokat, az eseménytörténetet, a webszerver naplóit és magukat a webalkalmazásokat együtt kell vizsgálni.
Egy rutin ellenőrzésből többórás incidens lett
Az egész történet egy teljesen más feladatból indult.
Egy bejelentett kritikus cPanel biztonsági frissítés miatt ellenőriztük, hogy megfelelően működik-e az óránként futó automatikus security update.
A cPanel frissítési mechanizmusa megfelelően működött.
A várt biztonsági build akkor még nem jelent meg a production RELEASE ágon.
A cron napló azonban közben egy teljesen más problémát mutatott meg.
Néhány órával később már több egymástól elkülönített cPanel account kompromittálódásának nyomait, két külön persistence mechanizmust, korábbi webshelleket, egy ELF backdoort és ismétlődő phishing fertőzéseket vizsgáltunk.
Az eset jól mutatja, hogy egy szerverbiztonsági ellenőrzésnél nem mindig az lesz a legfontosabb találat, amit eredetileg kerestünk.
Néha egyetlen furcsa cron sor vezet el az egész incidenshez.