Īsi sakot: Tīmekļa servera lietotājam, ar kuru darbojas PHP, pēc minimālo tiesību principa (Least Privilege) jālasa tikai tas, kas vietnei vajadzīgs, un jāraksta tikai tur, kur tā glabā datus. Tam nav pieteikšanās shell, sudo tiesību, savu cron uzdevumu un SSH atslēgu, un tā datubāzes kontam drīkst tikai lasīt un mainīt datus. systemd opcijas, piemēram, ProtectSystem un PrivateTmp, PHP-FPM papildus ierobežo.
Jautājums pēc ielaušanās: ko šis process drīkst?
PHP2Shell gadījumā runa ir par ļaunprātīga koda izpildi no attāluma bez pieteikšanās. Ja tā izdodas, kods nedarbojas tukšumā, bet kā konkrēts lietotājs: PHP procesa lietotājs. Visu, ko šis lietotājs drīkst, no šī brīža drīkst arī uzbrucējs.
Daudzos serveros tas ir pārsteidzoši daudz. Lietotājam pieder visa programmas koda daļa, tam ir shell, tas var izveidot savus cron uzdevumus, un lietojumprogrammas datubāzes kontam ir visas tiesības uz visām datubāzēm. Uzbrucējam tā ir ideāla sākumpozīcija, lai nostiprinātos uz ilgu laiku.
Kā pareizi piešķirt failus un mapes, apraksta ceļvedis Failu tiesības tīmekļa serverī. Šis raksts aplūko pašu kontu: pieteikšanos, īpašās tiesības, ieplānotos uzdevumus, datubāzi un robežas, ko velk systemd.
Inventarizācija: kas ir tīmekļa servera lietotājs?
Vispirms noskaidrojiet, kādi lietotāji vispār ir iesaistīti. Ar PHP-FPM katrs pūls ar user un group nosaka, kā lietotāja vārdā darbojas tā darbprocesi. Ar mod_php PHP darbojas kā Apache lietotājs. Kā PHP-FPM sadarbojas galvenais process un darbprocesi, skaidro raksts PHP-FPM skaidrojums: procesu pārvaldnieks, pūli un darbprocesi. Šīs komandas tikai lasa:
# Ar kuriem lietotājiem darbojas tīmekļa serveris un PHP?
ps -eo user,group,cmd | grep -E "[p]hp-fpm|[n]ginx|[a]pache2|[h]ttpd" | sort | uniq -c
# Konta dati: mājas direktorija un shell (pielāgot lietotāju)
getent passwd www-data
# Vai lietotājam ir sudo tiesības?
sudo -l -U www-data
# Savi cron uzdevumi?
sudo crontab -l -u www-data
# SSH atslēgas mājas direktorijā (Debian/Ubuntu tā ir /var/www)
sudo ls -la /var/www/.ssh 2>/dev/null
Pierakstiet rezultātus katram pūla lietotājam. Ja visas vietnes darbojas ar vienu un to pašu lietotāju, tas ir pirmais punkts sarakstā; kā to nodalīt, apraksta PHP-FPM pūlu izolēšana katrai vietnei.
Tīmekļa servera lietotāja tiesības: ko konts nevajag
Turpmākais pārskats parāda, kas tīmekļa servera lietotājam parasti nav vajadzīgs un kā to atņemt.
| Tiesības | Kāpēc bīstami | Ieteikums |
|---|---|---|
| Pieteikšanās shell | iespējama pieteikšanās un interaktīva lietošana | shell /usr/sbin/nologin |
| sudo ieraksti | ceļš uz root tiesībām | nekādu ierakstu, arī atsevišķām komandām ne |
| sava crontab | pastāvīga slēpta piekļuve, kas pārdzīvo katru pārstartēšanu | nekādas, ierobežot ar /etc/cron.allow |
| SSH atslēgas | pieteikšanās no ārpuses | nekādu authorized_keys |
| programmas koda īpašumtiesības | kodu var mainīt | īpašnieks ir deploy lietotājs |
| rakstīšanas tiesības ārpus datu mapēm | ļaunprātīga koda novietošana | tikai uploads, kešatmiņa, temp |
| pilnas datubāzes tiesības | citu lietojumprogrammu datubāzes, failu piekļuve caur datubāzi | tikai sava datubāze, tikai datu tiesības |
Shell iestata ar usermod -s /usr/sbin/nologin www-data. Attiecībā uz cron: ja pastāv /etc/cron.allow, savus cron uzdevumus drīkst izveidot tikai tur minētie lietotāji. Jauni cron uzdevumi vai nezināmas SSH atslēgas ir tipiska pazīme, ka kāds ir nostiprinājies. Īpaši skaidru brīdinājuma signālu apraksta raksts Brīdinājuma signāls: tīmekļa serveris startē shell.
Datubāze: ierobežot tiesības līdz nepieciešamajam
Vietnes datubāzes konts faktiski ir otrs tīmekļa servera lietotājs. Tā piekļuves dati atrodas lietojumprogrammas konfigurācijas failā, un ievadīts kods tos var nolasīt. Tāpēc tam jādrīkst tikai tas, kas lietojumprogrammai darbībā vajadzīgs.
-- Piemērs MySQL/MariaDB: savs konts katrai vietnei, tikai datu tiesības
CREATE USER 'seite1'@'localhost' IDENTIFIED BY 'hier-ein-langes-Zufallspasswort';
GRANT SELECT, INSERT, UPDATE, DELETE ON seite1.* TO 'seite1'@'localhost';
-- Pārbaudīt tiesības
SHOW GRANTS FOR 'seite1'@'localhost';
Tādas tiesības kā FILE, SUPER vai GRANT OPTION un piekļuve *.* lietojumprogrammas kontam nav vajadzīgas. Daudzām CMS atjauninājumiem papildus vajag CREATE, ALTER, INDEX un DROP. Tīrāk ir atsevišķs konts atjauninājumiem un migrācijām, ko izmanto tikai apkopes laikā. Prasības pārbaudiet ražotāja dokumentācijā.
PHP-FPM papildus ierobežot ar systemd
systemd var ierobežot pakalpojuma skatu uz sistēmu. PHP-FPM īpaši noder dažas opcijas no systemd dokumentācijas. Tās iedarbojas arī uz galveno procesu, kas startē kā root.
# sudo systemctl edit php8.3-fpm
[Service]
# /usr, /boot un /etc tikai lasāmi
ProtectSystem=full
# /home, /root un /run/user neredzami
ProtectHome=true
# savs /tmp un /var/tmp tikai šim pakalpojumam
PrivateTmp=true
# nekādas tiesību paplašināšanas ar setuid vai failu capabilities
NoNewPrivileges=true
Pārbaudiet šīs opcijas pirms ražošanas lietošanas. Ja vietnes atrodas zem /home, ProtectHome=true liedz piekļuvi. NoNewPrivileges=true var traucēt programmām, ko izsauc PHP un kas startēšanas laikā maina grupu tiesības, piemēram, dažām lokālām pasta programmām PHP funkcijai mail(). Tāpēc rīkojieties soļos:
- Pievienot vienu opciju, pārstartēt pakalpojumu, pārbaudīt
systemctl status php8.3-fpm. - Pārbaudīt vietnes pamatfunkcijas: pieteikšanos, veidlapas, pasta sūtīšanu, augšupielādes, lietojumprogrammas cron uzdevumus.
- Izvērtēt PHP-FPM un lietojumprogrammas kļūdu žurnālu.
- Tikai tad pievienot nākamo opciju.
Visbeidzot sockets: saskaņā ar PHP rokasgrāmatu tas pēc noklusējuma saņem tiesības 0660 pūla lietotājam un grupai. Iestatiet listen.owner un listen.group tā, lai pieslēgties drīkst tikai tīmekļa serveris, nevis ikviens lokālais lietotājs.
Minimālas tiesības ir pamatnostāja, nevis vienreizējs projekts. Pārbaudiet šī raksta inventarizāciju no jauna pēc katras pārbūves un katras jaunas vietnes, jo jauni pakalpojumi bieži nāk ar devīgām noklusējuma tiesībām.
Secinājums: uzbrucējs pārmanto to, ko jūs atļaujat
Least Privilege izklausās pēc teorijas, bet ir ļoti praktisks jautājums: ko var darīt tas, kurš izpilda kodu kā tīmekļa servera lietotājs? Serverī ar shell, sudo ierakstu, savu crontab un datubāzes kontu ar visām tiesībām atbilde ir: gandrīz visu. Ierobežotā serverī tas biežāk paliek incidents vienā vietnē, ko var atpazīt un attīrīt.
Pārejai nevajag jaunu programmatūru, tikai rūpīgu inventarizāciju un pakāpeniskus testus. Sāciet ar punktiem, kas gandrīz neko nevar salauzt, tas ir, shell, sudo un SSH atslēgām, un tad virzieties uz datubāzes tiesībām un systemd opcijām.
Kā PHP SOS palīdz konkrēti?
- Pārbaudīt kontus: mēs katram pūlam un tīmekļa serverim apkopojam lietotāju, shell, sudo ierakstus, cron uzdevumus, SSH atslēgas un datubāzes tiesības.
- Samazināt tiesības: mēs atņemam to, kas nav vajadzīgs, un nodalām deploy, izpildes un apkopes kontus.
- Ierobežot pakalpojumus: mēs pakāpeniski iestatām systemd aizsardzības opcijas un pēc katra soļa pārbaudām vietni.
- Noturēt ilgstoši: servera nostiprināšanas ietvaros mēs dokumentējam tiesību konceptu turpmākām izmaiņām.
Biežāk uzdotie jautājumi
Ar kuru lietotāju manā serverī darbojas PHP?
Tas ir atkarīgs no darbības režīma. Ar mod_php PHP darbojas kā Apache lietotājs, piemēram, www-data vai apache. Ar PHP-FPM katrs pūls ar user un group nosaka savu lietotāju; galvenais process parasti darbojas kā root, darbprocesi kā pūla lietotājs. Komanda ps to parāda ātri.
Vai tīmekļa servera lietotājam vajadzīga pieteikšanās shell?
Nē. Ne Nginx, ne Apache, ne PHP-FPM šim lietotājam interaktīvu pieteikšanos nevajag. Tāds shell kā /usr/sbin/nologin neļauj ar šo kontu pieteikties. Izvietošana (deployment) notiek ar atsevišķu lietotāju.
Kāpēc www-data nedrīkst būt sudo tiesību, pat ne vienai komandai?
Tāpēc, ka ievadīts kods pārmanto tieši šīs tiesības. Jau šķietami nevainīga komanda, ja tā atļauta nepareizi, var novest pie root tiesībām. Uzdevumi, kam vajadzīgas paaugstinātas tiesības, jāveic atsevišķos pakalpojumos vai procesos ārpus tīmekļa servera.
Vai tas palīdz pret PHP2Shell?
Tas neaizver ievainojamību; tam vajadzīgs PHP atjauninājums un visu darbprocesu pārstartēšana. Minimālas tiesības tomēr ierobežo to, ko uzbrucējs pēc veiksmīgas izmantošanas var izdarīt: mainīt failus, nostiprināties, sasniegt citas vietnes.