Mengapa lokasi variabel lingkungan sangat bervariasi?

9

Membaca buku Peretasan: Seni Eksploitasi oleh Jon Erickson, saya mencoba memperkirakan alamat variabel lingkungan SHELLCODEuntuk mengeksploitasi program.

Setiap kali saya berlari getenv("SHELLCODE");untuk mendapatkan lokasi, hasilnya sangat berbeda.

Ekstrak dari shell saya:

> for i in $(seq 10); do ./a.out SHELLCODE; done
SHELLCODE is at 0xff9ab3a3
SHELLCODE is at 0xffcdb3a3
SHELLCODE is at 0xffb9a3a3
SHELLCODE is at 0xffa743a3
SHELLCODE is at 0xffdb43a3
SHELLCODE is at 0xfff683a3
SHELLCODE is at 0xffef03a3
SHELLCODE is at 0xffc1c3a3
SHELLCODE is at 0xff85a3a3
SHELLCODE is at 0xff8e03a3

Saya mengerti bahwa jika nama program diubah atau variabel lingkungan baru ditambahkan, posisinya akan sedikit berbeda, tetapi mengapa lokasinya sangat bervariasi?

Janman
sumber
The getenvpengguna mengatakan ia mengembalikan pointer ke string yang berisi nilai variabel. Semua hal lain tidak ditentukan, sehingga kernel dan / atau kompiler Anda dapat menempelkan nilai di mana pun mereka inginkan, selama pointer-janji itu tetap benar. Saya menduga jawaban pasti untuk ini mungkin sihir yang berat dan tergantung pada berbagai detail implementasi pemetaan memori dan fase bulan. (Saya tidak cukup penyihir untuk memberikan jawaban yang tepat.)
Anko
"Saya mengerti bahwa jika nama program diubah atau variabel lingkungan baru ditambahkan, posisinya akan sedikit berbeda, tetapi mengapa lokasinya sangat bervariasi?" Itu benar dalam implementasi yang paling sederhana dari semua kemungkinan, tetapi tentu saja tidak diperlukan.
dmckee --- ex-moderator kitten

Jawaban:

13

Apa yang Anda gambarkan adalah fitur anti-eksploitasi yang disebut Address Space Layout Randomization (ASLR). Pada dasarnya, kernel menempatkan alamat paling atas dari tumpukan panggilan fungsi suatu program pada alamat yang sedikit berbeda ("acak") setiap kali kernel memuat file ELF program dari disk. Alamat-alamat di argvdan variabel lingkungan, di mana shellcode Anda adalah satu, berakhir di alamat yang berbeda dengan setiap permintaan program.

ASLR seharusnya membuat lebih sulit untuk mengeksploitasi buffer-overflow dan kerentanan terkait tumpukan lainnya. Pengeksploitasi harus menulis kode atau melakukan sesuatu untuk memperhitungkan berbagai alamat variabel dan nilai pada tumpukan panggilan fungsi.

Sepertinya Anda dapat menonaktifkan ASLR dengan melakukan sesuatu seperti:

echo 0 > /proc/sys/kernel/randomize_va_space

sebagai pengguna root. Karena Anda secara eksplisit mengutip Ubuntu, perintah di atas berbeda:

echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
Bruce Ediger
sumber
Ya, itu berhasil. Saya perhatikan bahwa penulis buku menggunakan Ubuntu 10.04, yang belum memiliki ASLR.
Janman