[LinuxFocus-icon]
<--  | Ana Sayfa  | Erişimdüzeni  | İçindekiler  | Arama

Duyumlar | Belgelikler | Bağlantılar | LF Nedir
Bu makalenin farklı dillerde bulunduğu adresler: English  Deutsch  Francais  Nederlands  Turkce  Polish  

[Photo of the Author]
Mulyadi Santosa
<a_mulyadi/at/softhome.net>

Yazar hakkında:

Adım Mulyadi Santosa. Indonesiya'da serbest yazar ve danışman olarak çalışıyorum. İlgi alanlarım, clustering, sistem güvenliği ve bilgisayar ağlarıdır. Bir de hazır clustering çözümleri sunan bir şirketim var. OpenMosix ve openSSI dikkatimi çeken projelerdendir. Boş zamanlarımında okumayı ve spor yapmayı seviyorum. Bu konularda sohbet etmek isterseniz bana yazabilirsiniz.



Türkçe'ye çeviri:
Erdal Mutlu <erdal(at)linuxfocus.org>

İçerik:

 

Syscalltracker ile Linux iç olaylarını izleme

[Illustration]

Özet:

Bazen Linux sistemimize daha yakından bakmak isteriz. Birçok çetele dosyalarını (log) inceleyen program, saldırı belirleme (instrusion detection) araçları, bütünlüğü (integrity) denetleyen araçlar vs programlar vardır. Ben size Linux'u çekirdek seviyesinde izleme olanağı sağlayan bir düzenekten sözedeceğim. Bu düzenek sayasinde, daha çok güvenirlik ve daha geniş olanaklara sahip olacaksınız.


_________________ _________________ _________________

 

Giriş

Günün birinde bir ileti listesinde clustering aracı konusunda konuşurken, rastlantı sonucu bir çekirdek yamasından dolayı sistemde oluşan bozuklukların tartışıldığı bir konu başlığı gözüme çarptı. Sonra birisi, sorunu yaşayan kişinin tarif ettiği şekilde aynı sorunu tekrar oluşturmaya çalıştığını yazdı. Bu kişi sorunu belirlemede Syscalltracker adında bir araç kullanıyordu. Ben de kendi kendime sordum: "Bu Syscalltracker nasıl bir araç acaba? Bununla neler yapılabilir?" Benim gibi bir kullanıcı için "Syscalltracker" adı pek bir şey ifade etmiyordu ve ben gizemli bir kuşkuya düştüm :-)

 

Syscalltracker

http://syscalltrack.sourceforge.net çekirdek modülleri topluluğu olup, Linux çekirdeği tarafından kullanılan sistem çağrılarının izlenmesi için kullanılmaktadır. Genellikle, sıradan hata belirleme araçları kullanarak ve çetele dosyalarına bakarak bulamayacağımız sistem hatalarını, bu araçla bulabiliriz. İşte bir örnek: Diyelim ki /etc dizininde yer alan inetd.conf (inetd servisinin yapılandırma dosyasıdır.) adında bir yapılandırma dosyanız var. Burada sisteminizde çalışması gereken bazı servisleri açtığınız ve çalışmaması gerekenleri iptal ettiniz. Daha sonra inetd servisini çalıştırdınız ve herşey yolunda gitti. Ancak, birden bire /etc/inetd.conf dosyası yokoldu. Şansınız vardı ve yedek dosyayı alıp yerine koydunuz. inetd tekrar çalıştırdığınızda, yapılandırma dosyanıza bilinmeyen bir servisi çalıştıran satırlar eklemiş olduğunu gördünüz. Şaşırdınız. "Bunu kim yapmış olabilir? "Bunu inetd tarafından çalıştırılmış bir servis mi yaptı acaba? Sistemin güvenliğini delen bir güvenlik açığı mı var?" Hızlıca sistem çetele dosyasına "cat" ile baktınız, "top" ve "ps" ile sisteminizde sıradışı programlar veya kullanıcıların varlığına baktınız. Ancak, hiç bir şey göremediniz.

Bu tür sorunları izlemik için bir yol var. %100 çözüm sağlayan bir yol değil, ama birçok durumda etkili olan bir yoldur. Bu yol veya çözümün temeli, kabuk ortamında çalıştırılan her komut veya servis, başka bir deyişle tüm süreçler sistem çağrıları (system calls) adı verilen, bilinen yordamları çalıştırmaları gerekmeleri esasına dayanmaktadır. Bir dosya mı silmek istiyorsunuz? O zaman unlink kullanıyorsunuz demektir. Kabuk programı mı çalıştırıyorsunuz? exec() veya execve() kullanıyor olmalısınız. Böylece sistemle ilgili tüm işlemler sonuçta bir veya birden fazla sistem çağrısı kullanımını gerektirmektedir. Böylece, sistem çağrılarını izleyecek yöntemin ne kadar güçlü bir silah olduğu ortaya çıkmaktadır.

 

İlginiz çekti mi?

Eğer, çektiyse bir deneme yapmakta fayda vardır. Bu yazıda ben işletim sistemi olarak RedHat 7.3'ü kullanmaktayım. İnternet tarayıcınızı kullanarak http://syscalltrack.sourceforge.net adresinin dosya indirme kısmından gerekli paketi elde edebilirsiniz. Bu yazıda ben syscaltrack-0.82.tar.gz sürümünü kullandım. Bu dosyanın yaklaşık büyüklüğü 500Kb idi. Paketi bir dizinde açın. Sözgelimi, bu dizin /usr/src olsun:

# tar xzvf syscalltrack-0.82.tar.gz

Ardından, /usr/src dizininde Linux çekirdek kaynaklarının bulunduğundan emin olun.

# rpm -qa | grep -i kernel-source

veya

# ls -al /usr/src/linux-2.4

Eğer, sisteminizde çekirdek kaynak dosyaları yüklenmemişse, RedHat'in 2. yükleme CD'sini kullanarak, gerekli paketi yüklemenız gerekecektir:

# rpm -replacepkgs -Uvh /path/to/your/RPM/kernel-source-2.4.18-3.i386.rpm

Syscaltracker'ı derlerken, sisteminizde hangi çekirdek sürümü ile yamaları kullanıyorsanız, aynısıyla derleme yapmanız gerektiğine özen gösteriniz. Sözgelimi, eğer RedHat 7.3 standart çekirdeğini kullanıyorsanız, RedHat CD'si ile birlikte gelen çekirdek kaynak kodlarını kullanmanız gerekecektir. Eğer, başka bir çekirdek sürümü kullanmak istiyorsanız, onun kaynak kodunu kullanarak derleme yapmanız gerekir.

Çekirdek kaynak kodunun yanısıra, Syscalltracker'ın derlenmesini kolaylaştırmak için RedHat'in çekirdek yapılandırma dosyasına sahip olmanızda fayda vardır. Bunun için /boot dizinine bakmanız gerekir:

# ls -al config*

Eğer, 'config-2.4.18-3' gibi bir dosya varsa, onu /usr/src/linux-2.4. dizini altına '.config' adı altında kopyalamalısınız:

# cp /boot/config-2.4.18-3 /usr/src/linux-2.4/.config

Eğer, bu dosya orada yoksa, çekirdek kaynak kodunun bulunduğu dizin içinde yer alan configs dizininden yapılandırma dosyasını elde edebilirsiniz. Kullanmanız gereken yapılandırma dosyasısı sisteminizde çalışan çekirdek ile uyumlu olmalıdır. Bunun için ilk önce

# uname -a

komutunu kullanarak, ne çalıştığına bir bakın. Komut çıktısı, o anda sisteminizde çalışan çekirdeğin sürüm numarasını göstermesi gerekir. Diyelim ki, elde edilen çıktı "kernel-2.4.18-3-i386", o zaman kernel-2.4.18-3-i386.config yapılandırma dosyasını almanız gerekecektir.

# cd /usr/src/linux-2.4
# cp configs/kernel-2.4.18-3-i386.config ./.config

Şimdi de aşağıdaki komutları çalıştırın:

# cd /usr/src/linux-2.4.18-3
# make mrproper
# make menuconfig

Gereksiniminize uygun ayarları yapıp, kaydedip çıkın. Eğer, çekirdeğinizi kendiniz derlediyseniz ve eski yapılandırma dosyasını kayıp ettiyseniz (Umarım etmemişsinizdir :-)), gerekli ayarları tekrar dikkatlice yapmalısınız.

 

Syscalltracker'ın derlenmesi

Şimdiye kadar gerekli olan herşeyi yerine getirdik. Artık, Syscalltracker'ın derlenmesine geçebiliriz:

# cd /usr/src/syscalltrack-0.82
# ./configure (veya ./configure -with-linux=/path/to/your/linux/kernel/source)
# make && make install

Eğer, derleme başarıyla sonuçlandıysa, iki adet yeni modül elde etmiş olacaksınız:

  1. /lib/modules/2.4.18-3/syscalltrack-0.82/sct_rules.o

  2. /lib/modules/2.4.18-3/syscalltrack-0.82/sct_hijack.o

Bu modüller sistem çağrılarını izlemeye yaramaktadır. Modülleri yazan kişi, sistem çağrılarını yakalama veya ele geçirme (system call hijacking) terimini kullanmaktadır. Bunun anlamı, asıl sistem çağrısından önce, önceden belirlenmiş bir yordamı çalıştırmaktır. Modülleri yüklemek için, root kullanıcısı olarak, Syscalltracker ile birlikte gelen aşağıdaki programı çalıştırabilirsiniz:

# sct_load

lsmod ile çekirdeğinizin modülleri yüklediğinden emin olun. Aşağıdakine benzer bir şey görmeniz gerekecektir:

Module     Size  Used by    Not tainted
sct_rules  257788   2
sct_hijack 110176   1      [sct_rules]
<…..cut………..>
 

Kurallar

Tebrikler! Modülleri yüklediniz, o zaman Syscalltracker çalışıyor demektir. Ancak bitmedi. Syscalltracker'ın birşeyler yapması için hala kurallar yazmanız gerekecektir. İsterseniz basit bir kural ile işe başlayalım:

rule
 {
   syscall_name=unlink
   rule_name=unlink_rule1
   action
   {
     type=LOG
     log_format {%comm : %params delete by %euid --> %suid}
   }
   when=before
}

Syscalltracker için tanımlanan her kural rule kelimesiyle başlamaktadır. Ardından "{" işareti gelmekte. Daha sonra, "syscall_name" parametresini kullanarak hangi sistem çağrısını izlemek istediğinizi belirtmeniz gerekir. Kullanabileceğiniz birçok sistem çağrısı vardır. Bunların listesini /usr/local/lib/syscalltrack-0.82/syscalls.dat-2.4.18-3 dosyasında bulabilirsiniz. Bazı sistem çağrı isimlerinin anlamını tahmin etmek zor olabilir. Şimdilik unlink()'i seçelim. Bu sistem çağrısı, birisi veya birşeyin herhangi bir şey silmek istediğinde kullanılmaktadır. Bence başlamak için iyi bir seçimdir. Böylece, amacımız sistemdeki silme işlemlerini izlemek olmuş oluyor.

"rule_name" parametresini kullanarak kurala bir isim vermeniz gerekecektir. İstediğiniz ismi verebilirsiniz. Anlamlı bir isim vermeniz yeterlidir. Ben "unlink_rule1" ismini verdim. "action" kısmına ise, Syscalltraker'ın bu sistem çağrısı çalıştırıldığında hangi işlemleri yerine getirmesi gerektiğini yazmanız gereklidir. Syscalltracker'ın desteklemiş olduğu çeşitli işlemler vardır. Biz burada LOG'u seçiyoruz. Buna göre çetele bilgileri /dev/log aygıtına yazılacaktır. Syscalltracker'ın internet sistesindeki yapılması düşünülenlerin listesinde, sistem çağrılarını yeniden yazma özelliğinin yapılacağı yazılmış. Buna göre, asıl sistem çağrısı parametrelerin değiştirilebileceği mümkün olacaktır:-)

LOG işlemi için çıktı biçimini belirtmeniz gerekecektir. Ayrıntılı bilgi elde edebilmek için, tanımlanmış makrolar vardır:

%ruleid -> kural adı
%sid    -> sistem çağrısı tanımlama numarası
%sname  -> sistem çağrısı adı
%params -> sistem çağrısı parametresi
%pid    -> sistem çağrısını kullanan sürecin numarası
%uid    -> kullanıcı numarası
%euid   -> etkin kullanıcı numarası
%suid   -> kayıt eden kullanıcı numarası
%gid    -> kullanıcı grup numarası
%egid   -> etkin grup numarası
%sgid   -> kayıt eden grup numarası
%comm   -> sistem çağrısını çalıştıran programın adı
%retval -> sadece LOG'un "after" değeri için
              çalışır ve sistem çağrısının dönüş değerini verir.

Örneğimiz için ben aşağıdakileri yazdım:

.log_format {%comm : %params delete by %euid --> %suid}

Bunun anlamı unlink sistem çağrısını kullanan her komutu kaydetmek istiyoruz demektir. Kayıt etme işlemi, etkin kullanıcı numarası (effective user id) ile kayıt edilen kullanıcı (recorded user id) numarasını da içermektedir.

when (ne zaman) parametresinde before (önce)" veya "after (sonra)" dan birini seçebiliriz. "before" seçildiğinde sistem çağrısını çalıştırmadan önce, "after" ise, sonra kayıt yapılmaktadır.

Kural "}" ile sona erdirilmektedir. Kuralı herhangi bir metin dosyasına yazabilirsiniz. Sözgelimi, dosyanın adı "try.conf" olsun ve /tmp dizininde bulunsun. Kuralı etkin kılmak için, Syscalltracker'a yüklemeniz gerekecektir.

# sct_config upload /tmp/try.conf

Eğer, kuralın yazımında yazım hatası yoksa, "Successfully uploaded rules from file '/tmp/try.conf' " mesajını elde edeceksiniz.

Tamam, şimdi deneme zamanı. X Pencere sisteminde iki adet xterm açın. Birinde Syscalltracker'ın çetele komutunu aşağıdaki gibi çalıştırın:

# sctlog

Kurala uygun bir sonuç ortaya çıktığında bu pencereden çetele biligisini görebileceksiniz. Diğer, xterm penceresinde aşağıdaki komutları çalıştırın:

# cd /tmp
# touch ./dummy
# rm ./dummy

Yukarıdaki kurala göre aşağıdakine benzer bir çıktı elde edeceksiniz:

"rm" : "./dummy" delete by 0 --> 0

Bu çıktıdan da anlaşıldığı gibi, "rm" komutu "./dummy" parametresiyle etkin kullanıcı nosu 0, yani root kullanıcısı tarafından çalıştırılımış olduğu ortaya çıkmaktadır. Bu komutun sonucunda da unlink() sistem çağrısı kullanılmıştır.

İste başka bir kural:

rule
{
   syscall_name = unlink
   rule_name = prevent_delete
   filter_expression {PARAMS[1]=="/etc/passwd" && UID == 0}
   action {
     type = FAIL
     error_code = -1
   }
   when = before
}

Bu, yukarıda tanımlanmış kurala benzemektedir. Ancak, bunun FAIL hareketi vardır. Bu hareket için, araya girilmiş sistem çağrısına dönüş değeri vermek gerekir. Ben burada işleme izin verilmediği anlamına gelen "-1" değerini verdim. Bu numaraların tam listesi /usr/include/asm/errno.h dosyasında yer almaktadır.

"filter expression"'ın yer aldığı satırda, ilgili sistem çağrısı çalıştırıldığında parametresi "/etc/passwd" değerine eşit olduğu koşulu tanımladım. Bu bölümde PARAMS değişkeni kullanıldı. Aslında her bölümün kendine özgü parametreleri vardır. Bir de, yapmış olduğum sağlama mükemmel değildir, çünkü birisi "cd /etc && rm -f ./passwd" komutlarını kullanabilir. O zaman benim kuralım bir işe yaramaz. Ama, biz deneme yaptığımızdan dolayı sorun değil. Ben ayrıca, bu kuralda kullanıcı numarasının (UID) 0'a eşit olması koşulunun sağlanmasını da aradım.

Kuralı önceki kuralın yer aldığı dosyaya ekleyin:

# sct_config delete
# sct_config upload /tmp/try.conf

Kuralların dosyadaki yazılış sıralarının önemli olduklarına dikkat edin. Eğer, "prevent_delete" kuralını "unlink_rule1 kuralından önce yazıp, aşağıdaki komutu çalıştırırsanız:

# rm -f /etc/passwd

"prevent_delete" devreye girecek ve tüm hareket iptal olacak ve "unlink_rule1" dikkate alınmayacaktır. Eğer, tersini yaparsanız, çetele bilgisini elde edeceksiniz, ancak dosyayı silmekten kurtaramayacaksınız!

Gözlem yapılabilecek diğer ilginç bir sistem çağırsı da ptrace dir. "man ptrace" sayfasından da anlaşıldığı gibi, bu sistem çağrısı, bir programın çalışmasının denetlemeye ve gözlemlemeye yaramaktadır. İyi ellerde, ptrace çok güzel bir hata belirleme aracı olabilir. Ancak, kötü ellere düşerse, sistemin güvenlik açıklarını belirleme ve güvenliğini kırmaya yarayabilir. Öyleyse, bunu izleyecek bir kural oluşturalım:

rule
{
    syscall_name=ptrace
    rule_name=ptrace_rule1
    action {
        type=LOG
      log_format {%comm : %params issued ptrace by %euid --> %suid}
  }
    when=before
}

Kuralı denemek için strace programını kullanmalıyız. İlk önce yukarıdaki kuralı Syscalltracker'a yüklememiz gerekir. Daha sonra sctlog programını bir yerde çalıştırıp, başka bir yerde de strace'i çalıştırın:

# strace /bin/ls

sctlog, aşağıdakilere benzer birkaç satır görüntüleyecektir:

"strace" : 3, 2019, 24, -1073748200 issued ptrace   by 0 --> 0
"strace" : 24, 2019, 1, 0 issued ptrace   by 0 --> 0
"strace" : 3, 2019, 44, -1073748200 issued ptrace   by 0 --> 0
"strace" : 3, 2019, 24, -1073748200 issued ptrace   by 0 --> 0
"strace" : 3, 2019, 0, -1073748216 issued ptrace   by 0 --> 0
"strace" : 7, 2019, 1, 0 issued ptrace   by 0 --> 0

Strace programını bilmeyenler için söylyorum. Bu program başka programların kullandıkları sistem çağrılarını izlemeye yaramaktadır ve çok güçlü bir araçtır. Strace kendi içinde başka programları izleyebilmek için ptrace'i kullanmaktadır. Syscalltracker, strace ile birlikte dosya ve sistem olaylarını izlemek için ideal bir ikili oluşturmaktadır. Bence bunlardan sözetmek yerinde oldu. Strace, Redhat'in 7.3/8/9 sürümleriyle birlikte gelmektedir. Yapmanız gerek ilgili RPM dosyasını yüklemektir (Redhat 7.3 için):

# rpm -Uvh /path/to/your/Redhat/RPM/strace-4.4-4.i386.rpm

Şimdi, sistem incileme konusunda bir adım daha ilerlemiş oldunuz. Syscalltracker, sistem çağrıları hakkında birçok bilgiye erişme olanağının yanısıra, kullanıcılara birçok esneklik de sağlamaktadır. Son olarak, yüklenmiş olan kuralları görüntülemek isterseniz:

# sct_config download

Yüklenmiş tüm kuralları silmek için:

# sct_config delete

komutunu çalıştırmalısınız. Syscalltracker'ı kullanmak istemediğinizde, geçici bellekten onu silmek için aşağıdaki komutu çalıştırın:

# sct_unload


Bir olasılık, Syscalltracker'ı bellekten silerken "Device or resource busy" mesajını alabilir ve silemezsiniz. Büyük bir olasılıkla Syscalltracker o anda çalışmaktadır. Bu yüzden biraz bekledikten sonra tekrar deneyin. Eğer, çok fazla kural eklemezseniz, Syscalltracker sisteminize çok yük oluşturmaz. Sonuç olarak şunu söyleyebilirim: Bırakın Syscalltracker çekirdekle birlikte çalışsın ve sizde böylece sisteminizi daha yakından izleme olanağı elde etmiş olursunuz.  

Bu yazı için görüş bildiriminde bulunabilirsiniz

Her yazı kendi görüş bildirim sayfasına sahiptir. Bu sayfaya yorumlarınızı yazabilir ve diğer okuyucuların yorumlarına bakabilirsiniz.
 talkback page 

<--, Bu sayının ana sayfasına gider

Görselyöre sayfalarının bakımı, LinuxFocus Editörleri tarafından yapılmaktadır
© Mulyadi Santosa, FDL
LinuxFocus.org
Çeviri bilgisi:
de --> -- : Mulyadi Santosa <a_mulyadi/at/softhome.net>
en --> tr: Erdal Mutlu <erdal(at)linuxfocus.org>

2003-12-26, generated by lfparser version 2.45