Dampak dan Mitigasi Serangan SSHole

Dampak dan Mitigasi Serangan SSHole

Halo friends!

Kita tahu kalau password yang panjang biasanya dianggap lebih aman, tapi ternyata di serangan terbaru ini password sepanjang 300 karakter justru dapat melewati autentikasi OpenSSH!. Inilah SSHole bukan brute force, bukan password yang berhasil ditebak, melainkan hasil verifikasi yang salah diperlakukan sebagai kecocokan.

Kami mencoba mereproduksi laporan SSHole di lingkungan lab terisolasi. Hasilnya cukup jelas pada target OpenSSH upstream yang rentan, akun terkunci bisa menerima password panjang. Kami juga menguji pembanding yang sudah ditambal (patch) dan sistem berbasis glibc untuk melihat batas kerentanannya.

Apa sebenarnya SSHole?

SSHole adalah authentication bypass pada kombinasi OpenSSH tanpa PAM dan implementasi crypt() berbasis musl. Pada akun tertentu, field password di /etc/shadow berisi tanda bintang (*), yang normalnya berarti tidak ada password yang boleh cocok. Masalahnya, musl juga dapat menghasilkan string * sebagai penanda kegagalan hashing. Ketika dua nilai itu dibandingkan tanpa pemeriksaan yang memadai, kegagalan justru bisa dianggap berhasil.

Temuan ini tidak berarti semua OpenSSH, semua Alpine, atau semua server dengan port 22 terbuka otomatis rentan. Versi paket, konfigurasi autentikasi, dan keadaan akun menentukan apakah jalur tersebut dapat terjadi.

Mengapa bisa terjadi?

Pada 2012, musl mengubah perilaku crypt() saat terjadi kegagalan dan menerapkan batas 256 byte untuk input sha512-crypt. Password yang lebih panjang dapat menghasilkan nilai gagal berupa *. Secara terpisah, mekanisme OpenSSH untuk mengurangi kebocoran informasi waktu autentikasi memakai salt dari akun lain ketika diperlukan. Lalu, perubahan field akun root menjadi * pada konfigurasi Alpine tertentu membuat rangkaian kondisi ini relevan di sistem nyata.

Dengan kata lain, bukan SHA-512 yang berhasil dipecahkan. Masalahnya ada pada penanganan error dan perbandingan hasilnya. Detail jalur kode inilah yang kami telusuri dalam lab.

Membangun lingkungan pengujian

Kami menggunakan dua container Docker sebagai lingkungan terkontrol, dengan tiga konfigurasi uji:

Peran

Lingkungan

Hasil yang diharapkan

Target

musl; OpenSSH 10.0p2 upstream, --without-pam; port 2223

Menguji bypass

Kontrol Alpine

musl; openssh 10.0_p1-r11 yang sudah ditambal

Autentikasi ditolak

Kontrol Debian

Debian 12; glibc/libxcrypt; UsePAM no

Autentikasi ditolak

Di target, bob memiliki hash password SHA-512 yang valid untuk menyediakan salt; alice, carol, dan root sengaja diberi field shadow persis *. Konfigurasi ini disiapkan khusus untuk membuktikan mekanisme kerentanan, bukan menggambarkan semua instalasi Alpine.

Gambar 1. Kondisi akun pada container target sebelum pengujian.

Pengujian pertama: perilaku crypt() pada musl

Kami menjalankan program kecil yang memanggil crypt() menggunakan salt yang sama dan panjang password berbeda. Hasilnya menunjukkan batas yang tegas: 256 byte masih menghasilkan hash, sedangkan 257 byte dan lebih panjang menghasilkan *.

Gambar 2. Pada musl, input di atas 256 byte menghasilkan nilai gagal *.

Sebagai pembanding, pengujian glibc/libxcrypt di Debian tetap menghasilkan hash untuk input 257 dan 300 karakter. Pada 1024 karakter, hasilnya *0, bukan *; perbedaan kecil ini penting karena string yang dibandingkan tidak sama.

Gambar 3. Hasil pembanding glibc/libxcrypt menunjukkan perilaku berbeda.

Pengujian kedua: apakah benar bisa bypass login?

Setelah mengetahui perilaku crypt(), kami menguji autentikasi SSH ke target yang rentan. Dalam matriks lab, 256 karakter ditolak, sementara input 257–1024 karakter dapat diterima pada akun ber-field *. Akun bob yang mempunyai hash password sungguhan tidak menunjukkan bypass yang sama. Bahkan akun root pada konfigurasi lab ikut terdampak.

Satu detail penting percobaan yang berhasil terjadi pada percobaan password kedua dalam koneksi yang sama. Input 1025 karakter pada pengujian klien juga terlihat berhasil karena klien SSH memotong input menjadi 1024 sebelum mengirimkannya; itu bukan berarti batas di sshd melebihi 1024.

Gambar 4. Matriks autentikasi: batas 256/257 byte dan hasil untuk masing-masing akun.

Mengapa percobaan pertama gagal, tetapi kedua berhasil?

Kami memasang instrumentasi LD_PRELOAD untuk mengamati pemanggilan getspnam(), crypt(), dan strcmp() di proses sshd. Pada percobaan pertama, pembacaan ulang data akun saat pick_salt() menimpa buffer statis milik musl. Akibatnya, nilai field shadow yang tersimpan tidak lagi utuh dan login ditolak.

Pada percobaan kedua, salt sudah tersedia di cache sehingga pembacaan ulang tersebut tidak terjadi. Nilai * bertahan, crypt() juga mengembalikan *, dan perbandingan strcmp("*", "*") menghasilkan 0: keduanya dianggap sama. Di sinilah bypass terjadi.

Gambar 5. Trace internal sshd yang menjelaskan perbedaan attempt pertama dan kedua.

Apakah semua sistem musl rentan?

Tidak. Kami menjalankan matriks yang sama pada paket OpenSSH Alpine yang telah menerima perbaikan dan pada Debian berbasis glibc/libxcrypt. Semua upaya bypass pada kedua kontrol tersebut ditolak.

Gambar 6. Pengujian kontrol pada Alpine yang sudah ditambal dan Debian: seluruh bypass ditolak.

Bagaimana dengan Docker, OpenWrt, dan router ISP?

Alpine memang menggunakan musl secara default, tetapi container Docker berbasis Alpine tidak otomatis memiliki atau menjalankan sshd. Image seperti alpine, nginx:alpine, atau node:alpine biasanya menjalankan proses aplikasinya sendiri, bukan SSH server. Docker juga menyediakan docker exec untuk akses administratif container.

OpenWrt juga menggunakan musl, tetapi umumnya memakai Dropbear sebagai SSH server bawaan, bukan OpenSSH. Begitu pula perangkat router/ONT dari ISP: firmware-nya beragam, dan sebagian memakai Dropbear atau implementasi lain. Jadi kita tidak bisa menyimpulkan router rentan hanya karena berbasis Linux atau menyediakan port SSH.

Lingkungan yang layak diprioritaskan adalah VM/VPS Alpine dengan OpenSSH aktif, appliance embedded yang secara khusus memasang OpenSSH, atau container musl yang memang menjalankan sshd. Semuanya tetap harus diperiksa berdasarkan versi patch, PAM, konfigurasi password, dan kondisi akun.

Kapan bisa dibilang sistem kita terdampak?

·       Menggunakan musl libc, bukan hanya sekadar Linux.

·       Menjalankan OpenSSH server yang dapat diakses melalui jaringan.

·       Menggunakan autentikasi password tanpa PAM.

·       Memiliki kondisi akun dan field shadow yang sesuai dengan jalur kerentanan.

·       Belum menerima perbaikan upstream atau backport dari distribusi.

Kelima poin tersebut harus ada. Banner OpenSSH saja tidak membuktikan bahwa SSHole dapat dieksploitasi. Begitu pula nomor versi yang terlihat lama belum tentu rentan jika vendor sudah melakukan backport.

Patch dan mitigasi

OpenSSH 10.6p2 menambahkan pemeriksaan yang menolak nilai hash tersimpan terlalu pendek sebelum membandingkannya. Nilai seperti * dan *0 tidak lagi dapat diperlakukan sebagai kecocokan password. Paket distribusi juga dapat membawa perbaikan yang sama tanpa harus memakai nomor versi upstream terbaru.

Gambar 7. Perubahan kode pada branch OpenSSH V_10_6 yang menutup jalur bypass.

Langkah paling tepat adalah memperbarui paket OpenSSH dari repositori resmi distribusi dan memeriksa advisori vendor. Untuk Alpine, administrator dapat memeriksa dan memperbarui paket melalui apk; pastikan versi hasil pembaruan memang sudah membawa patch.

Jika pembaruan belum dapat dilakukan, nonaktifkan password authentication setelah akses berbasis public key dipastikan berfungsi. Periksa konfigurasi efektif dengan sshd -T, bukan hanya membaca satu baris konfigurasi. Batasi pula akses jaringan ke layanan SSH dan tinjau log autentikasi, khususnya jika ditemukan login sukses pada akun yang semestinya terkunci.

Referensi teknis

·       SSHole — https://sshhole.com/

·       OpenSSH 10.6p2 release notes — https://www.openssh.org/releasenotes.html#10.6p2

·       musl commits b3c4cc12 dan 88bf5a8a (2012)

·       OpenSSH commit 9286875a7 — perubahan terkait CVE-2016-6210

·       Alpine aports commit fbe926af — perubahan field root (2022)

·       OpenSSH portable, branch V_10_6 — patch “avoid password authn bypass”

Leave a Reply 0

Your email address will not be published. Required fields are marked *