Bagaimana STACKLEAK Meningkatkan Keamanan Kernel Linux

STACKLEAK adalah fitur keamanan kernel Linux yang awalnya dikembangkan oleh pencipta Grsecurity / PaX. Saya memutuskan untuk membawa STACKLEAK ke vanilla kernel resmi (Linux kernel mainline). Artikel ini akan berbicara tentang struktur internal, sifat-sifat fungsi keamanan ini dan jalurnya yang sangat sulit di jalur utama.





STACKLEAK melindungi terhadap beberapa kelas kerentanan di kernel Linux, yaitu:

  • mengurangi informasi yang berguna bagi penyerang, yang dapat bocor dari tumpukan nuklir ke ruang pengguna;
  • memblokir beberapa serangan terhadap variabel yang tidak diinisialisasi dalam tumpukan kernel;
  • menyediakan alat deteksi overflow tumpukan dinamis.

Fitur keamanan ini sangat cocok dengan konsep Proyek Perlindungan Diri Kernel (KSPP): keamanan lebih dari sekadar memperbaiki bug. Tentu saja semua kesalahan dalam kode tidak dapat diperbaiki, dan oleh karena itu kernel Linux harus bekerja dengan aman dalam situasi kesalahan, termasuk ketika mencoba untuk mengeksploitasi kerentanan. Rincian lebih lanjut tentang KSPP tersedia di wiki proyek .

STACKLEAK hadir sebagai PAX_MEMORY_STACKLEAK di patch grsecurity / PaX. Namun, patch grsecurity / PaX telah berhenti didistribusikan secara bebas sejak April 2017. Oleh karena itu, penampilan STACKLEAK di kernel vanilla akan sangat berharga bagi pengguna Linux dengan peningkatan persyaratan keamanan informasi.

Perintah kerja:

  • pilih STACKLEAK dari grsecurity / patch PaX,
  • mempelajari kode dengan hati-hati dan membentuk tambalan,
  • kirim ke LKML, dapatkan umpan balik, perbaiki, ulangi lagi sebelum diterima di jalur utama.

Pada saat penulisan (25 September 2018), versi 15 dari serangkaian tambalan dikirim. Ini berisi bagian dan kode arsitektur independen untuk x86_64 dan x86_32. Dukungan STACKLEAK untuk arm64, yang dikembangkan oleh Laura Abbott dari Red Hat, telah berhasil masuk ke kernel vanilla 4.19.

STACKLEAK: fitur keamanan


Menghapus informasi residual di tumpukan kernel


Ukuran ini mengurangi informasi yang berguna yang mungkin dihasilkan oleh beberapa kebocoran dari tumpukan nuklir ke ruang pengguna.

Contoh kebocoran informasi dari tumpukan kernel disajikan pada Gambar 1.



Skema 1.

Namun, kebocoran tipe ini menjadi tidak berguna jika, pada akhir panggilan sistem, bagian yang digunakan dari tumpukan kernel diisi dengan nilai tetap (Gambar 2).



Skema 2.

Sebagai hasilnya, STACKLEAK memblokir beberapa serangan terhadap variabel yang tidak diinisialisasi dalam tumpukan kernel. Contoh kerentanan tersebut: CVE-2017-17712, CVE-2010-2963. Kita dapat menemukan deskripsi metodologi eksploitasi untuk kerentanan CVE-2010-2963 dalam sebuah artikel oleh Kees Cook.

Inti serangan pada variabel yang tidak diinisialisasi dalam tumpukan kernel ditunjukkan pada Gambar 3.



Skema 3.

STACKLEAK memblokir serangan jenis ini, karena nilai yang mengisi tumpukan nuklir pada akhir panggilan sistem menunjukkan area yang tidak digunakan dalam ruang alamat virtual (Gambar 4).



Skema 4.

Keterbatasan penting adalah bahwa STACKLEAK tidak melindungi terhadap serangan serupa yang dilakukan dalam satu panggilan sistem.

Deteksi overflow inti inti stack


Dalam kernel vanilla (Linux kernel mainline) STACKLEAK efektif terhadap overflow kedalaman tumpukan kernel hanya dalam hubungannya dengan CONFIG_THREAD_INFO_IN_TASK dan CONFIG_VMAP_STACK. Kedua langkah ini diterapkan oleh Andy Lutomirski.

Versi paling sederhana untuk mengeksploitasi jenis kerentanan ini ditunjukkan pada Gambar 5.



Skema 5.

Menimpa bidang-bidang tertentu dalam struktur thread_info di bagian bawah tumpukan nuklir dapat meningkatkan hak istimewa proses. Namun, ketika opsi CONFIG_THREAD_INFO_IN_TASK diaktifkan, struktur ini dihapus dari tumpukan nuklir, yang menghilangkan metode yang dijelaskan dalam mengeksploitasi kerentanan.

Versi yang lebih maju dari serangan ini adalah menimpa data di wilayah memori tetangga dengan keluar dari batas tumpukan. Lebih lanjut tentang pendekatan ini:


Jenis serangan ini tercermin pada Gambar 6.



Skema 6.

Perlindungan dalam hal ini adalah CONFIG_VMAP_STACK. Ketika opsi ini diaktifkan, halaman memori khusus (halaman penjaga) ditempatkan di sebelah tumpukan nuklir, akses yang mengarah ke pengecualian (Gambar 7).



Skema 7.

Akhirnya, opsi paling menarik dari meluap tumpukan secara mendalam adalah serangan seperti Stack Clash. Gagasan ini diajukan oleh Gael Delalleau pada 2005.

Pada 2017, peneliti dari perusahaan Qualys memikirkannya kembali, menyebut teknik ini Stack Clash. Faktanya adalah bahwa ada cara untuk melompati halaman penjaga dan menimpa data dari wilayah memori tetangga (Gambar 8). Ini dilakukan dengan menggunakan array panjang variabel (VLA), yang ukurannya dikendalikan oleh penyerang.



Skema 8.

Untuk informasi lebih lanjut tentang STACKLEAK dan Stack Clash, lihat blog grsecurity .

Bagaimana STACKLEAK melindungi terhadap Stack Clash di tumpukan nuklir? Sebelum setiap panggilan untuk mengalokasikan (), pemeriksaan dilakukan untuk stack overflow secara mendalam. Berikut adalah kode yang sesuai dari versi 14 dari seri patch:

void __used stackleak_check_alloca(unsigned long size) { unsigned long sp = (unsigned long)&sp; struct stack_info stack_info = {0}; unsigned long visit_mask = 0; unsigned long stack_left; BUG_ON(get_stack_info(&sp, current, &stack_info, &visit_mask)); stack_left = sp - (unsigned long)stack_info.begin; if (size >= stack_left) { /* * Kernel stack depth overflow is detected, let's report that. * If CONFIG_VMAP_STACK is enabled, we can safely use BUG(). * If CONFIG_VMAP_STACK is disabled, BUG() handling can corrupt * the neighbour memory. CONFIG_SCHED_STACK_END_CHECK calls * panic() in a similar situation, so let's do the same if that * option is on. Otherwise just use BUG() and hope for the best. */ #if !defined(CONFIG_VMAP_STACK) && defined(CONFIG_SCHED_STACK_END_CHECK) panic("alloca() over the kernel stack boundary\n"); #else BUG(); #endif } } 

Namun, fungsi ini dikecualikan dari versi 15. Ini terutama karena larangan kontroversial Linus Torvalds untuk menggunakan BUG_ON () di patch keamanan kernel Linux.

Selain itu, versi ke-9 dari seri patch menyebabkan diskusi, sehingga diputuskan untuk menghilangkan semua array variabel dari kernel garis utama. Sekitar 15 pengembang terlibat dalam pekerjaan ini, dan akan segera selesai .

STACKLEAK Dampak Kinerja


Saya memberikan hasil pengujian kinerja pada x86_64. Peralatan: Intel Core i7-4770, 16 GB RAM.

Tes # 1, menarik: membangun kernel Linux pada inti prosesor tunggal

  # time make   4.18: real 12m14.124s user 11m17.565s sys 1m6.943s   4.18+stackleak: real 12m20.335s (+0.85%) user 11m23.283s sys 1m8.221s 

Tes No. 2, tidak menarik:

  # hackbench -s 4096 -l 2000 -g 15 -f 25 -P    4.18: 9.08     4.18+stackleak: 9.47  (+4.3%) 

Oleh karena itu, efek dari STACKLEAK pada kinerja sistem tergantung pada jenis beban. Secara khusus, sejumlah besar panggilan sistem pendek meningkatkan overhead. T.O. Kinerja STACKLEAK harus dievaluasi untuk beban yang direncanakan sebelum produksi.

Perangkat internal STACKLEAK


STACKLEAK terdiri dari:

  • Kode yang membersihkan tumpukan kernel pada akhir panggilan sistem (aslinya ditulis dalam assembler),
  • Plugin GCC untuk kompilasi instrumental dari kode kernel.

Mengosongkan tumpukan kernel dilakukan dalam fungsi stackleak_erase (). Fungsi ini memenuhi sebelum kembali ke ruang pengguna setelah panggilan sistem. STACKLEAK_POISON (-0xBEEF) ditulis ke bagian tumpukan tumpukan yang digunakan. Variabel terendah_stack, terus diperbarui di stackleak_track_stack (), menunjuk ke titik awal pembersihan.

Tahapan stackleak_erase () tercermin dalam skema 9 dan 10.



Skema 9.



Skema 10.

T.O. stackleak_erase () hanya membersihkan bagian yang digunakan dari tumpukan nuklir. Itu sebabnya STACKLEAK sangat cepat. Dan jika Anda menghapus semua 16 kB tumpukan kernel pada x86_64 pada akhir setiap panggilan sistem, hackbench menunjukkan penurunan kinerja 40%.

Instrumentasi kode kernel pada tahap kompilasi dilakukan dalam plugin STACKLEAK GCC.

Plugin GCC adalah modul yang dapat diunduh khusus proyek untuk kompiler GCC. Mereka mendaftarkan pass baru dengan GCC Pass Manager, memberikan callback untuk pass ini.

Jadi, untuk operasi STACKLEAK yang lengkap, panggilan ke stackleak_track_stack () dimasukkan ke dalam kode fungsi dengan bingkai tumpukan besar. Juga, sebelum setiap alokasi (), panggilan ke stackleak_check_alloca () yang telah disebutkan dimasukkan, dan setelah itu, panggilan ke stackleak_track_stack () dimasukkan.

Seperti yang telah disebutkan, pada versi 15 dari seri patch, penyisipan panggilan ke stackleak_check_alloca () dikecualikan dari plugin GCC.

Path di jalur utama kernel Linux


Jalur STACKLEAK di jalur utama sangat panjang dan sulit (Gambar 11).



Skema 11. Kemajuan implementasi STACKLEAK di jalur utama kernel Linux.

Pada bulan April 2017, pencipta grsecurity menutup tambalan mereka untuk komunitas, mulai mendistribusikannya hanya secara komersial. Pada bulan Mei 2017, saya memutuskan untuk mengambil tugas memperkenalkan STACKLEAK ke dalam inti vanila. Maka dimulailah perjalanan yang lebih lama dari satu tahun. Perusahaan Positive Technologies, tempat saya bekerja, memberi saya kesempatan untuk menangani tugas ini selama beberapa waktu kerja saya. Tetapi pada dasarnya, saya menghabiskan waktu "bebas" untuk itu.

Sejak Mei lalu, seri tambalan saya telah mengalami beberapa ulasan, telah mengalami perubahan signifikan, telah dua kali dikritik oleh Linus Torvalds. Saya ingin meninggalkan semua ini berkali-kali. Tetapi pada saat tertentu ada keinginan kuat untuk mencapai akhir. Pada saat penulisan (25 September 2018), versi ke-15 dari seri patch ada di cabang linux-next, memenuhi semua persyaratan yang disebutkan dari Linus dan siap untuk jendela gabungan dari kernel 4.20 / 5.0.

Sebulan yang lalu, saya memberi ceramah tentang pekerjaan ini di Linux Security Summit. Saya memberikan tautan ke slide dan video :


Kesimpulan


STACKLEAK adalah fitur keamanan kernel Linux yang sangat berguna yang memblokir eksploitasi beberapa jenis kerentanan sekaligus. Selain itu, penulis asli Tim PaX mampu membuatnya cepat dan cantik dalam rekayasa. Oleh karena itu, penampilan STACKLEAK di kernel vanilla akan sangat berharga bagi pengguna Linux dengan peningkatan persyaratan keamanan informasi. Selain itu, bekerja dalam arah ini menarik perhatian komunitas pengembang Linux untuk alat pertahanan diri kernel.

PS


STACKLEAK akhirnya diadopsi oleh kernel Linux 4.20:
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=2d6bb6adb714b133db92ccd4bfc9c20f75f71f3f

Arsitektur yang didukung adalah x86_64, x86_32, dan arm64.

Selain itu, pekerjaan telah selesai untuk menghilangkan array panjang variabel dari kode kernel Linux. Peringatan kompiler Gcc "-Wvla" termasuk dalam versi kernel 4.20: lkml.org/lkml/2018/10/28/189

Source: https://habr.com/ru/post/id424633/


All Articles