OpenAI'ın php2shell-checker aracı ilk kontrol için kullanışlıdır; ancak tek başına sunucunun güvenli olduğunu kanıtlamaz. Araç, HTTP başlıklarından veya php -v çıktısından elde ettiği PHP sürümünü, içinde tanımlı yama eşikleriyle karşılaştırır. Bu nedenle gizlenmiş bir başlık UNKNOWN sonucuna yol açabilirken, dağıtımın uyguladığı bir backport da güncellenmiş bir sunucunun savunmasız görünmesine neden olabilir.
Önce sonuçların ne anlama geldiğine bakın
OpenAI'ın resmi repository'si üç temel durum bildiriyor. Bunları kapsamlı bir güvenlik değerlendirmesi olarak değil, ilk triyaj sinyalleri olarak ele alın.
| Çıktı | Çıkış kodu | Ne anlatıyor? | Sonraki adım |
|---|---|---|---|
OK | 0 | Tanınan bir branch, minimum düzeltilmiş sürüme eşit veya ondan daha yeni | Web trafiğini karşılayan PHP process'inin gerçekten bu sürümü kullandığını doğrulayın |
VULNERABLE | 1 | Tespit edilen sürüm, minimum düzeltilmiş sürümün altında | Web servisinin kullandığı runtime'ı güncelleyin, worker'ları yeniden başlatın ve iki kontrolü de tekrarlayın |
UNKNOWN | 3 | Checker, tanınan bir sürüm veya yanıt tespit edemedi | Sunucuyu yerel olarak inceleyin; bu sonucu güncelleme yapılmış kabul etmeyin |
| Geçersiz argümanlar | 2 | Komutun kendisi geçerli değildi | Komutu düzeltip yeniden çalıştırın |
OpenAI'ın sunduğu araçta neler var?
Herkese açık php2shell-checker repository'sinde bir Node.js script'i, testler ve iki Codex skill'i bulunuyor: erişilebilen siteler için phpcheck-url, sunucuya erişiminiz varsa kullanabileceğiniz phpcheck-server. Araç sürüm kanıtlarını toplar; hedefi exploit etmez ve uygulama kodunu taramaz.
Kontrolü doğru modda çalıştırın
Herkese açık bir URL'yi kontrol etme
Önce repository'yi klonlayın veya indirin. Ardından Node.js script'ini bir siteye karşı çalıştırın:
node phpcheck.js "https://example.com"
Uzak kontrol, HTTP HEAD isteği gönderir; sunucu 405 veya 501 döndürürse GET'e geçer. X-Powered-By ve Server başlıklarını okur, yönlendirmeleri takip etmez ve yanıt gövdesini incelemez.
CDN, reverse proxy, expose_php=off ayarı veya özel sunucu yapılandırması, yanıt checker'a ulaşmadan önce PHP sürümünü kaldırabilir. VULNERABLE sonucu yama gerektirir; başlığın bulunmaması ise yerel kanıt toplamanız gerektiği anlamına gelir.
Yerel PHP binary'sini kontrol etme
PHP'nin kurulu olduğu bir makinede şu komutu kullanın:
node phpcheck.js --local
Bu komut, mevcut PATH üzerinde bulunan binary için php -v çalıştırır. Ancak web sitenize hizmet veren binary'nin de aynı olduğunu kanıtlamaz. Tek bir host üzerinde CLI, PHP-FPM, CGI, Apache module, container veya source-built kurulumlar birbirinden farklı olabilir.
Yerel kontrolden sonra web sunucusuna bağlı runtime'ı tespit edin. Container kullanılan bir dağıtımda yalnızca image tag'ini değil, çalışan container'ı da inceleyin. Paket yöneticisiyle kurulmuş bir serviste ilgili PHP-FPM pool'unu veya Apache module'ünü ve vendor paketinin changelog'unu kontrol edin.
Codex skill'lerini kurma ve kullanma
Resmi README, iki skill'i tek bir Codex komutuyla kuruyor:
$skill-installer install both skills from https://github.com/openai/php2shell-checker
Ardından erişim şeklinize uygun arayüzü seçin:
$phpcheck-url check https://example.com
$phpcheck-server check the PHP version serving my site
Codex kullanmak zorunlu değil. Node.js komutu, CI job'ları ve minimum özellikli host'lar için doğrudan kullanılabilen arayüz olmaya devam ediyor. Otomasyon için --json parametresini ekleyin. Bu parametrenin patch_status alanı, script'in terminal metnini ayrıştırmasını gerektirmeden ok, vulnerable veya unknown değerlerinden birini döndürür.
İndirdiğiniz checker'ı doğrulama
Repository, Node'un yerleşik test runner'ını kullanıyor:
node --test phpcheck.test.js
Test paketi, CLI'yi yerel HTTP sunucularına karşı çalıştırıyor ve yerel senaryolarda sahte bir PHP executable kullanıyor. README'ye göre testler için gerçek bir PHP kurulumu ya da harici bir web sitesine erişim gerekmiyor.
UNKNOWN sonucunu hata ayıklama sinyali olarak okuyun
UNKNOWN sonucunu eksik kanıt olarak değerlendirin. Hedef PHP sürümünü gizliyor, tanınmayan bir branch kullanıyor, yanıt vermiyor veya daha yeni bir prerelease çalıştırıyor olabilir. Bu senaryoların hiçbiri düzeltmenin uygulandığını göstermez.
Gerçek bir kullanıcı olan @jvr0x bu sınırlamayı şöyle özetledi:
“Bu araç yalnızca sürümü, 20 Ekim'deki eşiklerle karşılaştırıyor; dolayısıyla gizlenmiş başlıklar UNKNOWN olarak dönüyor.”
Uzak komut reverse proxy'nin arkasındaki process'i değil, HTTP yanıtını görür. Başlık gizleniyorsa tekrar tekrar URL kontrolü yapmak yerine sunucu tarafında kontrol gerçekleştirmek gerekir.
UNKNOWN sonrasında şu sırayı izleyin:
- Siteye hizmet veren host üzerinde
node phpcheck.js --localkomutunu çalıştırın. - İsteğin PHP-FPM, CGI, Apache
mod_phpveya bir container'a ulaşıp ulaşmadığını tespit edin. - Backport edilmiş yamalar için vendor paketinin changelog'unu kontrol edin.
- Güncelleme sonrasında ilgili PHP-FPM veya Apache worker'larını yeniden başlatın.
- Yalnızca shell'in varsayılan
phpbinary'sini değil, web trafiğini karşılayan servis yolunu da doğrulayın.
SSH erişiminiz yoksa URL modu ilk kontrol için elinizdeki tek seçenek olabilir. Shared host sürüm başlığını gizliyorsa hosting sağlayıcısının hizmet veren runtime'ı, paket revizyonunu ve yeniden başlatma durumunu doğrulaması gerekir.
Sürüm tablosu, yama kararının tamamı değil
Checker, ilgili branch'ler için PHP 8.5.12, 8.4.27, 8.3.36 ve 8.2.35 sürümlerini minimum düzeltilmiş upstream sürümler olarak kabul ediyor. Resmi testlerinde 8.4.26 sürümü VULNERABLE, 8.4.27 ise OK olarak doğrulanıyor. PHP de 8.5.12, 8.4.27, 8.3.36 ve 8.2.35 sürümlerini güvenlik sürümleri olarak tanımlıyor.
| Branch | Minimum düzeltilmiş upstream sürümü | Önceki sürümün sınıflandırması |
|---|---|---|
| PHP 8.5 | 8.5.12 | 8.5.11 |
| PHP 8.4 | 8.4.27 | 8.4.26 |
| PHP 8.3 | 8.3.36 | 8.3.35 |
| PHP 8.2 | 8.2.35 | 8.2.34 |
| Dağıtım senaryosu | Basit bir sürüm karşılaştırması neden yanıltabilir? | Kullanılacak kanıt |
|---|---|---|
Gizlenmiş X-Powered-By veya Server başlığı | Uzak checker PHP'yi tespit edemez | Yerel runtime envanteri |
| Debian veya Ubuntu güvenlik paketi | Vendor, upstream sürüm dizesini değiştirmeden düzeltmeyi backport edebilir | Vendor duyurusu ve paket changelog'u |
| Aynı host üzerinde PHP-FPM ve CLI | php -v, HTTP worker'ını değil CLI'yi gösteriyor olabilir | Web sunucusu ve FPM yapılandırması |
| Önbellekte kalan container veya sabitlenmiş digest | Registry tag'i güncel olsa bile çalışan container eski kalabilir | Çalışan container image ID'si ve sürümü |
| Yeniden başlatılmamış Apache veya FPM worker'ları | Düzeltilmiş dosyalar diskte bulunurken eski worker'lar çalışmaya devam edebilir | Process başlama zamanı ve yeniden başlatma sonrası kontrol |
| Desteklenmeyen branch veya prerelease | Checker vendor'a özgü yama durumunu tanımayabilir | PHP veya vendor güvenlik duyurusu |
Repository'nin limitations bölümü, aracın listelenen branch'lerdeki daha sonraki stable yamaların düzeltmeyi içerdiğini varsaydığını ve düzeltmeyi bağımsız olarak doğrulayamadığını belirtiyor. Bir dağıtım, upstream sürüm numarasını değiştirmeden güvenlik backport'u uygulayabilir. Bu durumda changelog, tek başına görüntülenen sürüm numarasından daha güçlü bir kanıttır.
WordPress, Drupal, Laravel veya başka bir PHP uygulamasını güncellemek PHP engine'ini yamalamaz. Runtime paketini veya image'ı güncelleyin, worker'ları yeniden başlatın ve web isteklerini kabul eden process'i doğrulayın.
Sık sorulan sorular
Hangi çıktı production remediation ticket'ını kapatmak için yeterli?
Tek başına hiçbir çıktı ticket'ı kapatmak için yeterli olmamalı. OK sonucunu serving SAPI, vendor backport durumu, ilgili tüm vhost veya container'lar ve yama sonrasında worker'ların yeniden başlatıldığına dair doğrulamayla birlikte değerlendirin.