Trumpai: paslėpta cron užduotis yra viena dažniausių užpakalinių durų Linux serveriuose: ji reguliariai atsisiunčia kenkėjišką kodą arba iš naujo paleidžia procesus, net ir po PHP atnaujinimo. Patikrinkite visas suplanuotų užduočių vietas, ne tik crontab -l: visų naudotojų crontab, /etc/crontab, /etc/cron.d, cron aplankus, systemd laikmačius ir at užduotis. Radinius išsaugokite prieš juos pašalindami.
Kodėl cron užduotys kaip užpakalinės durys tokios populiarios
Po sėkmingo įsilaužimo užpuolikas turi problemą: jo prieiga trapi. Atnaujinimas uždaro spragą, administratorius ištrina webshell, paleidimas iš naujo nutraukia procesą. Cron užduotis šią problemą išsprendžia. Ji paleidžia komandas nustatytu laiku, niekam nesikišant, ir taip atkuria prarastas prieigas.
PHP2Shell atveju patvirtintų kompromitavimo indikatorių (Indicators of Compromise) nėra. Tačiau pagal mūsų turimus pranešimus naujos cron užduotys priklauso bendriesiems įspėjamiesiems ženklams po įsilaužimų per žiniatinklio programas. Kas jau ieškojo webshell, turėtų kartu patikrinti ir suplanuotas užduotis. Kitus paruošiamojo darbo po incidento žingsnius išvardija Kontrolinis sąrašas po įsilaužimo.
Kur gali slėptis suplanuotos užduotys
Linux turi kelis suplanuotų užduočių mechanizmus. Daug patikrų nepavyksta, nes peržiūrimas tik vienas iš jų.
| Vieta | Debian/Ubuntu | RHEL šeima | Kas gali rašyti |
|---|---|---|---|
| Naudotojo crontab | /var/spool/cron/crontabs/ |
/var/spool/cron/ |
atitinkamas naudotojas |
| Sisteminis crontab | /etc/crontab |
/etc/crontab |
root |
| Pavieniai failai | /etc/cron.d/ |
/etc/cron.d/ |
root |
| Periodiniai aplankai | /etc/cron.hourly iki /etc/cron.monthly |
taip pat | root |
| systemd laikmačiai | /etc/systemd/system/, naudotojo unit failai |
taip pat | root, iš dalies naudotojai |
| at užduotys | atd eilė |
taip pat | naudotojas, jei leidžiama |
Svarbu žiniatinklio serveriams: žiniatinklio serverio naudotojas paprastai gali susikurti savo crontab be root teisių. Užpuolikui su www-data teisėmis tam nereikia kito pažeidžiamumo. Įrašai /etc/cron.d ar systemd unit, priešingai, rodo, kad jis įgijo root teises.
Hostingo valdymo skydeliai, tokie kaip Plesk ar cPanel, suplanuotoms užduotims siūlo savo sąsają. Už jos paprastai taip pat yra atitinkamų sistemos naudotojų crontab. Kas žiūri tik sąsajoje, pastebi ne kiekvieną įrašą, sukurtą tiesiai serveryje. Abejojant patikrinkite abu.
Kaip visiškai patikrinti visas vietas
Toliau pateiktos komandos tik skaito. Vykdykite jas kaip root ir išvestis išsaugokite su data.
# Išvesti visų naudotojų crontab
for u in $(cut -d: -f1 /etc/passwd); do
out=$(crontab -l -u "$u" 2>/dev/null) && printf '### %s\n%s\n' "$u" "$out"
done
# Sisteminiai įrašai ir pakeitimo laikai
cat /etc/crontab
ls -la --time-style=full-iso /etc/cron.d /etc/cron.hourly /etc/cron.daily /etc/cron.weekly /etc/cron.monthly
# systemd laikmačiai ir at užduotys
systemctl list-timers --all
atq 2>/dev/null
# Ieškoti tipinių šablonų visuose cron failuose
grep -rnE "curl|wget|base64|/tmp/|/dev/shm|\| *(ba)?sh" /etc/crontab /etc/cron.* /var/spool/cron 2>/dev/null
Du triukai verti ypatingo dėmesio. Kai kurie įrašai komandas slepia už daugybės tarpų, todėl redaktoriuje jos išeina už dešiniojo ekrano krašto. Kiti naudoja valdymo simbolius, kurie rodant perrašo tekstą. Su cat -A tokie simboliai tampa matomi:
cat -A /var/spool/cron/crontabs/www-data 2>/dev/null | less
Antras žvilgsnis yra cron tarnybos žurnalai. Daugelyje sistemų cron kiekvieną vykdymą pažymi su naudotoju ir komanda. Taip pamatysite ir įrašus, kuriuos užpuolikas jau pašalino, ir atpažinsite, nuo kada veikia įtartina komanda:
# Žiniatinklio serverio naudotojo vykdytos cron komandos (Debian/Ubuntu arba systemd žurnalas)
grep -h "CRON" /var/log/syslog* 2>/dev/null | grep -E "\((www-data|apache|nginx)\) CMD"
journalctl -u cron -u crond --since "2026-10-17" --no-pager 2>/dev/null | grep CMD | head -100
Kaip atpažinti cron užpakalines duris
- Atsisiuntimas iš interneto: atsisiuntimas, kurio rezultatas tiesiai perduodamas apvalkalui.
- Užkoduotas turinys: ilgos simbolių eilutės, kurios dekoduojamos tik vykdymo metu.
- Neįprasti keliai: programos
/tmp,/dev/shm, paslėptuose aplankuose ar įkėlimų kataloguose. - Netinkamas naudotojas: užduotys po žiniatinklio serverio naudotoju, nors programai jų nereikia.
- Krintantis į akis ritmas: vykdymas kas minutę arba kiekvieną kartą paleidus iš naujo per
@reboot. - Netinkamos laiko žymos: failas pakeistas laikotarpiu, kai prie serverio niekas nedirbo, pavyzdžiui, po spalio 17 d.
Nepamirškite: ir programos turi savo tvarkaraščius. WordPress, pavyzdžiui, suplanuotas užduotis valdo duomenų bazėje. Kaip ten tikrinti, aprašo Užpakalinių durų WordPress radimas.
Cron užduotis retai būna viena. Kas sukūrė suplanuotą užduotį, dažnai yra palikęs ir SSH raktų arba paslėpęs failus. Papildomai patikrinkite raktus, kaip aprašyta straipsnyje Nežinomų SSH raktų radimas.
Radinį išsaugoti, suprasti, tada pašalinti
Kenkėjiška cron užduotis yra vertingas įrodymas. Ji rodo atsisiuntimo adresą, sukūrimo laiką ir dažnai naudotoją, per kurį užpuolikas patekęs. Failą prieš pašalindami išsaugokite su kontroline suma ir laiko žymomis. Laiko žyma vėliau padeda atkurti eigą; kaip tai daroma, parodo Incidento laiko juostos sudarymas. Ir galimam pranešimui duomenų apsaugos priežiūros institucijai, ir draudikui radinys yra svarbus įrodymas, nuo kada užpuolikas turėjo prieigą.
Vien pašalinti nepakanka. Jei dar veikia procesas, kuris įrašą perrašo iš naujo, po kitos minutės jis vėl atsiranda. O kol pradinė spraga atvira, užpuolikas bet kada gali pradėti iš naujo. Todėl eilė tokia: išsaugoti, uždaryti priežastį, pašalinti visas dalis, pakeisti prieigas, stebėti.
Cron užduotis apsaugoti prevenciškai
Kad cron užpakalinės durys išvis neatsirastų arba būtų greitai pastebėtos, padeda trys priemonės. Pirma, galima nustatyti, kurie naudotojai apskritai gali kurti crontab. Jei yra failas /etc/cron.allow, crontab gali naudoti tik ten nurodyti naudotojai. Jei jūsų programai cron užduoties po žiniatinklio serverio naudotoju nereikia, šis naudotojas į sąrašą nepriklauso. Iš anksto patikrinkite, kokių užduočių programai iš tikrųjų reikia, ir sąmoningai sukurkite jas po savo naudotoju.
Antra, verta stebėti failus. Vientisumo patikros įrankis praneša, kai pasikeičia failas cron kataloguose ar po /var/spool/cron. Trečia, suplanuotos užduotys priklauso serverio dokumentacijai: kas žino, kokie įrašai turi būti, svetimą atpažįsta iškart.
Kaip PHP SOS padeda konkrečiai?
- Patikrinti visiškai: nagrinėjame visus suplanuotų užduočių mechanizmus, taip pat systemd laikmačius, at užduotis ir programų tvarkaraščius.
- Įvertinti radinius: įtartinus įrašus analizuojame jų nevykdydami ir išvedame tolesnius pėdsakus.
- Švariai išvalyti: su kenkėjiškos programinės įrangos šalinimu pašaliname visas dalis ir uždarome priežastį.
- Atpažinti sugrįžimą: įrengiame stebėseną, kuri praneša apie naujas ar pakeistas suplanuotas užduotis.
Dažni klausimai
Kodėl užpuolikai naudoja cron užduotis?
Cron užduotis reguliariai ir be papildomų veiksmų paleidžia komandas. Užpuolikai per ją atsisiunčia kenkėjišką kodą, iš naujo sukuria ištrintus failus ar paleidžia procesus. Taip jų prieiga išgyvena atnaujinimą ir dažnai paviršutinišką išvalymą.
Ar patikrai pakanka crontab -l?
Ne. crontab -l rodo tik dabartinio naudotojo crontab. Suplanuotos užduotys yra ir kitų naudotojų crontab, /etc/crontab, /etc/cron.d, cron.daily aplankuose, systemd laikmačiuose ir at užduotyse.
Kaip atpažinti kenkėjišką cron užduotį?
Tipiška: atsisiuntimai iš interneto su tiesioginiu vykdymu, komandos su užkoduotomis simbolių eilutėmis, programos laikinuosiuose aplankuose, užduotys po žiniatinklio serverio naudotoju ir įrašai, veikiantys kas minutę. Vienas požymis yra užuomina, keli kartu rimtas įtarimas.
Ar įtartinas cron užduotis galiu tiesiog ištrinti?
Pirmiausia išsaugoti, tada pašalinti. Įrašas dažnai išduoda kilmę, atsisiuntimo adresą ir kitas dalis. Neišsiaiškinus, kaip jis atsirado, užpuolikas jį dažnai sukuria iš naujo.