2016-11-18 50 views
8

PHP7, opcache adı verilen bir bytecode önbelleğe alma mekanizması sunar. Kaynak kodunu dağıtmadan bir PHP betiğinin (.bin dosya uzantısı) "opcached" sürümünü dağıtmak ve çalıştırmak için herhangi bir yol olup olmadığını bilmek isterim. (.bin dosyasını edinmek için php.ini yılında opcache.file_cache direktifini sağladı.)PHP7 opcached dosyaları kaynak kodu olmadan dağıtılabilir mi?

Ben bir senaryo çalıştırırken, PHP7 eşleşen ad, zaman damgası ile .bin dosyası için opcache dizinini kontrol ve belki de bir karşılaştırma varsaymak sağlama toplamı veya sağlama değeri. Her şey eşleşirse, PHP7 .php dosyasını ayrıştırmak yerine .bin dosyasını çalıştıracaktır. Belki de ilgili .php betiği bulunmadığında bile PHP'yi .bin dosyasını yürütmesi için 'kandırmak' mümkündür.

+0

İlginç. Bence yapabilir. http://gosecure.net/2016/04/27/binary-webshell-through-opcache-in-php-7/ –

+0

İy'i denediniz mi? – RiggsFolly

+0

7'de yeni değil, 5. sıradaydı. Önemli bir soru niçin istiyorsun? –

cevap

9

PHP, opcache'nin çağrılması için dosyayı açabilmeli; o yoksa, o ... yüklenemez

Let en look ayrıntılı olarak, biz oynayabilir ne hileler görmek için:

if (!file_handle->filename || !ZCG(enabled) || !accel_startup_ok) { 
    /* The Accelerator is disabled, act as if without the Accelerator */ 
    return accelerator_orig_compile_file(file_handle, type); 
#ifdef HAVE_OPCACHE_FILE_CACHE 
} else if (ZCG(accel_directives).file_cache_only) { 
    return file_cache_compile_file(file_handle, type); 
#endif 
} else if ((!ZCG(counted) && !ZCSG(accelerator_enabled)) || 
      (ZCSG(restart_in_progress) && accel_restart_is_active())) { 
#ifdef HAVE_OPCACHE_FILE_CACHE 
    if (ZCG(accel_directives).file_cache) { 
     return file_cache_compile_file(file_handle, type); 
    } 
#endif 
    return accelerator_orig_compile_file(file_handle, type); 
} 

Biz dosya önbelleği etkin olduğu görebiliriz Paylaşılan bellek önbelleğinin önceliğini alır.

Sonra, file_cache_compile_file bakmak istiyorum:

  1. block signals
  2. protect shared memory
  3. zend_file_cache_script_load

Şimdi zend_file_cache_script_load bakmak:

  1. verify magic "OPCACHE"
  2. verify system id
  3. optionally validate timestamp
  4. perform read of cached file
  5. verify checksum
open
  • read header (layout) Yani elimizdeki ilk sorun olduğunu system id i benzersiz değil, ancak aşağıdaki unsurlardan oluşur:
    1. sizeof(char)
    2. sizeof(int)
    3. :

      1. PHP sürümü
      2. Zend Uzatma tanımlayıcının
      3. İkili tanımlayıcı inşa aşağıdakileri içerir
      4. sizeof(long)
      5. sizeof(size_t)
      6. sizeof(zend_long)
      7. ZEND_MM_ALIGNMENT
    4. (git den, yayınlanmamış) PHP bir dev sürümünü kullanılmıyorsa: ikili
    5. ikili
    6. ___TIME___ derleme zamanı
      1. ___DATE__ derleme tarihi

    PHP sürümü ve tanımlayıcı inşa şu sürümleri arasında değiştirebilir veya olabilir en azından çünkü gereklidir oluşturur: opcodes

  • iç yapılarının
  • talimatlar VM dizisi düzeni için

    • ayrılmaz tanımlayıcıları Bekler (mevcut bir kontrol yapısının detayları fe değişebilir.Mimari boyutunu etkileyebilir: Önceki olanları keşfedilmiş olabilir çünkü foreach) opcache tarafından gerçekleştirilen
    • optimizasyonlar (Endianess ve mimarisi ile zval değişiklikleri en az düzeni nedeniyle ikili tanımlayıcı gereklidir

    ) güvensiz olduğu Bazı temel derleyici türlerinin (uzun, size_t vb.) yanı sıra bu türlerin üst ve alt sınırları, endianess yapıdaki üyelerin sırasını ve temel derleyici türlerinin ikili sunumunu etkileyebilir. ziyade çaba mevcut sistemi tanımlamak için harcanan

    Not etse bile, zaman damgaları opcache.validate_timestamps=0 doğrulama dosya önbellek girişi yükleme sağlayacak devre dışı bırakılması

    ... sen düşünmek için ara vermelidir dosya sistemindeki geçerli dosya boş.

    Başlıkta bulunan sağlama toplamı yalnızca dosyanın (başlıktan sonra gelen) komut dosyasının bölümünü doğrulamak içindir, sistem tanımlayıcısının veya sağlama toplamının bulunduğu üstbilgiyi içermez (ve yapamaz). yazılı.

    Bu nedenle, önbelleğe alınmış dosyanın header sistem tanımlayıcısını, hedef makine tanımlayıcısına karşılık gelecek şekilde değiştirerek, başka bir makineden önbelleğe alınmış bir dosyayı yüklemek için PHP'yi kandırabilirsiniz.

    Belki de, ancak yazılımınızı dağıtmanın bir yöntemi olarak kesinlikle değil.

    Dosya önbelleği bu amaç için uygun değildir, farklı mimarilerden veya önbelleklerden yükleme önbellekleri PHP'yi kilitler.

  • +1

    Detaylı dökümün için teşekkür ederiz! opcache.validate_timestamps = 0 'sıfır uzunluktaki bir .php dosyası ile birlikte bayt kodu başka bir makineye kopyalamak için hile yapar (her iki makinenin aynı kemer ve PHP sürümüne sahip olması koşuluyla). Bunun "üretim" için uygun olmadığını anlıyorum. Bayt kodu dağıtmanın başka bir yolu var mı? Belki bu [softwarerecs] için bir şeydir (http://softwarerecs.stackexchange.com/). – dasup

    +0

    Obstrüktif kodu dağıtmak istiyorsanız, düz PHP kodunu gizleyen bir araç kullanın. – Andrea