Yayınlanan advisory [1] için kısa bir analiz yapayım dedim iyide ettim herhalde çok sık yazamıyorum malum vakit ayıramıyorum yada üşeniyorum :) neyse az laf çok iş diyerekten girişiyorum analize çok konuştum yine :]
modules/gnupg/json.php:
...
$data = $gnupg->export($_REQUEST['fingerprint']);
...
Görüldüğü üzere export methodu parametre olarak 'fingerprint' isimli HTTP isteğiyle birlikte çağırılıyor. Birde export methoduna göz atalım. Açıkca söyleyeyim bu zafiyeti bulmam 4 yada 5 dakika mı aldı tabi yayınlamak daha uzun sürdü, biraz üşengeçlik biraz vendor'u bekleme vs... gerçi vendor geri dönmedi o da ayrı bir meselede :))
uygulama önüme geldiğinde modüllerin bulunduğu klasöre girdim şöyle modül isimlerine bakıyordum gnupg'yi gördüm gnupg GNU'nun bir uygulaması, linux kullananlar bilirler [2] sanırım kullanmışlıkları varsa malum sistem üzerinde çalışan bir uygulama. Ee nolmuş yani ? Yani bu web uygulaması gnupg'ye erişmek için komut çalıştırıyor :)
Herneyse kaldığım yerden devam ediyorum.
modules/gnupg/classes/gnupg.class.inc.php:
public function export($fingerprint)
{
$this->run_cmd('--armor --export '.$fingerprint, $key);
...
}
Kırmızı ile işaretlediğim kısım 'run_cmd' methoduna ilk parametre olarak yollanıyor. Aynı dosya içerisindeki run_cmd methodunun nasıl tanımlandığına ve neler yaptığına bakalım
private function run_cmd($cmd, &$output=null, &$errorcode=null, $data=null, $passphrase=null, $background=false)
{
...
$complete_cmd .= ' '.$cmd;
...
$p = proc_open($complete_cmd,$this->fd, $this->pipes);
...
}
Methodun ilk parametresi olan 'cmd' parametresi 'complete_cmd' isimli bir değişkenin en sonuna ekleniyor. Ardından morumsu bir renk ile işaretlediğim yere bakarsanız 'complete_cmd' değişkeni yani kullanıcının girdisi ile çok kolayca manipule edilen değişken php'nin vukuatlı* fonksiyonlarından birisi olan proc_open ile çalıştırılıyor. Bu zafiyetin tek kötü yanı çalıştırılan komut 'p' isimli bir değişkene atanıyor o yüzden komutlarınızın çıktısını göremiyorsunuz ama şöyle birşey yapabilirsiniz mesela; cat /etc/passwd > ./password yaparsanız json.php'nin bulunduğu dizinde bir adet /etc/passwd dosyasına sahip olabilirsiniz :))
Exploitation ise şu şekilde oluyor;
http://server/groupoffice/modules/gnupg/json.php?task=send_key&fingerprint=xyz;COMMAND
Saldırı :]
Sonuç =)
Önlemek için ise escapeshellcmd veya escapeshellarg fonksiyonları kullanıcı girdilerine uygulanabilir eğer çalıştırılacak bir komuta dahil edilecekse kullanıcı girdisi..
ciao! ;)
* vukuatlı dememin sebebi uzaktan komut çalıştırılmasına imkan verebiliyor olması :)
[1] http://www.exploit-db.com/exploits/14381/
[2] http://www.gnupg.org
yine konuşturmuşsun bilgini kardeşim (:
ReplyDeleteYok canım yaa :)
ReplyDelete(: öyle öyle mütevazliğe gerek yok :P
ReplyDelete