Tavs WordPress vakar strādāja. Šodien tas arī strādā. Tikai šobrīd, kamēr tu lasi šo teikumu, kāds otrā pasaules malā sūta uz tavu serveri pieprasījumu, kas izpildās pirms tavs WordPress kods vispār sāk darboties.
21. oktobrī PHP izstrādātāji izlaida ārkārtas ielāpu. Nevis plānotu. Ārkārtas. Ap plkst. 14:00 pēc UTC (17:00 pēc Latvijas laika). Divām ievainojamībām, kuras ieguvušas nosaukumu php2shell.
Kas ir php2shell un kāpēc tā ir krīze
Tās ir divas kritiskas attālinātas koda izpildes ievainojamības pašā PHP interpretatorā: CVE-2026-109618 un CVE-2026-109619, abas ar CVSS v4.0 novērtējumu 9.2 no 10. Kļūda nav WordPress, Joomla vai kādā spraudnī — tā ir valodā, kurā tie visi darbojas. Tāpēc apdraudēta ir jebkura vietne, kas darbojas ar neielāpītu PHP versiju.
Labotās versijas ir PHP 8.5.12, 8.4.27, 8.3.36 un 8.2.35. PHP komanda ir nepārprotama: vienīgais pilnīgais risinājums ir atjaunināšana. Viss pārējais šajā rakstā ir tikai pagaidu tilts.
Kāpēc krīze ir globāla:
- PHP izmanto 69,3% no visām vietnēm, kuru servera puses valoda ir zināma (W3Techs dati). Ne 7%. Gandrīz 70%.
- Pētnieku aplēses par internetā redzamiem PHP serveriem svārstās no 1,3 līdz vairāk nekā 2 miljoniem. CybelAngel saskaitīja 2,24 miljonus, no kuriem 59% darbojas ar versijām, kurām PHP projekts labojumu neizlaidīs (8.1 un vecākas). Daļai no tām labojumu piedāvā Linux distribūcijas, bet ne visām.
- PHP 8.2 atbalsts beidzas jau 2026. gada 31. decembrī — tas ir labs brīdis plānot pāreju uz jaunāku versiju.
Un pats bīstamākais: uzbrukums notiek pirms tavas lietotnes koda. PHP pats augstāko risku piešķir Apache ar mod_php režīmam, jo tur demonstrēts uzbrukums ar neautentificētu pieprasījumu, kas nostrādā, pirms tiek palaists jebkāds lietotnes kods.
Izmantošana jau notiek — ne rīt, bet vakar
Šī nav teorija.
- Amazon MadPot honeypot tīkls fiksēja pirmo php2shell izmantošanas mēģinājumu jau 17. oktobrī — četras dienas pirms publiskās izpaušanas. Tas bija viens mēģinājums pret honeypot, un Amazon norāda, ka nav skaidrs, vai tas būtu izdevies pret īstu sistēmu. Tomēr tieši 17. oktobris ir datums, no kura vērts pārbaudīt savus žurnālus.
- Cloudflare ziņoja par pirmajiem uzbrukumiem 21. oktobrī plkst. 07:43 pēc UTC — vairāk nekā sešas stundas pirms ielāpa.
- watchTowr reproducēja abas ievainojamības un savā honeypot tīklā novēro izmantošanas mēģinājumus pret abām.
- Patchstack jau 21. oktobra rītā ziņoja par vairākiem apstiprinātiem aktīvas izmantošanas incidentiem.
- CISA (ASV Kiberdrošības un infrastruktūras drošības aģentūra) mudina nekavējoties atjaunināt PHP. Ja to uzreiz izdarīt nevar vai ja tiek lietota PHP 8.1 vai vecāka versija, CISA iesaka PHP sistēmas atslēgt no tīkla, līdz tās ir atjauninātas. Līdzīgi iesaka arī CERT-EU: izolēt no interneta pieejamās PHP lietotnes, līdz labojums ir uzlikts un pārbaudīts.
Godīgi jāpiebilst: ne visi avoti 21. oktobrī redzēja vienādu ainu. Nīderlandes NCSC tobrīd ziņoja, ka aktīvas izmantošanas pazīmju tai vēl nav, taču sagaida masveida izmantošanu tuvākajā laikā. Ielāps un atklātie tehniskie apraksti šo laiku tikai saīsina.
Tehniski vienkārši: kur ir caurums
Abas kļūdas ir PHP iekšējā pieprasījumu apstrādē:
- CVE-2026-109618 — koda izpilde caur atmiņas izsīkuma bojājumu. Ja PHP beidzas atmiņa brīdī, kad pieprasījuma iekšējie dati ir sagatavoti tikai daļēji, sekojošā tīrīšana šos datus apstrādā kā derīgus. Rezultāts ir atmiņas bojājums, ko var pārvērst koda izpildē.
- CVE-2026-109619 — koda izpilde caur novecojušu iekšējo stāvokli. Pieprasījumam piederošs iekšējais stāvoklis var saglabāties arī pēc tam, kad tā atmiņa ir atbrīvota. Nākamais pieprasījums, ko apstrādā tas pats PHP darba process (worker), var šo novecojušo stāvokli izmantot.
Publiski ziņojumi norāda, ka abas ievainojamības var izraisīt ar vienkāršu POST pieprasījumu. Pirmajos noplūdušajos aprakstos abas kļūdas tika sasaistītas ar sesiju augšupielādes progresa funkciju (session.upload_progress). Oficiālais PHP ziņojums to precizēja: tas ir tikai viens apstiprināts CVE-2026-109619 izmantošanas ceļš, nevis pašas kļūdas būtība. Tāpēc šīs funkcijas izslēgšana vien neaizsargā.
Ko darīt tagad: 2 fāzes (Linux serveris ar Debian vai Ubuntu)
1. fāze: inventarizācija 5 minūtēs
Svarīgi: komanda php -v parāda komandrindas PHP versiju, kas var atšķirties no tās, ar kuru strādā tava vietne. Uz Ubuntu ielāpītā pakotne turklāt saglabā veco versijas numuru (piemēram, 8.1.2). Tāpēc skaties pakotņu versijas.
# 1. Kuras PHP pakotnes ir uzstādītas un kādās versijās
dpkg -l | awk '/^ii +(php[0-9.]+-(fpm|cli|cgi)|libapache2-mod-php[0-9.]*) /{print $2, $3}'
# 2. Kas reāli apkalpo vietni: PHP-FPM, Apache ar mod_php vai abi
ps -eo pid,user,cmd | grep -E "php-fpm|php-cgi|apache2" | grep -v grep
systemctl list-units --type=service | grep -E "php|apache2|nginx"
# 3. Upload progress iestatījums TĪMEKĻA PHP (nevis komandrindas php.ini)
for f in /usr/sbin/php-fpm*; do echo "$f: $($f -i 2>/dev/null | grep -m1 '^session.upload_progress.enabled')"; done
grep -RHs "^session.upload_progress.enabled" /etc/php/*/apache2/ || echo "mod_php: nav iestatīts (noklusējumā ieslēgts)"
2. fāze: ielāps un pilns restarts
sudo apt-get update
# Atjaunina TIKAI jau uzstādītās PHP pakotnes, arī mod_php (libapache2-mod-php*)
sudo apt-get install --only-upgrade $(dpkg-query -W -f='${db:Status-Abbrev} ${binary:Package}\n' 'php*' 'libapache2-mod-php*' 2>/dev/null | awk '$1=="ii"{print $2}')
# Pārbaudi pakotņu versijas (salīdzini ar tabulu zemāk)
dpkg -l | awk '/^ii +(php[0-9.]+-(fpm|cli)|libapache2-mod-php[0-9.]*) /{print $2, $3}'
# Pilns restarts: restart = stop + start (reload nepietiek)
sudo systemctl restart 'php*-fpm'
# Tikai, ja lieto Apache (mod_php vai Apache + PHP-FPM):
sudo systemctl restart apache2
# Vai kāds process vēl izmanto veco PHP (abām komandām jāatgriež tukšums)
for p in $(pgrep -f 'php-fpm|apache2'); do sudo readlink /proc/$p/exe; done | grep '(deleted)'
sudo grep -l 'libphp.*(deleted)' /proc/[0-9]*/maps 2>/dev/null
Pirmās versijas ar labojumu populārākajās distribūcijās:
| Distribūcija | PHP | Pakotnes versija ar labojumu |
|---|---|---|
| Debian 13 (trixie) | 8.4 | 8.4.27-1~deb13u1 |
| Debian 12 (bookworm) | 8.2 | 8.2.35-1~deb12u1 |
| Ubuntu 24.04 LTS | 8.3 | 8.3.6-0ubuntu0.24.04.13 |
| Ubuntu 22.04 LTS | 8.1 | 8.1.2-1ubuntu2.28 |
Ja lieto ondrej/sury repozitoriju, tur versijas atbilst oficiālajām: 8.2.35, 8.3.36, 8.4.27, 8.5.12. Neatkarīgi no versijas numura labojumu var pārbaudīt pakotņu izmaiņu žurnālā — ja komanda atgriež failu nosaukumus, labojums ir uzlikts:
zgrep -lE "CVE-2026-10961[89]" /usr/share/doc/php*/changelog.Debian.gz
Docker. Oficiālie php un wordpress attēli jau ir pārbūvēti ar labotajām versijām. Taču strādājošs konteiners pats neatjauninās — tas jāpārbūvē un jāpalaiž no jauna:
docker compose pull # vai: docker compose build --pull, ja attēls tiek būvēts no Dockerfile
docker compose up -d
docker exec <konteinera_nosaukums> php -v
Ja tava vietne darbojas uz Synology DSM
Synology DSM ir izplatīta izvēle mazo uzņēmumu vietnēm, un šeit ir sava specifika. Synology PHP pakotnes (Web Station) labojumus parasti saņem ar kavēšanos, tāpēc vietnes, kas darbojas caur Web Station, paliek ievainojamas, līdz Package Center parādās PHP 8.2.35, 8.3.36 vai 8.4.27.
- Pārbaudi versiju: Package Center → PHP 8.x. Ja versija ir zemāka par labotajām, uzskati vietni par ievainojamu.
- Pagaidu solis: Web Station → Script Language Settings → savs PHP profils → Edit → cilne Core →
session.upload_progress.enabled= 0. Tas aizver tikai vienu ceļu, tāpēc tas ir tilts, nevis risinājums. - Drošāks ceļš: pārcelt vietni uz Container Manager ar oficiālo
wordpressattēlu, kurā jau ir labotais PHP, un publicēt to caur DSM Reverse Proxy. - Neaizmirsti par Synology pakotnēm, kas lieto PHP. Piemēram, Synology Calendar ir atkarīgs no PHP 8.2 pakotnes, un Synology MailPlus tīmekļa klients — no Calendar. Kamēr PHP nav atjaunināts, drošākais ir šīs pakotnes apturēt. Kuras pakotnes ir atkarīgas no PHP, var redzēt ar komandu:
grep -H '^install_dep_packages=.*PHP' /var/packages/*/INFO
Ja ielāpu uzreiz uzlikt nevari — pagaidu tilts
PHP saka tieši: neviena konfigurācijas izmaiņa ievainojamības pilnībā nenovērš. Viss zemāk ir tilts, nevis risinājums. Izmanto to tikai, lai iegūtu laiku līdz atjaunināšanai.
1. Oficiālie PHP pagaidu iestatījumi — tikai servera konfigurācijā. PHP iesaka abus iestatījumus norādīt tā, lai lietotne tos nevarētu pārrakstīt. ini_set() un .user.ini te nepalīdz — tie iedarbojas par vēlu.
; PHP-FPM: /etc/php/8.x/fpm/pool.d/www.conf (katrā pool failā)
php_admin_flag[session.upload_progress.enabled] = off ; CVE-2026-109619 (viens ceļš)
php_admin_value[memory_limit] = -1 ; CVE-2026-109618
; tikai PHP 8.5:
php_admin_flag[fatal_error_backtraces] = off
Apache ar mod_php — divi faili. Pirmais ir PHP iestatījumu fails:
; /etc/php/8.x/apache2/conf.d/99-php2shell.ini
session.upload_progress.enabled = 0
memory_limit = -1
Otrais ir Apache konfigurācija, lai lietotne nevarētu memory_limit pārrakstīt:
# /etc/apache2/conf-available/php2shell.conf
php_admin_value memory_limit -1
Aktivizē to ar sudo a2enconf php2shell.
Pēc izmaiņām — pilns restarts, nevis reload: sudo systemctl restart 'php*-fpm' vai sudo systemctl restart apache2.
2. Ierobežo atmiņu no ārpuses. Ar memory_limit = -1 viens pieprasījums var aizņemt visu servera atmiņu. Tāpēc atmiņu ierobežo ar systemd. PHP to sauc par pieejamības robežu, nevis pilnīgu aizsardzību.
Atver papildu iestatījumu failu (mod_php gadījumā apache2 vietā):
sudo systemctl edit php8.x-fpm
Atvērtajā failā ieraksti šīs rindas. Vērtības pielāgo sava servera RAM apjomam, piemēram, 60–70% no kopējās atmiņas:
[Service]
MemoryHigh=3G
MemoryMax=4G
Saglabā un restartē: sudo systemctl restart php8.x-fpm.
3. Ja lieto PHP-FPM — nobeidz darba procesu pēc katra pieprasījuma. Šis nav PHP oficiālais ieteikums, bet to iesaka administratori, jo CVE-2026-109619 izmanto stāvokli, kas paliek tajā pašā procesā starp pieprasījumiem. Cena ir ievērojami lielāka CPU slodze.
; /etc/php/8.x/fpm/pool.d/www.conf
pm.max_requests = 1
4. Ja tava vietne failus nepieņem — bloķē multipart pieprasījumus nginx līmenī. Uzmanību: WordPress administrācijas panelis attēlus, spraudņus un tēmas augšupielādē tieši ar multipart pieprasījumiem, tāpat formas ar pielikumiem. Pēc šī noteikuma tās pārstās darboties. Tas der tikai vietnēm, kurās augšupielādes tiešām nav vajadzīgas.
if ($http_content_type ~* "multipart/form-data") {
return 403;
}
Pārbaude: curl -F a=b https://tavs.lv/ — jāatbild 403.
5. Ja faili ir vajadzīgi — bloķē upload progress lauku ar WAF. Šis aizver tikai vienu CVE-2026-109619 ceļu un atpazīst tikai noklusējuma lauka nosaukumu.
ModSecurity (nepieciešams SecRequestBodyAccess On):
SecRule REQUEST_HEADERS:Content-Type "@rx (?i)multipart/form-data" \
"id:1096181,phase:2,deny,status:403,chain,msg:'php2shell probe blocked'"
SecRule ARGS_NAMES "@rx (?i)PHP_SESSION_UPLOAD_PROGRESS"
Cloudflare. Ja vietne ir aiz Cloudflare, aizsardzība jau ir ieslēgta: Cloudflare 21. oktobrī plkst. 03:02 pēc UTC automātiski iedarbināja pārvaldītos WAF noteikumus visiem plāniem ar WAF, arī bezmaksas plānam. Pašam noteikums nav jāraksta. Tas gan neaizstāj ielāpu.
Ko nedarīt: mīti, kas caurumu neaizver
Apkopes režīma spraudnis, pieteikšanās lapa, CSRF aizsardzība, WordPress drošības spraudņi — tas viss tiek apiets, jo ievainojamais kods izpildās PHP iekšienē, pirms tava lietotne vispār ir sākusi darbu. Tāpat nepalīdz ini_set() un .user.ini — tie iedarbojas par vēlu.
Spoku procesu lamatas: kāpēc tu domā, ka esi ielāpījis, bet neesi
Tu uzliec atjauninājumu, redzi jauno versiju, bet serveris joprojām ir ievainojams. Kāpēc? Jo vecie PHP-FPM vai Apache procesi turpina darboties ar izdzēstajām, neielāpītajām bibliotēkām atmiņā. Pārbaudi:
for p in $(pgrep -f 'php-fpm|apache2'); do sudo readlink /proc/$p/exe; done | grep '(deleted)'
sudo grep -l 'libphp.*(deleted)' /proc/[0-9]*/maps 2>/dev/null
Ja kāda no komandām kaut ko parāda — piemēram, /usr/sbin/php-fpm8.2 (deleted) — tu joprojām esi ievainojams. Risinājums ir pilns restarts (systemctl restart), nevis reload.
Vai uzbrucējs jau nav bijis iekšā
Ielāps aizver durvis, bet neizmet to, kas jau ir ienācis. Tā kā pirmais mēģinājums fiksēts 17. oktobrī, pārbaudi žurnālus un failus no šī datuma:
# POST pieprasījumi, kas beigušies ar 500 kļūdu
sudo zgrep -hE '"POST [^"]*" 500 ' /var/log/nginx/access.log* /var/log/apache2/access.log* 2>/dev/null | tail -20
# Atmiņas izsīkums un nogalināti PHP procesi
sudo zgrep -hiE "Allowed memory size|exited on signal|SIGSEGV" /var/log/php*-fpm.log* /var/log/apache2/error.log* 2>/dev/null | tail -20
# Procesi, kas darbojas kā www-data, bet nav tīmekļa serveris vai PHP (jābūt tukšam)
ps -u www-data -o pid,ppid,lstart,cmd | grep -vE "php-fpm|apache2|nginx|CMD"
# PHP faili augšupielāžu mapē (WordPress tos tur neliek)
sudo find /var/www -path "*/wp-content/uploads/*" -name "*.php*" -ls
Atradums vēl nenozīmē, ka tevi ir uzlauzuši, bet tas ir iemesls pārbaudīt rūpīgāk vai lūgt palīdzību.
Kur šajā stāstā ir tavi dati
Godīgi: rezerves kopija php2shell uzbrukumu neapturēs. To dara tikai ielāps. Bet php2shell nav tikai stāsts par PHP. Tas ir stāsts par to, kas notiek desmit minūtes pēc veiksmīgas koda izpildes.
wp-config.phpir pirmais upuris. Uzbrucējs ar tīmekļa servera tiesībām nolasa datubāzes paroli un API atslēgas. No turienes — visas datubāzes kopija. Ja tava vienīgā rezerves kopija atrodas tajā pašā serverī, tā var aiziet kopā ar uzbrucēju vai tikt izdzēsta.- Tīmekļa čaula (web shell) paliek. Pat ja ielāpu uzliec divas stundas vēlāk, serverī jau var gaidīt, piemēram,
/wp-content/uploads/.hidden.php. Ja atjauno no kopijas, kas veidota pēc ielaušanās, tu atjauno arī čaulu. - Atmiņas satura noplūde. Kļūdas PHP atmiņas apstrādē var atklāt datus no citiem pieprasījumiem, kurus apstrādājis tas pats PHP darba process — paroles, sesiju atslēgas, tokenus.
Tāpēc 3-2-1 princips šoreiz nozīmē:
- Viena kopija ir ārpus servera un nav sasniedzama ar tā paša tīmekļa servera lietotāja tiesībām.
- Viena kopija ir nemaināma (immutable) — to nevar pārrakstīt vai izdzēst pat tad, ja serveris ir kompromitēts.
- Ir zināma tīra kopija — veidota pirms 17. oktobra, lai atjaunojot neatgrieztu arī uzbrucēja atstāto.
- Atjaunošana ir pārbaudīta uz tukša servera, nevis uz tā paša, iespējams, inficētā.
Ja šis tev šķiet pazīstami, tas nav nejauši: tieši tādu pašu mācību deva wp2shell WordPress ievainojamība vasarā, un par to, kāpēc “atjaunini laikus” vien vairs nav plāns, rakstījām augusta ievainojamību pārskatā.
Ko darīt šovakar: 15 minūšu saraksts
- Inventarizē PHP pakotņu versijas visos serveros, arī Docker konteineros un Synology NAS.
- Uzliec labojumu (8.5.12 / 8.4.27 / 8.3.36 / 8.2.35 vai distribūcijas pakotni no tabulas augstāk), veic pilnu restartu un pārbaudi, vai nav palikuši procesi ar veco PHP.
- Ja uzreiz nevari — iestati
memory_limit = -1ar ārēju atmiņas ierobežojumu unsession.upload_progress.enabled = 0servera konfigurācijā. Ja vietne ir svarīga un ielāpu tuvākajās stundās uzlikt nevari, apsver to uz laiku atslēgt, kā iesaka CISA un CERT-EU. - Pārbaudi žurnālus no 17. oktobra: POST pieprasījumi ar 500 kļūdu, atmiņas izsīkums, nezināmi procesi, kas darbojas kā www-data, PHP faili augšupielāžu mapē.
- Atjauno vienu kopiju no ārējās glabātuves testa vidē. Vai tā tiešām strādā bez piekļuves oriģinālajam serverim?
Vēlies, lai koda izpilde tavā serverī nebeidzas ar tukšu datubāzi? Piesakies php2shell pārbaudei (50 EUR + PVN): 30 minūšu zvanā novērtēsim, vai tava vietne ir salāpīta un vai tās rezerves kopija izdzīvotu uzbrukumu. Rakstisku atskaiti saņemsi tajā pašā dienā.”
Avoti
- PHP: paziņojums par kritisko drošības laidienu
- PHP drošības ziņojums GHSA-w8hw-w9fx-j79w (CVE-2026-109618)
- PHP drošības ziņojums GHSA-6wmf-4rv5-p3rp (CVE-2026-109619)
- CISA: Critical Vulnerabilities in PHP Require Immediate Patching
- CERT-EU drošības ziņojums 2026-018
- NCSC-NL: operatīvā informācija par php2shell
- Tenable: php2shell biežāk uzdotie jautājumi
- Cloudflare: aizsardzība pret php2shell
- CybelAngel: ko zinām par php2shell
- Labotās pakotņu versijas Ubuntu, Debian un RHEL
- ma.ttias.be: pagaidu aizsardzības soļi



