Dosya Listeleme
Muhtemelen bir Unix / Linux sistem üzerinde en çok kullanılan komutlardan birisi “ls” komutudur.Diğer komutlar gibi “ls” komutunun da pek çok switch’i var. Bazıları diğerlerinden daha çok ihtiyaç duyacağınız switch’ler. Bunlardan birisi “-a” switch’i (“all” kelimesinin ilk harfi).
“-a” switch’i isminin başında “.” olan dosya ve dizinlerin de listelenmesini sağladı. Bu dosyalardan bazıları daha önceden bahsi geçen startup script’leri, çünkü şu anda “root” kullanıcısının “home” dizinindeyiz. Hangi dizinin içinde olduğumuzu “pwd” yani “present working directory” komutu ile görebiliriz.
Adı “.” ile başlayan dosyalardan birisi de “.bash_history” dosyası. Bu dosyaya daha sonra değineceğiz.
Dosya Adı Tamamlama
Shell ortamının sağladığı imkanlardan birisi de dosya adı tamamlama imkanıdır. Herhangi bir komuta parametre olarak dosya ismi vereceğimiz zaman dosya adının bir veya daha fazla karakterini yazdıktan sonra tab tuşuna basarak dosya adının tamamlanması için destek alabiliriz.
Yukarıdaki örnekte dosya isminin ilk karakteri olarak “d” karakterini girdikten sonra “tab” tuşuna birinci basışımızda herhangi bir tamamlama yapmadı. Bunun anlamı adı “d” ile başlayan birden fazla dosya veya dizin adı bulunduğudur. Bu nedenle tekrar “tab” tuşuna bastığımızda olası tüm ihtimalleri bize gösterdi. Bunu yaparken adı “d” ile başlayanlardan birisinin bir dizin olduğunu da sonuna “/” karakterini ekleyerek belirtti. Bu aşamadan sonra “d” karakterinden sonra “o” karakterini de yazdım ve “tab” tuşuna bastım. Bu durumda tek alternatif olduğundan shell dosyanın adını tamamladı.
Dosya Erişim Hakları
Bir başka “ls” switch’i de “-l” yani “long listing format” switch’idir.
“-l” switch’i gördüğünüz gibi her bir dosya için daha detaylı bilgiler sağlıyor. Bunlar arasında en kayda değer olanları dosya / dizin erişim hakları, dosyanın sahibi olan kullanıcı adı, dosyanın sahibi olan grup adı, dosyanın boyutu (byte cinsinden) ve dosyanın son güncellenme zamanı sayılabilir.
Dosya / dizin erişim haklarının bulunduğu bölümün başında özel erişim bayrağı (special permission flag) bulunur.
[-] [rwx] [rwx] [rwx]
Bu ilk bölümde bulunabilecek tüm opsiyonlara farklı bir kaynaktan ulaşabilirsiniz. Ancak burada sadece sıklıkla karşılaşılan opsiyonlara değineceğim:
- “-“ karakteri dosyanın rutin bir dosya olduğuna işaret eder.
- “d” karakteri ilgili ismin bir dizin ismi olduğunu belirtir.
- “l” dosyanın aslında farklı bir dosyanın sembolik linki olduğunu belirtir. Bu konuyu aşağıda açıklayacağız.
Sembolik link örneği için öncelikle bir sembolik link oluşturuyoruz. Bu örnekte bulunduğumuz dizin altında oluşturduğumuz bizim-passwd.txt dosyasını /etc/passwd dosyasına bir sembolik link olarak tanımlıyoruz.
Sembolik link dosyamızın özelliklerine göz attığımızda ilk karakterin “l” olduğunu görebiliriz. Sembolik link dosyamızın içeriğine göz attığımızda orijinal passwd dosyasının içeriğini görüyoruz. Sembolik link aslında tahmin edebileceğiniz gibi yeni bir dosya oluşmasına neden olmuyor, teknik olarak ilgili dizin hiyerarşisi içinde yeni bir inode veri yapısı oluşuyor ve bu veri yapısı da orijinal dosyaya işaret ediyor. Sembolik link ile dosyaya erişerek içeriğinde güncelleme yapabiliriz, ancak sembolik linki sildiğinizde orijinal dosya silinmez.
Dosya erişim izinleri 3 farklı grup için verilir:
- Dosya sahibi kullanıcı (u - owner)
- Grup (g - group)
- Diğer (tüm) kullanıcılar (o - others)
- Okuma (r - read): Dosyalar için dosyanın içeriğinin görülebilmesi, dizinler için dizin içeriğinin listelenmesi anlamına gelir.
- Yazma (w - write): Dosyalar için dosya içeriğinin değiştirilebilmesi, dizinler için dizin içinde dosya oluşturma, dizin içindeki dosyaların adını değiştirme, dizin içindeki dosyaları silme ve dizin özelliklerini (attributes) değiştirebilme anlamına gelir.
- Çalıştırma (x - execute): Dosyalar için dosyanın (derlenmiş kod dosyası veya script dosyası) çalıştırılabilmesi, dizinler için dizine giriş, dizinin içindeki dosya ve dizinlere erişim hakkı anlamına gelir.
Görüldüğü gibi “passwd” komutu dosyasında dosya sahibi (u) alanındaki çalıştırma hakkı “s” olarak görülüyor. Bu mantıklı çünkü her sistem kullanıcının parolasını değiştirebilmesi gerekir, ancak bu /etc/passwd dosyasında değişiklik yapabilmek anlamına gelir ki bu hak yine yukarıda görülebileceği gibi sadece root kullanıcısına aittir.
Setuid / setguid hakkına sahip dosyalar güvenlik denetimlerinde özellikle incelenir, çünkü bu uygulamalar yüksek erişim hakkına sahip olduklarından düşük kullanıcı hakkına sahip kullanıcılar tarafından kötüye kullanılabilirler. Ayrıca bu uygulamalardaki bir açıklık yüksek kullanıcı haklarının herhangi bir işlem gerçekleştirilebilmesine de olanak tanıyabilir.
Dosya / Dizin Erişim Haklarının Düzenlenmesi
Erişim haklarının düzenlenmesi için kullanılan araç “chmod” uygulamasıdır. Erişim haklarının düzenlenmesinde aşağıdaki 2 yöntemden birisi tercih edilebilir:
- Numerik: Bu yöntemde dosya sahibi (user), grup (group) ve diğer kullanıcılar (others) için haklar tek seferde tanımlanmalıdır.
- Sembolik (alfabetik karakterlerle): Bu yöntemde istenilen profile (yani user, group ve/veya others’a) istenilen hak (yani read, write ve/veya execute) verilebilir veya çıkarılabilir.
“touch” komutu ile “dosya” isimli bir dosya oluşturduk ve bu dosyanın erişim haklarını gözlemledik. “touch” komutu ile büyüklüğü 0 olan bir dosya oluşturabiliriz veya var olan bir dosyayı “touch” komutuna parametre olarak vererek bu dosyanın son erişim tarihini mevcut zamanla güncelleriz. Çok kullanışlı gibi görünmese de bir shell script’in içinde hızlıca bir dosya oluşturmak için veya dosya erişim zamanlarına bakan bir uygulama için işimize yarayabilir.
Erişim haklarına baktığımızda aşağıdaki erişim haklarını görüyoruz:
- User (owner): read, write
- Group: read
- Others: read
“umask” komutu ise “0022” gibi bir değer üretti. Öntanımlı erişim hakları ile umask komutunun çıktısı birbirleri ile ilişkili.
“umask” değeri yine “umask” komutu ile belirlenebilir. Startup script’leri içinde bu komutu bulamadım, ama /etc dizini altında login.defs dosyası içinde bu değeri görebiliriz, dolayısıyla tahminen tüm kullanıcılar için bu değer umask değeri olarak atanıyor. Peki bu değer ne anlama geliyor?
“umask” değeri öntanımlı baz erişim hakları ile bitwise NOT işlemine tabi tutularak yeni oluşturulacak dosyanın erişim hakları belirlenir. Baz erişim hakları şu şekilde hesaplanabilir (dosyalar için):
- Read: 4
- Write: 2
- Execute: 1
Unix / linux sistemlerde öntanımlı dosya baz erişim hakları 666, öntanımlı dizin erişim hakları ise 777’dir. Kernel yeni bir dosya oluşturulurken bu değeri alır ve umask değerini bu değerden çıkararak dosya ve dizin erişim haklarını belirler. Eğer Kali ve root kullanıcısı için bu hesaplamayı yaparsak:
- Dosya için: 666 – 022 = 644, yani “- r w - r - - r - -“
- Dizin için: 777 – 022 = 755, yani “d r w x r - x r - x”
Dikkatli okuyucu farketmiş olabilir, “ls” komutunu çalıştırırken “-l” switchinin yanına bir de “d” switch’ini ekledik. Bunun nedeni “dizin” dizininin içeriğini değil dizin erişim haklarını görüntülemek istediğimiz içindi. Eğer sadece “-l” switchini kullanırsak “ls” komutu dizinin içeriğini görüntülemeye çalışıyor.
Şimdi yeni oluşturduğumuz dosyamızın erişim haklarını biraz düzenleyelim.
Yukarıda “chmod” komutunun çeşitli kullanım örneklerini görüyorsunuz. İlk kullanımda sembolik yöntemle group’a yazma (w) hakkını ekliyoruz.
İkinci kullanımda others’a okuma ve yazma haklarını atıyoruz (rw).
Üçüncü kullanımda others’dan yazma hakkını (w) çıkarıyoruz.
Sembolik yöntemde eğer kullanıcıya ilişkin bir bilgi yoksa atama tüm kullanıcılar için yapılır. Örneğin “chmod +w dosya” komutu user, group ve others kategorilerinin hepsi için bu atamayı yapar.
Dördüncü kullanımda numerik yöntemle erişim haklarını atıyoruz. Bu örnekte ayrıca ilk defa executable (x) hakkı da ekledik. Linux’un (ya da Unix’in) Windows’dan kullanıcı açısından temel farklarından birisi de dosya uzantılarının bir anlam taşımamasıdır. Bir dosyanın çalıştırılabilir olup olmadığı o dosyaya executable hakkının atanıp atanmadığı ile ilgilidir. Bu bir elf formatındaki çalıştırılabilir dosya da olabilir, bir shell script dosyası da. Tabi buradaki dosyamızın içinde çalıştırılabilir bir içerik bulunmamaktadır. Ancak listelediğimizde çalıştırılabilir bir dosya gibi görünmektedir.
Dosya Sistemi Navigasyonu
Temel bir bilgi olmakla birlikte dosya sistemi (file system) içinde temel navigasyon işlemlerine de değinmemizde fayda var.
“cd” (change directory) komutu adından da anlaşılabileceği gibi içinde bulunulan dizini değiştirmek için kullanılan bir komut. Yukarıdaki örnekte içinde bulunduğumuz dizinin altında bulunan bir dizine geçiyoruz. Bir sonraki adımda ise “..” karakterlerini kullanarak 2 üst dizine çıkıyoruz.
Herhangi bir dosya adını işaret ederken 2 tür işaret etme imkanımız bulunmaktadır:
- Relative (göreli) dosya adı ile işaret etme
- Absolute (tam) dosya adı ile işaret etme
Yukarıdaki örneklerde içinde bulunduğumuz dizine göreli (relative) olarak belli dosyalara işaret ediyor ve içeriklerini inceliyoruz. Birinci örnekte “/etc” dizini içindeyken bu dizinin altında bulunan “cron.d” dizini içinde yer alan “anacron” dosyasının içine göz atıyoruz. Daha sonra “cd” komutuna yine relative olarak “cron.d” dizinini parametre olarak veriyoruz ve bu dizine geçtikten sonra üst dizinde (yani /etc dizininin içinde) bulunan bir dosyanın içeriğine göz atıyoruz.
Yukarıdaki örnekte ise “/etc” dizini altında bulunan “hosts” dosyasının içeriğine “/root” dizininin altından göz atabilmek için absolute path yöntemini kullanıyoruz.
“cd” komutunun sık kullanılan imkanlarından birisi de dizin ismi yazmadan kullanıcının HOME dizinine hızlıca dönmesini sağlamasıdır. Bunu yapmak için herhangi bir parametre vermeden sadece “cd” komutunu işletmemiz yeterlidir.
HOME dizini shell ortamında startup script’lerini barındırması, kullanıcının shell tarihçesinin bulunduğu dosyayı barındırması ve kullanıcının login olduğunda ilk düştüğü dizin olması gibi çeşitli nedenlerden dolayı kullanıcılar için önemli bir dizindir. Bu yüzden dosya erişimleri ile ilgili işlemlerde pratik biçimde HOME dizine işaret edebilmek için tilda yani “~” işareti kullanılır.
Yukarıdaki örnekte dizinimizi “/etc” dizini olarak değiştiriyoruz ve bu dizinin altındayken sadece tilda işaretini kullanarak HOME dizinimiz altındaki dosyaları listeleyebiliyoruz.
Linux’ta bir dizin oluşturmak için “mkdir” komutunu kullanıyoruz. Dizin silmek içinse dosyalar için de kullandığımız “rm” komutunu kullanıyoruz, yalnız bir farkla. Linux bizi silmek istediğimiz şeyin bir dosya değil bir dizin olduğu hakkında uyarıyor. Bir dizini silebilmek için “rm” komutunu “-r” switch’i ile birlikte kullanmamız gerekiyor.
Dosya manipülasyonu ile ilgili temel işlemlerden birisi de dosya kopyalama işlemi “cp” komutu ile yapılıyor. Dosya isminin basit bir biçimde değiştirilmesi ile ilgili komut “mv” yani “move” komutu. “rename” komutu ise bir perl deyimi ile dosya isim değişikliği için kullanılıyor. “rm” komutu da tahmin edilebileceği dosya silmek için kullanılıyor.
Dosya Arama
Shell ortamında önemli olan bir başka konu da bir çalıştırılabilir dosyanın ismi yazılarak çalıştırıldığında aslında hangi dosyanın çalıştırıldığı konusudur. Windows’a benzer şekilde Linux’ta da bir PATH çevresel değişkeni bulunmaktadır. Bu değişken startup script’leri ile her kullanıcı için atanır.
Linux’ta PATH değişkenini diğer lokal veya çevresel diğer değişkenleri görüntülediğimiz gibi görüntüleyebiliriz.
Bir başka yöntem de “env” gibi bir komutla tüm çevresel değişkenleri listeleyerek içinde PATH kelimesi geçenleri listelemek olabilir.
Biz herhangi bir komut çalıştırdığımızda (örneğin “ls” komutu) bu komut PATH çevresel değişkeni içindeki dizinler içinde bu değişkende belirtilen sırayla aranır ve ilk bulunan çalıştırılabilir komut dosyası çalıştırılır. Herhangi bir komut çalıştırdığımızda bu komutun aslında hangi dizin altında bulunduğunu “which” komutuyla inceleyebiliriz.
PATH çevresel değişkeni içinde aranan isimdeki tüm çalıştırılabilir dosyaları tespit etmek için “-a” switch’ini kullanabiliriz.
PATH çevresel değişkeni ve “root” kullanıcısı ile ilgili bahse değer bir başka konu da “.” yani mevcut dizin konusudur. Normalde sıradan Unix / Linux kullanıcılarının PATH çevresel değişkeninin içinde “.”, yani mevcut dizin bulunur. Buna göre örneğin bir shell script çalıştırılacağı zaman shell’de içinde bulunulan dizin içinde de bu script aranır. Unix’in ilk dönemlerinde yaşanan bazı sosyal mühendislik saldırıları nedeniyle bu dizin öntanımlı olarka “root” kullanıcılarının PATH değişkeni içinde yer almaz. Unix bildiğiniz gibi çok kullanıcılı bir sistem (her ne kadar Kali böyle bir amaç için hazırlanmamış olsa da). Böyle bir sistem üzerinde çalışan kullanıcılar yardım amacı ile sistem yöneticisini yanlarına çağırdıklarında sistem yöneticisi kendi kullanıcısına geçmek için “su”, yani switch user komutunu kullanır. Ancak shell ortamına kendisi interaktif logon olarak giriş yapmadığı için halen kendisini çağıran kullanıcının içinde bulunduğu dizinde bulunmaya devam etmektedir. Eğer sistem yöneticisini çağıran kullanıcı “ls” komutu ile aynı ismi taşıyan bir shell script yazmış ve bu dizinin içine yerleştirmiş ise ve “root” kullanıcısının PATH çevresel değişkeni içinde “.” var ve “/bin” dizininden önce geçiyorsa o zaman çağıran kullanıcının yazdığı script “root” kullanıcı hakları ile çalışır. İşte bu basit saldırı nedeniyle öntanımlı olarak “.” dizini “root” kullanıcısının PATH değişkeni içinde bulunmaz.
PATH değişkeni mevcut dizini işaret etmediği için “root” kullanıcısıyla kendi dizininizdeki bir uygulama veya script’i çalıştırmak istediğinizde dosya adının başına “./” karakterlerini koymanız gerekir.
Bir başka dosya bulma komutu da “locate” komutudur. Bu komut “which” komutu gibi ne çalıştırılabilir dosyalara özeldir ne de sadece PATH değişkeninde geçen dizinleri arar. “locate” komutu bir veritabanı içinde dosya isimlerini arar. Bu veritabanı bir “cron” işiyle periyodik olarak güncellenir. “cron” ve zamanlı işler konusuna daha sonra değineceğiz. Eğer veritabanını manuel olarak güncellemek isterseniz “updatedb” komutuyla da bu işlemi yapabilirsiniz.
“locate” komutu bir veritabanı kullandığı için çok hızlı yanıt döndürür. Yukarıda “updatedb” komutunun güncellediği veritabanı dosyasının adını ve bulunduğu dizini de görebilirsiniz.
Bir başka dosya bulma komutu da “find” komutudur. Bu komut her çalıştığında hedef dizinleri tarayarak dosya ismini arar.
“find” komutunun bir özelliği de eğer bir isim hedefi verilmemişse hedef dizinin içindeki tüm dizinler ve bu dizinlerin içindeki tüm dosyaların isimlerini listeler. Bu özellik “find” komutunun arşiv komutları ile birlikte kullanılmasını da sağlamaktadır (arşiv işlemlerine daha sonra değineceğiz).
<<Önceki Bölüm Sonraki Bölüm>>