GNU/Linux >> Belajar Linux >  >> Linux

Linux Kernel ROP - Kembali ke userland dari konteks kernel?

Saya akhirnya menulis kode shell saya dengan cara yang berbeda. Karena saya tidak tahu bagaimana cara mengembalikannya, saya membiarkan kernel melakukan pekerjaan berat untuk saya, dengan kembali ke tanah pengguna. Idenya adalah untuk mengeksekusi bit eskalasi hak istimewa saya, dan melompat kembali ke tempat fungsi yang rentan seharusnya dikembalikan, dengan register dan tumpukan diperbaiki.

Segera setelah kernel kembali dari fungsi yang rentan (ketika tidak meluap), saya melihat sesuatu melalui gdb . (Alamatnya imajiner, tetapi menjelaskan konsepnya.)

(gdb) x/i $eip
0xadd1: ret
(gdb) x/xw $esp
0xadd1: 0xadd2
(gdb) x/6i 0xadd2
0xadd2: add esp,0x40
0xadd3: pop ...
0xadd4: pop ...
0xadd5: pop ...
0xadd6: pop ...
0xadd7: ret

Jadi, segera setelah dikembalikan, 0x40 byte tumpukan tidak digunakan dan akan hilang begitu saja dengan add esp petunjuk. Jadi, dengan memanfaatkan fakta ini, saya membuat rantai ROP (saya telah membuatnya saat menulis pertanyaan ini, tugasnya adalah menonaktifkan SMEP dan melompat ke kode shell userland saya), yang panjangnya 24 byte. 4 byte akan menimpa EIP pada saat pengembalian, dan 20 sisanya (0x14 ) akan mengikutinya langsung ke tumpukan yang tidak digunakan. Ini meninggalkan kita dengan 0x2c byte tumpukan yang tidak terpakai.

Tetapi jika kita kembali ke 0xadd2 , kita berisiko kehilangan 0x14 lebih lanjut byte informasi register yang berharga dari stack, dan mengisi register dengan data yang tidak valid. Kita bisa add 0x2c ke esp di shellcode userland kami, dan langsung melompat ke 0xadd3 , melewatkan add yang sebenarnya instruksi.

Juga mencatat dari sesi debug, semuanya kecuali eax dan ebx sedang dipulihkan dengan benar. Karena luapan saya telah menghancurkan keduanya, saya harus memulihkannya dengan nilai yang mirip dengan kasus ketika fungsi menghasilkan pengembalian yang bersih. (Melakukan ini sederhana:saya menyetel breakpoint di 0xadd2 , dan mengekstrak nilai dari info reg )

Jadi, kode shell userland terakhir saya adalah ini:

Execute privesc payload -> add esp,0x2c -> register fixup -> jump to 0xadd3

Melakukan ini, jalur kode kembali bersih sempurna, dan kernel melakukan tugas melompat kembali ke mode pengguna untuk saya.


Linux
  1. Linux – Apakah Kernel Linux/unix yang Berbeda Dapat Dipertukarkan?

  2. Bagaimana cara memuat modul kernel Linux dari kode C?

  3. Memanggil fungsi userspace dari dalam modul kernel Linux

  1. Kisah Linux Saya:Dari penggemar 8-bit hingga sysadmin Unix

  2. Dereferensi NULL-pointer kernel Linux di memset dari kzalloc

  3. Mengapa melindungi kernel Linux dari pengguna root?

  1. Mengapa saya beralih dari Mac ke Linux

  2. Memecahkan masalah Tahun 2038 di kernel Linux

  3. Menjadi administrator sistem Linux:Dari penjualan hingga sysadmin