XML EXTERNAL ENTITY INJECTION AND OOB (OUT-OF-BAND) DATA RETRIEVAL

Yayınlayan
Halit İnce
Yayınlanma tarihi
25/2/2022
Okuma süresi
10
Dakika
go back icon
Geri Dön

XML EXTERNAL ENTITY INJECTION AND OOB (OUT-OF-BAND) DATA RETRIEVAL

XML Nedir?

XML yani Extensible Markup Language, W3C (World Wide Web Consortium) tarafından bir veri iletişim standardı oluşturmak için tasarlanan bir metin işaretleme dilidir. XML’in geliştirilmesi ile birlikte veri alışverişi gerçekleştiren platformlar arasında bir iletişim standardı oluşturulmuş ve veri iletişimi sırasında yaşanan problemlerin önüne geçilmiştir. Belirli bir standart getirilmeden önce, iletişim esnasında taşınacak veri yapısının diğer sistemdeki yapıya uygun hale getirilmesi, karmaşık ve zaman alan bir süreç gerektiriyordu. Bu standart ihtiyacı dolayısı ile XML geliştirilmiştir ve günümüzde de veri iletimi gerektiren her alanda sıklıkla kullanılmaktadır. Günümüzde web sitelerinin haritalanması, veri tabanlarının aktarılması, içerik depolama gibi onlarca alanda XML kullanılmaktadır.

XML Entity Yapısı ve Zafiyete Doğru

XML üzerinde keşfedilmiş “Tag Injection”, “Entity Expansion” ve “XPath Injection” gibi birçok güvenlik açığı bulunmaktadır. Bu yazıda inceleyeceğimiz “XML External Entity Injection” zafiyetini daha iyi anlamak için “entity” yani “varlık” yapısını anlamak gerekmektedir. XML dilinde var olan “entity”(varlık) yapısı ile veri depolama sağlayabilmektedir. Bir veya daha fazla bulunabilmesi ile birlikte “entity” kavramı ile XML yapısında var olan veya yapı dışındaki bir veri tanımlanır.

Her XML dokümanı bir adet “document type” (DOCTYPE) adında varlık içermektedir. DOCTYPE varlığı içerisinde dosyada işlenen belgenin türü, belgeyi oluşturan etiketlerin tanımlandığı paketin ismi ve sürümü, nerede bulunabileceği, belgeyi oluşturan ek dosyalar varsa bunların tanımları gibi bilgiler belirtilir. Öncelikle Internal DTD (Document Type Definition) yapısını kullanan örnek bir XML dokümanını inceleyerek saldırgan bakış açısına doğru yolculuğa çıkalım.

XML üzerinde DTD (Document Type Definition) adı verilen ve doküman üzerindeki kayıtların uyması gereken kuralların belirlenmesini sağlayan bir yapı bulunmaktadır. Bu şekilde tanımlama yapılarak daha sonra bu tanımlamaya uygunluk durumu kontrol edilebilmektedir. Temel olarak bir XML dokümanında bulunacak DTD’nin belirlenmesi iki şekilde mümkün olmaktadır. Bunlar “Internal” (dahili) ve “External”(harici) DTD’dir. Bu tanımlama yöntemlerini sırayla inceleyerek zafiyete doğru yol alalım. Dahili DTD ile incelemeye başlayalım.

xml external entity injection

Dahili bir XML dokümanı tanımlarken(yukarıdaki örnekte göründüğü gibi), tanımlama ögeleri dahili yapıda yani dokümanın içerisinde bulunmaktadır. (#PCDATA, Parsed Character Data anlamına gelmektedir.) Buradaki DOCTYPE varlığını “message.dtd” adlı bir dosyada barındırdığımızı ve harici DTD yapısını kullanarak dahil ettiğimizi düşünelim.

xml external entity injection

XML üzerinde harici tanımlanmış yapıyı dahil edebilme imkanı, zafiyetin kokusunu aldığımız nokta olmakla birlikte “injection” türündeki birçok zafiyetin çıkış mantığını taşımaktadır. Biz de XXE Injection saldırısını incelediğimizden dolayı, harici DTD ile tanımlanmış varlığı dahil edebiliyor olmamız üzerinden ilerleyeceğiz. Saldırı senaryosuna geçmeden önce, bu durumun bir saldırganın zihninde ne çağrıştırabileceği üzerinde biraz düşünelim. Bir varlığı harici tanımlama ile dahil edebilmek; hedef sunucuda yetki dışında dosya okuyabilme, PHP desteği sağlanması durumunda uzaktan kod çalıştırabilme gibi senaryoları saldırganın aklına getirebilmektedir. Harici tanımlama durumunun zafiyet açısından önemini konuşmuşken bu yapıyı biraz daha detaylı inceleyelim.

XML External Entity ve Özellikleri

Harici varlıklar “public” ve “private” olarak ikiye ayrılmaktadır. “private” tanımlama, yapının iletişim kuracağı host üzerinde bulunan bir dosyayı dahil etmek istendiğinde kullanılmaktadır.

-* Private External Entity tanımlanması şu şekilde yapılmaktadır:

Örnek olarak aşağıdaki gibi bir copyright dosyası dahil edebiliriz :

xml external entity injection

-* “public” tanımlama ise, dahil etmek istediğimiz dosyayı farklı herhangi bir adresten almak istediğimizde kullanılmaktadır. Public External Entity tanımlanması şu şekilde yapılmaktadır:

Örnek olarak copyright dosyasını w3schools adresinden dahil edebiliriz:

xml external entity injection

Altını çizmemiz gereken bir diğer önemli nokta ise harici varlıkların sahip olduğu URI alanlarının sadece HTTP/S çözümleme yapmadığıdır. FTP, DNS, PHP gibi protokolleri de kullanabileceğimizi bilmek saldırı tarafında önemli faydalar sağlayacaktır.

XXE Injection İlk Saldırı Senaryosu

Zafiyet testi yapılacak odak noktası ve yapısını daha iyi anladığımızı düşünerek örnek bir senaryo işletelim ve zafiyetin nasıl sömürülebileceğine bakalım. İlk saldırı örneğimizde “private” entity yapısını kullanarak host üzerindeki password dosyasını nasıl okuyabileceğimizi görelim:

p>

Yukarıdaki gibi bir varlığı DOCTYPE varlığında oluşturup, bu varlığı XML yapısının herhangi bir yerinde çağırarak, zafiyete açık olan sistemlerde host üzerindeki dosyalara yetkisiz erişim sağlanabilmektedir. Örneğin:

xml external entity injection

Herhangi bir önlem alınmamış bir sistemde yukarıdaki gibi basit bir şekilde yetkisiz dosya okumak mümkün olmaktadır fakat yazının ilerleyen kısmında karşılaşabileceğimiz engeller ve bypass yöntemlerinden konuşacağız.

Saldırı aşamasında karşılaşabileceğimiz hatalardan biri de, harici bir dosya çağrıldığında oluşabilecek XML parser’dan kaynaklanan parsing hatasıdır. Bilindiği gibi “&”, “<” ve “>” gibi karakterler XML özel karakterledir. Saldırı yapılırken çağrılan dosyanın içeriğinde bu özel karakterlerden bulunması halinde parsing hatası oluşacak ve çalışma durumu sonlanacaktır. Bu gibi parsing hatalarından kaçınma konusunda imdadımıza “PHP” ve “base64” yetişmektedir.

xml external entity injection

Yukarıdaki gibi bir PHP konfigürasyon dosyasına erişmeye çalıştığımızı varsayalım:

xml external entity injection

Erişmeye çalıştığımız dosyada bulunan “<” ve “&” XML özel karakterleri parser’a takılacağı için dosyayı okumak mümkün olmayacaktır. Fakat daha önce bahsettiğimiz gibi varlıkların URI kısımları farklı protokol ve işlemleri desteklemektedir. PHP de bunlardan biri olmakla birlikte PHP I/O Stream’leri kullanarak bu hataları bypass etmek mümkündür. İşte bu noktada PHP desteği ile base64 hayat kurtarmaktadır. Okumak istediğimiz dosyayı PHP ile encode ederek çağırmak, XML parsing hatalarını bypass etmekte kullanılabilmektedir. Bu durumda az önceki URI kısmımızı aşağıdaki URI ile değiştiriyoruz:

php://filter/read=convert.base64-encode/resource=/path/to/config.php

xml external entity injection

Yukarıdaki gibi gerçekleştirilen base64 encoding işlemi ile okumak istediğimiz dosya, XML özel karakteri içermeyeceğinden encode edilmiş halde karşımızda olacaktır.

Başarı ile sonuçlanan saldırıdan sonra zorluk seviyesini biraz arttıralım. Bir sonraki kısımda dosya erişimi sırasında erişim engeli ile karşılaşılması ve bu engelin nasıl bypass edileceği üzerinde duracağız.

OOB(Out-of-Band) Data Retrieval

xml external entity injection

Örneğin, erişmeye çalıştığımız config.php dosyasının sadece belirli IP aralıklarına erişim izni verdiğini ve istek halinde “ACCESS DENIED” sayfası ile karşılaştığımızı varsayalım. Bu erişim engelini bypass etmenin bir yolu olan OOB tekniği, Black Hat EU2013 etkinliğinde Timur Yunusov ve Alexey Osipov tarafından sunulmuştur. Bypass mantığı basit anlamda hedef sisteme, saldırganın elinde bulundurduğu bir sunucuya, parametrelerinde hassas bilgiler barındıran HTTP isteğinde bulundurmaktır. Örnek üzerinden açıklamaya devam edelim:

xml external entity injection

Adım adım saldırıyı açıklayalım:

  1. Saldırganın sunucusunda bulunan evil_oob.dtd dosyasına HTTP isteğinde bulunalım.
xml external entity injection
  1. evil_oob.tdt dosyasının içeriğinde 3 adet varlık bulunmaktadır: resource, LoadOOBEnt ve OOB. Bunlardan ilki “resource”, daha önce bahsettiğimiz private yapıyı kullanarak host üzerindeki erişim engeli bulunan dosyayı dahil etme görevini üstlenmektedir. Bu varlık daha önce bahsettiğimiz gibi hedef dosyanın base64 ile encode edilmiş halini taşıyacaktır.
  2. Diğer iki varlığımız ise iç içe bulunmaktadır. Dış tarafta bulunan LoadOOBEnt, OOB varlığını dahil etmektedir. OOB varlığı ise, XML özel karakterleri encode edilerek oluşturulmuş(“!” = “%”) ve görevi saldırganın sunucusuna “resource” varlığını parametre olarak taşıyacak bir HTTP isteği sağlamak olan varlıktır.
xml external entity injection

4. Bu aşamada saldırganın gelen HTTP isteğini karşılamak üzere bir sunucu taşıması gerekmektedir. Aşağıdaki örnekteki gibi bu amaçla Ruby dili ile geliştirilmiş XXEServe aracı ile OOB varlığında tanımladığımız yani isteğin geleceği portu dinlemeye alıyoruz.

Çözüm Önerileri

XXE zafiyetine karşı alınabilecek önlemlerden birkaç tane örnekleyelim:

-XML işlemcisi ve kütüphanelerinin en güncel sürümde olup olmadığı kontrol edilmelidir. Bu bağlamda bağımlılık yöneticisi kullanılabilir.

-SOAP 1.2 ve üzerinin kullanılması önerilmektedir.

-Uygulamadaki tüm XML parser’ların XML External Entity özelliğinin kapatılması önerilmektedir.

– “Whitelist” mantığı ile çalışacak bir filtreleme metodu geliştirilmelidir.

XML dilinin yapısı ve amacı itibariyle verilerle haşır neşir olması birçok saldırganın ve güvenlik araştırmacısının odak noktasını kendine çekmektedir. XML varlıkları üzerinde gerçekleştirilen ufak müdahaleler ile saldırganlar oldukça ileri gidebilmektedir.

Halit İnce 06.05.2019

Referanslar

https://hdivsecurity.com/owasp-xml-external-entities-xxe

https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Processing

https://blog.elearnsecurity.com/xml-external-entity-xxe-attack-demo.html

https://media.blackhat.com/eu-13/briefings/Osipov/bh-eu-13-XML-data-osipov-slides.pdf

Halit İnce

Detaylı Bilgi İçin

info@gaissecurity.com