PHP Type Juggling Zafiyeti

Merhaba arkadaşlar, bugün sizlere elimden geldiğince PHP Type Juggling özelliğinden ve bu özelliğin saldırganlar tarafından nasıl kötüye kullanılabileceğini anlatacağım.

PHP, hepimizin bildiği gibi esnek bir programlama dilidir. Bu esneklik, bir değişkene herhangi bir tür tanımlama yapmamamıza olanak tanır. Yani C, C++ veya Java programlama dillerinin aksine PHP değişkeninin türü kendisine atanan değere göre belirlenir. Aşağıdaki örneği incelediğimizde ilgili değişkenlere herhangi bir tür belirtmediğimizi ve içerisinde tutulan değere göre türünün belirlendiğini görüyoruz.

Farklı türdeki iki değişkenin karşılaştırılması sırasında PHP programlama dili bu iki değişkeni ortak, karşılaştırılabilir türe dönüştürür ve bu dönüşüme “Type Juggling” denir. Aşağıdaki PHP kodunu incelediğimizde bir Type Juggling yapıldığını ve sonucun True döndüğünü görüyoruz.

PHP Type Juggling yaparken tırnak işareti içerisinde belirtilen “1337” değerini bir tamsayıya dönüştürdü ve var1 değişkeni içerisinde yer alan değer ile karşılaştırdı. İki tamsayı değeri bir birine eşit olduğu için True değerini döndürdü. Aşağıdaki PHP kodlarına baktığımızda 0x01 hexadecimal değerinin decimal karşılığı 1 değeri olduğu için sonuç True dönmektedir.

Yukarıdaki PHP kodlarını PHP 5 versiyonunda çalıştırdığımızda True değerini döndürdüğünü görmüştük. PHP proramlama dilini geliştiren topluluk Type Juggling özelliğinin probleme sebep olduğunu belirtti. PHP 7 ve sonraki sürümlerde daha katı kurallar getirildi ve bu durumun önüne geçildi. Yukarıdaki ’0x01’ == 1 kontrolünü PHP versiyon 8 ile çalıştırdığımızda False değerinin döndüğünü görmekteyiz.

PHP Type Juggling Nasıl Bir Güvenlik Zafiyeti Oluşturabilir?
Yazılımcı ilgili kontrolleri Type Juggling ile doğrudan “==” operatörü ile yaparsa bu kontrollerin atlatılmasına sebep olabilir. Örneğin, yazılımcı kimlik doğrulama işlemini “==” operatörü ile yaparsa saldırgan ilgili kimlik doğrulama işlemini atlatabilir. Yazılımcımcının gözünden kaçan bu kontrol yaygın olarak kimlik doğrulama bypass’ı olarak karşımıza çıkmaktadır. Peki Type Juggling ile kimlik kontrolü nasıl atlatılabilir bir senaryo ile açıklamaya çalışalım.

Yazılımcının aşağıdaki PHP kodu ile cookie değerini kontrol ettiğini düşünelim. İlgili kullanıcının kullanıcı adı ve Unix zaman damgası alınıyor. Bu veriler ile MD5 şifreleme algoritması kullanılarak benzersiz bir özet değeri oluşturuluyor.  Sonra cookie değeri içerisinde yer alan hmac değeri ile üretilen özet değeri kontrol ediliyor. İlgili kontrole dikkat ettiğimizde != operatörü ile yapıldığını görmekteyiz.

Peki Burada Zafiyet Nerede?
hmac değeri kullanıcı tarafından kontrol edilebiliyor ise saldırgan buradaki kontrolü atlayabilir. Bunu yapmak için saldırgan ilgili hmac değerine 0 sabit değerini gönderir. Sonra kaba kuvvet saldırısı ile expiration(Unix Zaman Damgası) değerini bir bir arttırarak hash değişkenine atanan MD5 özet değerinin 0 ile başlaması sağlanır. Biraz daha açıklayıcı olabilmek için PHP kodunun adım adım çalışmasına bakalım.

Hash_hmac fonksiyonuna kullanıcı adı ve zaman damgası gönderilir.

hash_mac(okan|1654592878)

Yukarıdaki değerler MD5 şifreleme algoritmasına girer ve aşağıdaki şekilde bir özet değer ortaya çıkar.

c029c45c79770ebb7030f763f8088615

Saldırgan hmac değerini kontrol edebiliyor ise “0” değerini gönderir. Sonrasında if kontrolünün son hali aşağıdaki gibi olur.

“c029c45c79770ebb7030f763f8088615” =! “0”

Fakat yukarıdaki kontrol ile sonuç true döneceği için if blogunun dışına çıkamayacağız. Saldırgan zaman damgasını birer birer arttırarak kaba kuvvet saldırısı yapabilir ve özet değeri 0 ile başlayan bir değere denk getirebilir. Bu durumda 0 ile başlayan bir özet değeri oluşturulursa if kontrolü aşağıdaki gibi olacaktır.

“0e462097431906509019562988736854” =! “0”

If bloğu çalıştırıldığında false değerinin döndüğünü ve kontrolün atlatılabildiği görülmüştür.

Burada kontrol için özet değerin başındaki 0 değeri alınıyor ve geri kalan kısım alınmıyor. Bu şekilde kontrol ‘0’ =! ‘0’ gibi yapılmış olunuyor.

Bu Zafiyetten Korunmak için Neler Yapmalıyız?

  • Esnek olan “==” operatörü yerine kontrolleri daha katı olan “===” operatörü ile yapmalıyız. Bu şekilde iki değişkenin içerisinde yer alan değerleri ve türlerini kontrol etmiş oluruz.
  • Tür değişimlerini aşağıdaki yapıda yapmanızı önerilir.
    (int) ”0e1111” === (int)“0e112233”

Umarım açıklayıcı olmuşumdur, bir sonraki yazımda görüşmek üzere

Leave a Reply

Your email address will not be published. Required fields are marked *