Buffer Overflow, Ancaman Keamanan Perangkat Lunak dan Solusinya Damar Widjaja Jurusan Teknik Elektro, Universitas Sanata Dharma Yogyakarta Kampus III, Paingan, Maguwoharjo, Sleman
[email protected] Abstract Security exploitation that is used by hacker and combined with computer virus cause a very complex threat to a software based system and application. In some cases, this kind of attack is beyond the capability of antivirus software. More than half of security vulnerability problems are caused by Buffer Overflow (BO). The BO attack will still be a problem in the next 20 years. BO occur when a computer program try to safe data to a buffer, where the size of the data is bigger than the size of the buffer. This paper intended to present the BO attack process and the survey of some techniques to deal with this problem. Not all techniques are presented. However, better understanding of BO attack can be expected after the full read of this paper. Keywords: Buffer Overflow, security vulnerability, computer program.
1. Pendahuluan Eksploitasi security, yang sering digunakan oleh para hacker, yang digabungkan dengan virus komputer, dapat menyebabkan serangan yang sangat kompleks terhadap sistem dan aplikasi berbasis software [1]. Dalam kasus tertentu, serangan semacam ini jauh melebihi kemampuan software antivirus. Salah satu masalah keamanan yang cukup lama muncul dan sangat mengganggu adalah serangan dengan Buffer Overflow (BO). Pembobolan sistem komputer pertama yang cukup signifikan, yang memanfaatkan BO, adalah Morris Worm (yang diluncurkan oleh Robert Morris) yang terjadi pada bulan Nopember 1998 [2 – 4]. Virus (worm) ini memanfaatkan BO di finger service, yaitu service yang memberikan informasi tentang sekelompok pengguna yang "log in" pada sistem komputer berbasis UNIX. Saat mendapat akses ke sistem yang rentan, program yang dibuat Morris ini ter-install pada satu mesin dan, dengan metode tertentu, menyebar ke mesin yang lain. Pada mulanya Morris menginginkan penyebaran ke mesin lain berlangsung dengan lambat dan tidak membuat kerusakan yang besar pada mesin yang terkena. Tetapi pada kenyataanya terjadi error dan menyebabkan worm menyebar dengan kecepatan yang tinggi. Karena error ini, mesin yang terinfeksi menjadi terinfeksi terus-menerus secara cepat dan menyebabkan sistem terbebani. Akhirnya program Morris dapat terdeteksi dengan cepat. Hampir separo dari masalah security vulnerability saat ini disebabkan oleh BO dan diperkirakan masih menjadi masalah dalam 20 tahun mendatang [5, 6]. Dengan melakukan serangan terhadap BO, pengguna jarak jauh, seperti pengguna internet dapat mempunyai kendali total terhadap suatu host. Sehingga serangan terhadap BO merupakan ancaman keamanan yang paling serius. 2. Pengertian dari Buffer Overflow Buffer adalah area penyimpanan data yang mempunyai kapasistas/ukuran tertentu. Buffer overflow (BO) terjadi jika suatu program berusaha menyimpan data ke buffer, dimana ukuran data lebih besar dari ukuran buffer [1]. BO terjadi karena pembuat program
Media Teknika Vol. 8 No. 1, Juni 2008: 13 – 19
komputer menulis baris kode tanpa mengecek ukuran dari buffer yang dituju untuk mengetahui apakah cukup untuk menerima data baru [2]. Saat jumlah data melebihi ukuran buffer, kelebihan data dapat melimpah ke lokasi memory terdekat, merusak data dan bisa merubah path dan perintah eksekusi. Diantara informasi yang rusak, mungkin terdapat informasi yang berisi subroutine dari suatu program, sehingga program tidak dapat menemukan subroutine dan tidak dapat menyelesaikan programnya. Kemampuan eksploitasi BO memungkinkan seseorang untuk memasukkan kode sembarang ke path eksekusi. Kode ini memungkinkan akses jarak jauh yang terlarang (unauthorized). Seorang hacker bisa mengirimkan data yang lebih besar dari ukuran buffer dan berisi kode yang dirancang untuk melakukan aksi tertentu, untuk merusak atau mengubah data dan membuka informasi rahasia [7]. Ada beberapa jenis BO berdasarkan kemudahan eksploitasi dan teknik yang digunakan. Tetapi secara konsensus, BO dibagi dalam tiga generasi. Generasi pertama adalah overwriting stack memory. Generasi kedua adalah heap, function pointer dan eksploitasi off-by-one. Generasi ketiga adalah format string attack dan vulnerabilities in heap memory management. Tulisan ini akan membahas generasi pertama dari BO. Detil dari kedua generasi BO yang lain dapat dilihat di [1]. 3. Proses terjadinya Buffer Overflow Dalam program yang menggunakan bahasa C, buffer dialokasikan dengan array atau pointer. C atau C++ tidak mempunyai pengecekan otomatis (automatic bounds checking) batasan suatu buffer, sehingga pengguna dapat menulis kode untuk memberikan data melebihi ukuran buffer [8]. Sebagai contoh: int main () { int buffer[10]; buffer[20] = 10; } Program di atas adalah program yang valid dan compiler dapat meng-compile tanpa error. Tetapi program tersebut berusaha untuk memberikan data melebihi alokasi memory untuk buffer. Hal ini dapat mengakibatkan kejadian yang tidak diinginkan. Konsep ini digunakan para hacker untuk mengacau industri komputer. Program yang dapat dieksekusi berisi sekumpulan instruksi biner yang harus dieksekusi oleh processor. Instruksi ini dapat berupa read-only data, (seperti print format strings), data global dan data statis yang tetap ada selama proses eksekusi, dan break pointer yang selalu mengikuti malloced memory. Function local variable adalah variabel otomatis yang ada di stack selama suatu fungsi bekerja dan dibuang setelah fungsi selesai bekerja. Gambar 1 memperlihatkan memory layout dari suatu proses Linux. Proses dimulai dengan kode program dan data. Kode dan data berisi instruksi program serta data global dan data static yang terinisialisasi maupun tak terinisialisasi. Setelah itu adalah run-time heap (dibuat dengan malloc/calloc), dan di paling atas adalah users stack. Stack digunakan jika ada function call.
14
Damar Widjaja, Buffer Overflow, Ancaman …
Gambar 1. Memory layout pada proses Linux [8]. 3. 1. The Stack Region Stack adalah blok memory yang berisi data. Stack Pointer (SP) menunjukkan puncak dari stack. Jika ada function call, parameter fungsi dimasukkan ke stack dari kanan ke kiri. Kemudian return address (alamat yang dieksekusi setelah fungsi selesai) dan frame pointer (FP) juga dimasukkan ke stack. FP digunakan sebagai referensi dari local variable dan parameter fungsi, karena keduanya berada pada jarak yang konstan dari FP. Locl automatic variabel dimasukkan ke stack setelah FP.
Gambar 2. Typical Stack Region [8]. Gambar 2 memperlihatkan typical stack region saat function call dieksekusi. Perlu dicatat bahwa FP berada di antar local dan return address. Untuk contoh program dalam bahasa C berikut: void function (int a, int b, int c) { char buffer1[5]; char buffer2[10]; } int main() { function(1,2,3); } function stack akan terlihat seperti gambar berikut:
15
Media Teknika Vol. 8 No. 1, Juni 2008: 13 – 19
Gambar 3. Function stack untuk contoh program di atas [8]. Gambar 3 menunjukkan bahwa buffer1 berisi 8 bytes dan buffer2 berisi 12 bytes. Sedangkan memory hanya dapat digunakan untuk beberapa word size (4 byte). Sebagai tambahan, FP diperlukan untuk mengkases a, b, c, buffer1, dan buffer2. Semua variabel ini akan dibuang dari stack jika fungsi selesai bekerja. 4. Serangan Buffer Overflow Pada serangan BO, penyusup akan membuat buffer menjadi overflow dengan script yang ditulis sedemikian rupa sehingga program melakukan apa yang diinginkan oleh penyusup, bukan apa yang diinginkan pemrogram [2]. Akibatnya, penyusup menjadi pemrogram karena instruksinya yang dieksekusi. Penyusup sering memprogram ulang suatu aplikasi untuk membuat program lain bekerja. Sebagai contoh pemrogram dapat memulai program baru yang dapat mengirimkan data rahasia seperti rekening bank, password, atau surat rahasia melalui email. Tujuan dari serangan BO adalah untuk melemahkan fungsi dari suatu program sehingga penyusup dapat mengambil alih kendali pada program tersebut [6]. Tujuan selanjutnya adalah mengendalikan host dari jarak jauh. Untuk mencapai hal tersebut, penyusup harus dapat mengatur kode yang sesuai supaya tersedia di alamat program dan membuat program untuk jump ke kode tersebut, dengan parameter yang dimasukkan ke dalam register dan memory. Serangan BO yang paling sederhana adalah stack smashing [3 – 5], yaitu memberi data baru pada stack suatu buffer untuk mengganti return address. Saat suatu fungsi selesai, control akan melompat (jump) ke alamat yang ditulis di stack oleh penyusup, sehingga penyusup akan mempunyai kemampuan untuk mengeksekusi kode yang diinginkan. Program yang ditulis dalam bahasa C sangat rentan terhadap serangan BO. Besarnya memory dan performansi merupakan pertimbangan yang lebih penting dari bahasa C dibandingkan keamanan. Library standar dalam bahasa C menjadi sangat tidak aman jika digunakan secara tidak hati-hati. Walaupun begitu, banyak program keamanan yang ditulis dalam bahasa C. Bahasa C menyediakan akses langsung ke low-level memory dan pointer arithmetic tanpa bounds checking, sehingga fungsi-fungsi dari library standar C, seperti gets dan strcpy , dapat menuliskan jumlah yang tak terbatas dari user input ke buffer dengan ukuran yang tetap. Untuk mengeksploitasi ancaman ini, penyusup tinggal memasukkan input yang lebih besar dari ukuran buffer dan memberikan kode untuk menyusup. Proses stack smashing diperlihatkan pada Gambar 4. Proses ini terdiri dari Inject Attack Code dan Change the Return Address.
16
Damar Widjaja, Buffer Overflow, Ancaman …
Gambar 4. Stack smashing BO attack [3]. Pada Inject Attack Code, penyusup memberikan input string yang dapat dieksekusi berupa kode biner ke mesin yang diserang. Biasanya kode ini sederhana dan melakukan hal yang sama seperti exec("sh") untuk menghasilkan root shell. Pada tahap Change the Return Address, terdapat stack frame untuk fungsi yang sedang aktif yang berada di atas buffer yang sedang diserang pada stack-nya. Saat function return, tidak akan kembali ke tempat di mana fungsi itu dipanggil, tetapi jump ke kode penyusup. Program yang diserang dengan teknik ini biasanya priveledged daemon, yaitu program yang bekerja dengan user-ID dari root untuk melakukan beberapa layanan. Kode penyusup biasanya suatu deretan instruksi singkat yang menghasilkan shell yang juga bekerja dengan user-ID dari root. Akibatnya, penyusup mendapatkan shell dengan root priveledge. Jika input program diberikan dari proses lokal yang sedang berjalan, maka setiap pengguna dengan account lokal dapat menjadi root. Lebih parah lagi jika input program berasal dari koneksi jaringan, maka setiap pengguna di jaringan dapat menjadi root. Jadi teknik ini benar-benar bisa mengancam keamanan sistem. BO dapat menyerang hampir semua Operating System [4]. Beberapa serangan telah berhasil menembus sistem Windows NT dan Windows 2000. Keamanan dari sistem Windows NT dan UNIX mempunyai tingkat vulnerability yang sama dalam menghadapi serangan BO. 5. Solusi Ada berbagai cara yang digunakan untuk meningkatkan keamanan sistem dari serangan BO. Di bagian berikut akan dibahas beberapa diantaranya. 5. 1. Audit Kode Cara tradisional adalah mencari fungsi-fungsi yang tidak aman dalam library bahasa C, seperti strcpy( ), dan mengganti dengan fungsi yang memperhitungkan ukuran buffer, seperti strncpy( ) [4]. Audit manual seperti ini harus digunakan untuk setiap program, sehingga hal ini merupakan pendekatan yang sangat lama dan mahal. Tetapi bukan berarti bahwa cara ini tidak perlu ditempuh. Sudah ada beberapa cara yang secara sistematis mengaudit kode dan berhasil dengan baik, paling tidak untuk dua versi UNIX, yaitu OpenBSD dan Linux. Walaupun sudah terbukti berhasil baik, pendekatan ini belum menjamin bahwa suatu sistem operasi bebas dari serangan BO. Beberapa serangan BO ditemukan, walaupun sudah dilakukan audit kode.
17
Media Teknika Vol. 8 No. 1, Juni 2008: 13 – 19
5. 2. Mengawal Peluncuran Security Patches Cara tradisional yang kedua merupakan rekomendasi dari para spesialis keamanan agar administrator dari sistem mengikuti dengan dekat peluncuran suatu security patches oleh vendor, sehingga sesegera mungkin dapat di-install setelah diluncurkan [4]. Asumsi ini dapat menjadikan sistem lebih aman. Tetapi pendekatan ini mempunyai beberapa masalah. Masalah pertama adalah terlalu menyita waktu dan tenaga dari administrator. Banyak sistem yang ditangani bukan oleh rofesional yang khusus menjadi administrator, tetapi seseorang yang mempunyai pekerjaan utama lain. Jadi pendekatan ini tidak praktis. Selain dua cara tradisional di atas, ada tiga cara yang lebih murah, mudah diimplementasikan oleh setiap administrator yang tidak perlu bergantung pada vendor, dan efektif menangkal serangan BO. Karakteristik umum dari cara-cara ini adalah memberikan proteksi yang cukup baik walaupun dengan kode yang rentan (vulnerable). Kelebihan lain adalah bahwa cara-cara ini melakukan proteksi secara proaktif, tidak reaktif seperti cara yang dibahas sebelumnya. Proaktifitas ini memungkinkan administrator tidak perlu menunggu vendor untuk melakukan sesuatu terhadap sistemnya. Ketiga cara ini dibahas di bagian berikut. 5. 3. Disabling Stack Execution Kebanyakan sistem tidak membutuhkan kode yang selalu dapat dieksekusi di stack. Karena serangan BO pada umumnya mengandalkan kode yang dapat di-inject kedalam buffer dan kemudian mengeksekusinya, maka solusi sederhana adalah meng-install sistem operasi tanpa kemampuan eksekusi stack (stack execution disabled) [4]. Ide ini sederhana, murah, dan relatif efektif. Dilain pihak, ide ini juga mempunyai beberapa kelemahan yang serius. Pertama, walaupun jarang, beberapa program mengandalkan stack yang dapat dieksekusi. Hal lain yang lebih penting adalah bahwa pertahanan dari pendekatan ini lemah. Walaupun kode dalam crop of stack berbasis BO yang ada sering disimpan ke dalam buffer, refleksi sedikit saja akan memperlihatkan bahwa hal ini tidak esensial. Penyusup tidak peduli di mana kode penyusup berada. Yang dibutuhkan penyusup hanyalah kodenya dapat berada di manapun di memory dan alamat memory ini dapat diketahui oleh penyusup sehingga penyusup dapat melakukan overflow dari return address dan mengambil alih kendali. 5. 4. Safer C Library Support Alternatif yang lebih handal adalah jika tersedia versi yang aman dari fungsi-fungsi dalam library bahasa C [4]. Hal ini telah dipikirkan dan diimplementasikan untuk Unix versi FreeBSD. Grup Bell Labs mengimplementasikan fungsi-fungsi aman ini dalam library yang disebut LibSafe, yang dapat di-download dari web site resminya. Pada prinsipnya, LibSafe tidak mengganti library standar dari bahasa C. Metode yang digunakan adalah mencari fungsi yang aman yang ada di dalam LibSafe sebelum menggunakan fungsi yang ada dalam library standar bahasa C, dan menggunakannya. Teknik ini lebih fleksibel dari pada mengganti fungsi di dalam library bahasa C. LibSafe dapat di-install sebagai default library. Kelebihan dari teknik ini adalah efektif menangkal serangan BO yang berusaha melakukan stack smashing. Tetapi teknik ini tidak dapat mencegah BO secara total, karena teknik ini tidak tahu ukuran sebenarnya dari buffer. Overflow masih mungkin dilakukan di area di antara buffer dan dynamic link, tetapi return address dan dynamic link yang kritis dilindungi dari overwritting. Metode ini tidak memberikan proteksi untuk serangan BO berbasis heap atau
18
Damar Widjaja, Buffer Overflow, Ancaman …
serangan yang tidak memerlukan overwritting dari return address. Selain itu, metode ini juga tidak memberikan proteksi terhadap program yang tidak menggunakan fungs-fungsi yang ada di dalam library standar bahasa C. 5. 5. Teknik-teknik Compiler Pengujian range (range checking) akan memberikan pertahanan yang 100% efektif menangkal serangan BO. Sebagai contoh, serangan BO tidak mungkin dilakukan di program Java, karena Java secara otomatis mengecek batasan array index. Oleh karena itu beberapa peneliti telah mencoba mengimplementasikan teknik-teknik range checking dalam bahasa C [4]. Masih banyak teknik-teknik yang digunakan untuk menangkal serangan BO yang tidak dibahas daam tulisan ini. Tetapi setidaknya tulisan ini dapat memberi pemahaman umum tentang serangan BO dan bagaimana mengatasinya. 6. Kesimpulan Proses serangan BO yang tidak begitu rumit dan efektif untuk merusak sistem masih merupakan ancaman serius untuk beberapa dekade mendatang. Serangan BO telah mengancam sistem dengan berbagai sistem operasi. Proses serangan BO perlu dipahami sehingga pengembangan teknik-teknik anti serangan dapat semakin efektif, mudah dan murah. Daftar Pustaka [1] Eric Chien dan Péter Ször, 2002, Blended Attacks Exploits, Vulnerabilities and BufferOverflow Techniques in Computer Viruses, Virus Bulletin Conference., www.symantec.com, Oktober 2004 [2] Lawrence R Rogers, 2002, Buffer Overflows - What Are They and What Can I Do About Them?, Software Engineering Institute, Carnegie Mellon University [3] Crispin Cowan, Calton Pu, Dave Maier, Heather Hintony, Jonathan Walpole, Peat Bakke, Steve Beattie, Aaron Grier, PerryWagle and Qian Zhang, 1999, StackGuard: Automatic Adaptive Detection and Prevention of Buffer-Overflow Attacks, Department of Computer Science and Engineering, Oregon Graduate Institute of Science & Technology, http://cse.ogi.edu/DISC/projects/immunix, Oktober 2004 [4] Istvan Simon, 2001, Comparative Analysis of Methods of Defense against Buffer Overflow Attacks, California State University, http://www.mcs.csuhayward.edu/~simon/security/boflo.html, Oktober 2004 [5] David Larochelle dan David Evans, 2001, Statically Detecting Likely Buffer Overflow Vulnerabilities. Department of Computer Science, University of Virginia [6] Crispin Cowan, Perry Wagle, Calton Pu, Steve Beattie, and Jonathan Walpole, 1999, Buffer Overflows: Attacks and Defenses for the Vulnerability of the Decade. Department of Computer Science and Engineering, Oregon Graduate Institute of Science & Technology, http://cse.ogi.edu/DISC/projects/immunix, Oktober 2004 [7] __, 2002, Student Workbook – Module 8: Threat, Vurnabilities and Attack. CERT® Coordination Center, Software Engineering Institute, Carnegie Mellon University [8] Sandeep Grover, 2003, Buffer Overflow Attacks and Their Countermeasures. Linux Journal, www.linuxjournal.com , Oktober 2004
19