SUID, SGID ve Sticky Bit: Linux’ta Güvenlik Riskleri ve Denetimi
Linux sistemlerinde dosya izinleri deyince çoğu sysadmin aklına hemen rwx kombinasyonları gelir. Ama işin içinde öyle bir katman daha var ki, yanlış yapılandırıldığında bir saldırganın elinde sistemin anahtarlarını teslim edebilirsin: SUID, SGID ve Sticky Bit. Bu üç özel izin biti, Linux’un güç mekanizmalarından biri olduğu kadar, ihmal edildiğinde ciddi bir güvenlik deliği de açabilir. Bugün bu bitlerin ne işe yaradığını, nasıl kötüye kullanılabileceğini ve bir sysadmin olarak nasıl denetim yapman gerektiğini ele alacağız.
SUID, SGID ve Sticky Bit Nedir?
Önce temelden gidelim. Linux dosya sistemi üç tane “özel” izin biti sunar. Bunlar normal okuma/yazma/çalıştırma izinlerinin üstüne eklenir.
SUID (Set User ID): Bir çalıştırılabilir dosyaya SUID biti atandığında, o program kim tarafından çalıştırılırsa çalıştırılsın, dosyanın sahibinin yetkileriyle çalışır. Klasik örnek /usr/bin/passwd komutudur. Normal bir kullanıcı kendi şifresini değiştirebilmek için /etc/shadow dosyasına yazması gerekir. Bu dosya sadece root tarafından yazılabilir. passwd üzerindeki SUID biti sayesinde program geçici olarak root yetkileriyle çalışır ve işi tamamlar.
SGID (Set Group ID): SUID’in grup versiyonu diyebiliriz. Dosyalarda uygulandığında, program dosyanın sahibi olan grubun yetkileriyle çalışır. Dizinlerde uygulandığında ise o dizin içinde oluşturulan tüm dosyalar, oluşturan kullanıcının birincil grubu yerine dizinin grubunu miras alır. Bu özellikle paylaşımlı proje dizinlerinde çok kullanışlıdır.
Sticky Bit: Eskiden bellek yönetimiyle ilgiliydi ama modern Linux’ta dizinlerde anlam taşır. Sticky Bit atanmış bir dizinde (örneğin /tmp), her kullanıcı kendi dosyalarını silebilir ama başkasının dosyasına dokunamaz. Bir nevi “herkes yazar ama sadece sahibi siler” politikası.
Sayısal ve Sembolik Gösterim
Bu bitlerin dosya izinlerindeki gösterimi biraz kafaları karıştırabilir. Sayısal sistemde şöyle çalışır:
- SUID: 4 (4000)
- SGID: 2 (2000)
- Sticky Bit: 1 (1000)
Yani bir dosyaya SUID + normal 755 izni vermek istiyorsan:
chmod 4755 /path/to/file
chmod u+s /path/to/file # Sembolik yol
SGID için:
chmod 2755 /path/to/directory
chmod g+s /path/to/directory
Sticky Bit için:
chmod 1777 /tmp
chmod +t /tmp
ls -la çıktısında bu bitleri şöyle görürsün:
ls -la /usr/bin/passwd /tmp /usr/bin/wall
# -rwsr-xr-x (SUID: owner execute pozisyonunda 's')
# drwxrwxrwt (Sticky: other execute pozisyonunda 't')
# -rwxr-sr-x (SGID: group execute pozisyonunda 's')
Eğer execute biti yokken bu özel bitler atanırsa küçük ‘s’ yerine büyük ‘S’ görürsün. Bu genellikle yanlış yapılandırma işaretidir.
Güvenlik Riskleri: İşler Nasıl Ters Gider?
SUID Riski: Privilege Escalation
SUID’in en kritik riski şu: Eğer root’a ait ve SUID bitli bir program çalıştırılabilirse, o program üzerinden kabuk açmak mümkünse, sistem ele geçirilmiş demektir.
Gerçek dünya senaryosu düşün: Bir geliştirici takımı, kendi yazdığı bir backup script’ini root’a ait ve SUID bitli olarak bırakmış. Script içinde güvenli olmayan bir komut çağrısı var veya PATH manipülasyonuna açık. Saldırgan bu açığı kullanarak root shell alabilir.
GTFOBins (https://gtfobins.github.io) sitesi tam da bu yüzden var. SUID bitli find, vim, python, bash gibi programların nasıl privilege escalation için kullanılabileceğini belgeler. Örneğin SUID bitli find varsa:
# Eğer /usr/bin/find SUID root ise:
find . -exec /bin/sh -p ; -quit
# Bu komut root shell verir
Ya da SUID bitli python3 varsa:
python3 -c 'import os; os.execl("/bin/sh", "sh", "-p")'
SGID Riski: Grup Bazlı Erişim İhlali
SGID, özellikle yanlış yapılandırılmış grup izinleriyle birleşince tehlikeli olabilir. Örneğin docker grubuna üye olan bir kullanıcı, SGID bitli bazı araçlar üzerinden sistem dosyalarına erişebilir.
Dizinlerde SGID kullanımında da dikkat gerekir. Paylaşımlı bir dizin SGID ile ayarlanmışsa ve grup izinleri çok genişse, grup üyeleri birbirlerinin dosyalarını okuyup değiştirebilir.
Sticky Bit Eksikliği: Dosya Silme Kaosı
/tmp dizininde sticky bit olmadığını düşün. Sisteme giriş yapan herhangi bir kullanıcı diğerlerinin geçici dosyalarını silebilir. Bu hem veri kaybına hem de servis kesintisine yol açabilir. Uygulama geçici dosyalarına dayanan servisler bozulabilir.
Sistemdeki SUID/SGID Dosyaları Tespit Etmek
Bir sysadmin olarak periyodik denetim şart. İlk yapman gereken şey sistemdeki tüm SUID ve SGID dosyaları listelemek:
# Tüm SUID dosyaları bul
find / -perm -4000 -type f 2>/dev/null
# Tüm SGID dosyaları bul
find / -perm -2000 -type f 2>/dev/null
# Her ikisini de bul
find / -perm /6000 -type f 2>/dev/null
# Daha detaylı çıktı için ls formatında
find / -perm /6000 -type f -exec ls -la {} ; 2>/dev/null
Bu komutları çalıştırdığında muhtemelen uzun bir liste göreceksin. Önemli olan bu listenin beklenen haliyle karşılaştırmak. Bunun için bir baseline oluşturman gerekiyor.
Baseline Oluşturma ve Karşılaştırma
Temiz bir sistemde, kurulumdan hemen sonra bir baseline al ve sakla:
# Baseline dosyası oluştur
find / -perm /6000 -type f -exec ls -la {} ; 2>/dev/null | sort > /root/suid_sgid_baseline_$(date +%Y%m%d).txt
# Sticky bit'li dizinleri de kaydet
find / -perm -1000 -type d 2>/dev/null | sort >> /root/sticky_baseline_$(date +%Y%m%d).txt
Sonraki denetimlerde baseline ile karşılaştır:
# Yeni tarama yap
find / -perm /6000 -type f -exec ls -la {} ; 2>/dev/null | sort > /tmp/suid_current.txt
# Farkları göster
diff /root/suid_sgid_baseline_20240101.txt /tmp/suid_current.txt
Baseline’da olmayan bir satır görürsen, o dosya sonradan SUID/SGID bit almış demektir. Bu ciddi bir uyarı işareti.
Otomatik Denetim Script’i
İşte günlük veya haftalık çalıştırabileceğin basit bir denetim script’i:
#!/bin/bash
# suid_audit.sh - SUID/SGID Denetim Script'i
BASELINE="/root/security/suid_baseline.txt"
CURRENT="/tmp/suid_current_$(date +%Y%m%d_%H%M%S).txt"
REPORT="/var/log/suid_audit_$(date +%Y%m%d).log"
EMAIL="[email protected]"
echo "=== SUID/SGID Denetim Raporu ===" > $REPORT
echo "Tarih: $(date)" >> $REPORT
echo "" >> $REPORT
# Mevcut durumu tara
find / -perm /6000 -type f -exec ls -la {} ; 2>/dev/null | sort > $CURRENT
# Baseline yoksa oluştur
if [ ! -f "$BASELINE" ]; then
echo "[UYARI] Baseline bulunamadi. Yeni baseline olusturuluyor..." >> $REPORT
cp $CURRENT $BASELINE
echo "Baseline olusturuldu: $BASELINE" >> $REPORT
exit 0
fi
# Karşılaştır
NEW_FILES=$(diff $BASELINE $CURRENT | grep "^>" | awk '{print $NF}')
REMOVED_FILES=$(diff $BASELINE $CURRENT | grep "^<" | awk '{print $NF}')
if [ -n "$NEW_FILES" ]; then
echo "[KRITIK] Yeni SUID/SGID dosyalar tespit edildi:" >> $REPORT
echo "$NEW_FILES" >> $REPORT
# Mail gonder
mail -s "KRITIK: Yeni SUID/SGID Dosya Tespit Edildi" $EMAIL < $REPORT
fi
if [ -n "$REMOVED_FILES" ]; then
echo "[BILGI] Kaldirilan SUID/SGID dosyalar:" >> $REPORT
echo "$REMOVED_FILES" >> $REPORT
fi
echo "Toplam SUID/SGID dosya sayisi: $(wc -l < $CURRENT)" >> $REPORT
cat $REPORT
Bu script’i cron’a ekle:
# Her gece saat 02:00'de çalıştır
echo "0 2 * * * root /usr/local/bin/suid_audit.sh" >> /etc/cron.d/suid-audit
Gereksiz SUID/SGID Bitlerini Kaldırmak
Tespit ettikten sonra aksiyon zamanı. Bir dosyanın SUID bitine gerçekten ihtiyacı olup olmadığını sorgulamalısın:
# SUID bitini kaldır
chmod u-s /path/to/suspicious/file
# SGID bitini kaldır
chmod g-s /path/to/suspicious/file
# Her ikisini kaldır
chmod ug-s /path/to/suspicious/file
Dikkat: Sistem araçlarından SUID’i körce kaldırma. passwd, su, sudo, ping gibi araçlar SUID’e ihtiyaç duyar. Kaldırırsan çalışmazlar.
Hangi dosyaların meşru SUID kullandığını anlamak için dağıtım belgelerine bakabilirsin. Debian/Ubuntu sistemlerinde:
# dpkg ile hangi pakete ait olduğunu bul
dpkg -S /usr/bin/passwd
# Dosyanın beklenen izinlerini kontrol et
dpkg --verify passwd
Red Hat/CentOS/Rocky Linux sistemlerinde:
# rpm ile kontrol
rpm -V $(rpm -qf /usr/bin/passwd)
Eğer rpm veya dpkg bu dosyayı tanımıyorsa, yani hiçbir pakete ait değilse, bu ciddi bir alarm.
Lynis ile Kapsamlı Güvenlik Denetimi
Manuel tarama iyidir ama otomatize araçlar daha kapsamlı bakar. Lynis bu iş için biçilmiş kaftan:
# Lynis kurulumu (Debian/Ubuntu)
apt install lynis
# Lynis kurulumu (RHEL/CentOS)
yum install lynis
# Sistem denetimi çalıştır
lynis audit system
# Sadece dosya izinleriyle ilgili testleri çalıştır
lynis audit system --tests-from-group file_permissions
Lynis çıktısında SUID/SGID ile ilgili uyarıları FILE- ile başlayan test ID’leri altında bulabilirsin. Rapor genellikle /var/log/lynis.log ve /var/log/lynis-report.dat dosyalarına yazılır.
/tmp ve Benzeri Dizinlerde Sticky Bit Kontrolü
Dünya-yazılabilir (world-writable) dizinlerde sticky bit kontrolü ayrı bir önem taşır:
# Sticky bit olmayan world-writable dizinleri bul (tehlikeli!)
find / -type d -perm -0002 ! -perm -1000 2>/dev/null
# Tüm sticky bit'li dizinleri listele
find / -type d -perm -1000 2>/dev/null
# /tmp ve /var/tmp kontrolü
ls -la / | grep tmp
ls -la /var/ | grep tmp
Eğer /tmp üzerinde sticky bit yoksa hemen düzelt:
chmod +t /tmp
chmod +t /var/tmp
Gerçek Dünya Saldırı Senaryosu ve Savunma
Bir penetrasyon testi senaryosu düşünelim. Saldırgan sisteme düşük yetkili bir kullanıcı olarak girmiş. İlk hamlesi SUID taraması:
find / -perm -u=s -type f 2>/dev/null
Listede /usr/local/bin/backup_tool adlı bir binary görüyor. Bu araç bir geliştirici tarafından yazılmış, root’a ait ve SUID bitli. Binary’yi analiz ettiğinde system() çağrısıyla tar komutunu PATH üzerinden çağırdığını görüyor. PATH manipulation ile saldırı:
# Kötü niyetli 'tar' oluştur
echo '/bin/bash -p' > /tmp/tar
chmod +x /tmp/tar
export PATH=/tmp:$PATH
# SUID binary'yi çalıştır
/usr/local/bin/backup_tool
# Sonuç: root shell
Savunma: Bu tür araçları geliştirirken tam yol kullan (/bin/tar gibi), system() yerine execve() kullan, SUID gerçekten gerekli mi sorgula, gerekirse capability’leri kullan.
Linux Capabilities: SUID’e Modern Alternatif
Modern Linux sistemlerinde SUID’e her zaman başvurmak zorunda değilsin. Linux Capabilities çok daha granüler bir kontrol sağlar:
# Bir dosyanın mevcut capability'lerini görüntüle
getcap /usr/bin/ping
# ping'e sadece gerekli capability'yi ver, SUID kaldır
setcap cap_net_raw+ep /usr/bin/ping
chmod u-s /usr/bin/ping
# Sistemdeki tüm capability'li dosyaları bul
getcap -r / 2>/dev/null
Capability ile programı root yetkilerinin tamamına değil, sadece ihtiyaç duyduğu yetkiye sahip yaparsın. Bu principle of least privilege (en az yetki ilkesi) açısından çok daha doğru bir yaklaşım.
Audit Framework ile Gerçek Zamanlı İzleme
Auditd ile SUID binary çalışmalarını gerçek zamanlı izleyebilirsin:
# SUID binary çalıştırmalarını izle
auditctl -a always,exit -F arch=b64 -F perm=x -F auid>=1000 -F auid!=4294967295 -k suid_exec
# Audit kuralını kalıcı hale getir
echo "-a always,exit -F arch=b64 -F perm=x -F auid>=1000 -F auid!=4294967295 -k suid_exec" >> /etc/audit/rules.d/suid.rules
# Logları izle
ausearch -k suid_exec | grep -i "priv-esc|suspicious"
# aureport ile özet al
aureport --executable --summary
Sonuç
SUID, SGID ve Sticky Bit, Linux’un güç mekanizmalarının ayrılmaz parçaları. Sorun bu bitlerin var olması değil, kontrolsüz ve gereksiz yere var olması. Sysadmin olarak görevin şu üç prensibi hayata geçirmek: görünürlük (sistemde ne var?), değişim takibi (ne değişti?) ve minimum yetki (gerçekten bu yetkiye ihtiyacı var mı?).
Baseline oluştur ve bunu düzenli taramalarla karşılaştır. Şüpheli her dosyayı paket yöneticisiyle doğrula. Mümkün olan yerlerde SUID yerine Linux capabilities kullan. Auditd ile bu izinlerin ne zaman ve kim tarafından kullanıldığını kayıt altına al. Lynis gibi araçları periyodik denetim süreçlerine dahil et.
Unutma, bir saldırgan sisteme girdiğinde yapacağı ilk şeylerden biri SUID taraması. Sen de ondan önce bu taramayı yap ve sistemi ona göre sertleştir. Güvenlik reaktif değil proaktif bir iş olmalı, yoksa logları inceleyerek hasarı tespit edersin, ki bu hiç iyi bir his değil.
