Bug, Hacker, & Developer

Jika kita mencari melalui google[5] mengenai NULL pointer dereference, maka akan banyak sekali laporan tentang bug ini. Pada dasarnya bug tersebut adalah hal yang umum bagi programmer dimana penyebabnya adalah kekurangan proses checking dalam suatu aplikasi. Programmer yang baik biasanya akan melakukan beragam test case terhadap aplikasi miliknya, hal ini dilakukan untuk melihat sejauh mana aplikasi tersebut dapat meng-handle berbagai situasi yang akan ditemukan pada saat digunakan oleh user. Namun biasanya disebabkan oleh aplikasi yang sangat kompleks, ataupun dikarenakan berbagai macam alasan lainnya bug jenis ini tidak dapat dihindari sekalipun oleh seorang programmer tingkat tinggi.

Dan oleh para hacker, setiap bug terutama yang melibatkan memory corruption seperti ini selalu bisa dimanfaatkan untuk mengambil alih sistem. Hal sederhana telah kita lakukan sebelumnya dimana mmap() dapat digunakan untuk mengontrol lokasi zero page memory, dan oleh para hacker / cracker bidang security hal tersebut dijadikan sebagai pintu masuk untuk mendapatkan akses yang lebih tinggi (contoh: root) ataupun merebut sistem.

Mekanisme logisnya sederhana, kita bisa memasukan data apapun kedalam zero page memory (contoh: shellcode), sisanya tinggal men-trigger NULL pointer dereference sehingga eksekusi akan menuju zero page memory, dan pada akhirnya sistem akan berada dibawah kendali kita.

Pada sistem komputer (khususnya intel) terdapat mekanisme untuk memisahkan antara kernel process dan userland process. Intel memperkenalkan mekanisme ini melalui istilah-istilah seperti protected mode ataupun ring. Intinya, dalam hal pembagian resource akan dilakukan pemisahan antara kernel process dan user process. Sehingga alokasi memory misalnya, antara kernel process dan user process dilakukan pemisahan hingga level physical memory secara eksplisit. Dengan mekanisme ini resource dari user process tidak akan pernah bisa dicampur aduk dengan resource dari kernel process, hal ini akan meningkatkan security sistem komputer.

Dari sisi CPU, terdapat mekanisme privilege rings dalam protected mode. CPU
harus masuk ke Ring 0 ketika menjalankan instruksi kernel, Ring 1 / Ring 2 ketika menjalankan instruksi device drivers, dan Ring 3 ketika menjalankan instruksi userland process.

NULL pointer dereference jika terjadi pada user process mungkin tidak akan
terlalu berbahaya karena seperti yang telah dibahas sebelumnya, zero page yang di-kontrol hanya sebatas zero page untuk user process. Namun jika bug NULL pointer dereference terdapat pada kernel maka kita dapat mengambil alih sistem secara penuh. Inilah yang menjadikan bug NULL pointer dereference berbahaya.

Bug NULL pointer dereference bisa terjadi pada setiap sistem operasi (Windows, FreeBSD, OpenBSD, Linux, Solaris, dll), namun setiap sistem operasi memiliki strategi masing-masing dalam hal memory management, sehingga eksploitasi terhadap NULL pointer dereference pada satu sistem operasi tidak bisa di implementasikan begitu saja pada sistem operasi lainnya. Pada tahap inilah kita biasa mendengar bahwa suatu sistem operasi di klaim memiliki tingkat security yang jauh lebih baik dibandingkan sistem operasi lainnya. Sehingga tidak salah jika Theo de Raadt sang founder / developer OpenBSD sering menyombongkan bahwa OpenBSD adalah sistem operasi paling aman dan paling sulit untuk di-eksploitasi :)

Kembali ke Linux, kernel 2.4 dan 2.6 sendiri memiliki mekanisme yang cukup
berbeda pada beberapa bagian terutama memory management. Secara teknis, NULL pointer dereference dari bug kernel akan lebih sulit untuk di-eksploitasi pada kernel 2.4 dibandingkan kernel 2.6 (Linus Torvalds mengorbankan security untuk performa dan fitur yang akan bisa diusung oleh kernel 2.6), namun dikarenakan bug NULL pointer dereference sangat banyak maka developer kernel Linux menambahkan fitur sysctl mmap_min_addr untuk Virtual Memori (vm) sejak kernel 2.6.23, fungsi dari fitur ini adalah untuk me-limit mapping terhadap zero page memory oleh user process yang biasanya digunakan oleh para hacker / cracker untuk mengambil alih sistem saat memanfaatkan bug NULL pointer dereference.

Fitur ini cukup sederhana, kita bisa mendefinisikan sendiri lokasi minimum yang bisa digunakan oleh mmap() untuk proses mapping, jadi jika kita definisikan mmap_min_addr (yang juga bisa dilihat secara langsung dari file /proc/sys/kernel/mmap_min_addr) dengan nilai 64KB (65,536 bytes) maka aplikasi user / user process tidak akan diperbolehkan menggunakan mmap() untuk mapping lokasi antara 0 hingga 64KB.

# sysctl -w vm.mmap_min_addr=65536 <set agar bernilai 64KB>
vm.mmap_min_addr = 65536

Fitur ini terbukti dapat mempersulit eksploitasi NULL pointer dereference yang memanfaatkan trik mmap().