GNU/Linux >> Belajar Linux >  >> Linux

Cara Menghindari Serangan Stack Smashing dengan GCC

Stack smashing adalah istilah mewah yang digunakan untuk stack buffer overflows. Ini mengacu pada serangan yang mengeksploitasi bug dalam kode yang memungkinkan buffer overflows. Sebelumnya itu semata-mata tanggung jawab programmer/pengembang untuk memastikan bahwa tidak ada kemungkinan buffer overflow dalam kode mereka tetapi dengan waktu kompiler seperti gcc telah mendapat tanda untuk memastikan bahwa masalah buffer overflow tidak dieksploitasi oleh cracker untuk merusak sistem atau sebuah program.

Saya mengetahui tentang flag-flag ini ketika saya mencoba mereproduksi buffer overflow di Ubuntu 12.04 saya dengan versi gcc 4.6.3. Inilah yang saya coba lakukan :

#include <stdio.h>
#include <string.h>

int main(void)
{
    int len = 0;
    char str[10] = {0};

    printf("\n Enter the name \n");

    gets(str); // Used gets() to cause buffer overflow

    printf("\n len = [%d] \n", len);

    len  = strlen(str);
    printf("\n len of string entered is : [%d]\n", len);

    return 0;
}

Dalam kode di atas, saya telah menggunakan get() untuk menerima string dari pengguna. dan kemudian menghitung panjang string ini dan dicetak kembali di stdout. Idenya di sini adalah untuk memasukkan string yang panjangnya lebih dari 10 byte. Karena get() tidak memeriksa batas array sehingga ia akan mencoba menyalin input di buffer str dan dengan cara ini buffer overflow akan terjadi.

Inilah yang terjadi ketika saya menjalankan program:

$ ./stacksmash 

 Enter the name
TheGeekStuff

 len = [0] 

 len of string entered is : [12]
*** stack smashing detected ***: ./stacksmash terminated
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(__fortify_fail+0x45)[0xb76e4045]
/lib/i386-linux-gnu/libc.so.6(+0x103ffa)[0xb76e3ffa]
./stacksmash[0x8048548]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0xb75f94d3]
./stacksmash[0x8048401]
======= Memory map: ========
08048000-08049000 r-xp 00000000 08:06 528260     /home/himanshu/practice/stacksmash
08049000-0804a000 r--p 00000000 08:06 528260     /home/himanshu/practice/stacksmash
0804a000-0804b000 rw-p 00001000 08:06 528260     /home/himanshu/practice/stacksmash
0973a000-0975b000 rw-p 00000000 00:00 0          [heap]
b75af000-b75cb000 r-xp 00000000 08:06 787381     /lib/i386-linux-gnu/libgcc_s.so.1
b75cb000-b75cc000 r--p 0001b000 08:06 787381     /lib/i386-linux-gnu/libgcc_s.so.1
b75cc000-b75cd000 rw-p 0001c000 08:06 787381     /lib/i386-linux-gnu/libgcc_s.so.1
b75df000-b75e0000 rw-p 00000000 00:00 0
b75e0000-b7783000 r-xp 00000000 08:06 787152     /lib/i386-linux-gnu/libc-2.15.so
b7783000-b7784000 ---p 001a3000 08:06 787152     /lib/i386-linux-gnu/libc-2.15.so
b7784000-b7786000 r--p 001a3000 08:06 787152     /lib/i386-linux-gnu/libc-2.15.so
b7786000-b7787000 rw-p 001a5000 08:06 787152     /lib/i386-linux-gnu/libc-2.15.so
b7787000-b778a000 rw-p 00000000 00:00 0
b7799000-b779e000 rw-p 00000000 00:00 0
b779e000-b779f000 r-xp 00000000 00:00 0          [vdso]
b779f000-b77bf000 r-xp 00000000 08:06 794147     /lib/i386-linux-gnu/ld-2.15.so
b77bf000-b77c0000 r--p 0001f000 08:06 794147     /lib/i386-linux-gnu/ld-2.15.so
b77c0000-b77c1000 rw-p 00020000 08:06 794147     /lib/i386-linux-gnu/ld-2.15.so
bfaec000-bfb0d000 rw-p 00000000 00:00 0          [stack]
Aborted (core dumped)

Nah, ini merupakan kejutan yang menyenangkan bahwa lingkungan eksekusi entah bagaimana dapat mendeteksi bahwa buffer overflow bisa terjadi dalam kasus ini. Pada output Anda dapat melihat bahwa stack smashing terdeteksi. Hal ini mendorong saya untuk mengeksplorasi bagaimana buffer overflow terdeteksi.

Saat mencari alasannya, saya menemukan flag gcc '-fstack-protector'. Berikut adalah deskripsi dari flag ini (dari halaman manual) :

-fstack-protector

Keluarkan kode tambahan untuk memeriksa buffer overflows, seperti serangan stack smashing. Ini dilakukan dengan menambahkan variabel penjaga ke fungsi dengan objek yang rentan. Ini termasuk fungsi yang memanggil alloca, dan fungsi dengan buffer lebih besar dari 8 byte. Penjaga diinisialisasi saat fungsi dimasukkan dan kemudian diperiksa saat fungsi keluar. Jika pemeriksaan penjaga gagal, pesan kesalahan dicetak dan program keluar.

CATATAN:Di Ubuntu 6.10 dan versi yang lebih baru, opsi ini diaktifkan secara default untuk C, C++, ObjC, ObjC++, jika -fno-stack-protector, -nostdlib, atau -ffreestanding tidak ditemukan.

Jadi, Anda melihat bahwa gcc memiliki flag ini yang mengeluarkan kode tambahan untuk memeriksa buffer overflows. Sekarang pertanyaan berikutnya yang muncul di benak saya adalah saya tidak pernah menyertakan flag ini saat kompilasi lalu bagaimana fungsi ini diaktifkan. Kemudian saya membaca dua baris terakhir yang mengatakan untuk Ubuntu 6.10 fungsi ini diaktifkan secara default.

Kemudian, sebagai langkah selanjutnya, saya memutuskan untuk menonaktifkan fungsi ini dengan menggunakan tanda ‘-fno-stack-protector’ saat kompilasi dan kemudian mencoba menjalankan kasus penggunaan yang sama seperti yang saya lakukan sebelumnya.

Inilah cara saya melakukannya :

$ gcc -Wall -fno-stack-protector stacksmash.c -o stacksmash
$ ./stacksmash 

 Enter the name
TheGeekStuff

 len = [26214] 

 len of string entered is : [12]

Jadi kita melihat bahwa setelah kode dikompilasi dengan flag ini kemudian dengan input yang sama, lingkungan eksekusi tidak dapat mendeteksi buffer overflow yang sebenarnya terjadi dan merusak nilai variabel 'len'.

Selain itu, jika Anda baru mengenal gcc, Anda harus memahami opsi kompiler gcc yang paling sering digunakan yang telah kita bahas sebelumnya.


Linux
  1. Cara Menginstal WordPress dengan LAMP Stack di Ubuntu 16.04

  2. Cara Menginstal Magento 2.4 dengan LEMP Stack di Ubuntu 20.04

  3. Pelajari Cara Menghentikan Serangan XML-RPC Dengan .htaccess

  1. Cara Menginstal WordPress dengan LAMP Stack di Ubuntu 20.04

  2. Cara Menginstal dan Mengatur Stack MERN dengan Nginx di Ubuntu 20.04

  3. Cara Menginstal Mern Stack dengan Nginx di Debian 11

  1. Cara mengkompilasi biner 32-bit pada mesin linux 64-bit dengan gcc/cmake

  2. Bagaimana cara mendapatkan jejak tumpukan untuk C++ menggunakan gcc dengan informasi nomor baris?

  3. cara menginstal gcc 4.9.2 di RHEL 7.4