Sıfır günü keşfetme ve Mozilla’nın AWS Ağında kod yürütme olanağı elde etme


Assetnote Continuous Security (CS) saldırı yüzeyinizi izlerken aradığı şeylerden biri WebPageTest örnekleridir. WebPageTest, herhangi bir URL/ana bilgisayar için ağla ilgili ölçümleri test etmenize olanak tanıyan bir web sitesi performans test aracıdır.

Temel kimlik doğrulaması, settings.ini dosyası değiştirilerek etkinleştirilebilmesine rağmen, anonim erişimin önlenmesi için önerilir. Assetnote CS’nin tanımladığı çoğu WebPageTest dağıtımının kimliği doğrulanmamıştır ve WebPageTest tarafından sağlanan test araçları dizisi, sunucu tarafı istek sahteciliği (genellikle SSRF olarak bilinir, ancak WebPageTest için bu bir özelliktir) yoluyla dahili kaynaklara erişim sağlamak için saldırgan bir şekilde kullanılabilir. ).

Kasım 2017’de Assetnote CS, Mozilla’nın AWS ortamında aşağıdaki varlıkları keşfetti:

  • wpt-vpn.stage.mozaws.net
  • wpt1.dev.mozaws.net

Bunların her ikisi de WebPageTest’in kimlik doğrulama gerektirmeyen örnekleriydi ve Assetnote CS bunu bir hata ödülü olarak ilk kez tespit etmişti. Birlikte çalışmak Mathiaskaynak kodunu denetledik ve yalnızca birkaç saat içinde uzaktan kod yürütülmesine yol açan bir saldırı zinciri oluşturmayı başardık.

Keşif sırasında sıfır gün olmasına rağmen, güvenlik açığının yukarı yönde düzeltilmesi için Mozilla ve WebPageTest ekibiyle birlikte çalıştık. Bu blog yazısında özetlenen hataları düzelten taahhüt, 17 Ocak 2018’de bu taahhütte aktarıldı.

Kod tabanında dikkatimizi çeken ilk şey, rastgele Zip dosyalarını yükleme ve çıkarma yeteneğiydi. /www/work/workdone.php. Bu komut dosyası, aşağıdaki kod parçacığından görüldüğü gibi, 127.0.0.1 dışındaki kaynaklardan erişimi kısıtlamak için bazı mantıklar içeriyordu:

...
!strcmp($_SERVER['REMOTE_ADDR'], "127.0.0.1")
...

Bu konuya daha sonra geri döneceğiz.

Aynı dosyada, rastgele bir Zip yüklemek ve onu bilinen bir konuma çıkartmak için başka bir potansiyel vektör mantığı bulduk:

133 – 136. satırlar: /www/work/workdone.php

if (isset($_FILES['file']['tmp_name'])) {
  ExtractZipFile($_FILES['file']['tmp_name'], $testPath);
  CompressTextFiles($testPath);
}

Eğer IP’mizi 127.0.0.1’den gelecek şekilde taklit edebilirsek, bu vektör aracılığıyla kod çalıştırmayı başarabilirmişiz gibi görünüyor.

Ancak 321 numaralı hat nedeniyle bunun düşündüğümüz kadar basit olmadığını gördük. /www/work/workdone.php:

Mantığı GüvenliDir işlevi 2322 – 2347 numaralı satırlarda bulunabilir. /www/common_lib.inc:

/**
* Make sure there are no risky files in the given directory and make everything no-execute
*
* @param mixed $path
*/
function SecureDir($path) {
    $files = scandir($path);
    foreach ($files as $file) {
        $filepath = "$path/$file";
        if (is_file($filepath)) {
            $parts = pathinfo($file);
            $ext = strtolower($parts['extension']);
            if (strpos($ext, 'php') === false &&
                strpos($ext, 'pl') === false &&
                strpos($ext, 'py') === false &&
                strpos($ext, 'cgi') === false &&
                strpos($ext, 'asp') === false &&
                strpos($ext, 'js') === false &&
                strpos($ext, 'rb') === false &&
                strpos($ext, 'htaccess') === false &&
                strpos($ext, 'jar') === false) {
                @chmod($filepath, 0666);
            } else {
                @chmod($filepath, 0666);    // just in case the unlink fails for some reason
                unlink($filepath);
            }
        } elseif ($file != '.' && $file != '..' && is_dir($filepath)) {
            SecureDir($filepath);
        }
    }
}

SecureDir işlevi kod akışı sırasında daha sonra ortaya çıktığı için, web sunucusuna çıkarılan PHP dosyalarının silinmeden önce kısa bir süreliğine erişilebilir olduğu, istismar edilebilir bir yarış durumu vardır.

Traceroute çalıştırılarak geçerli bir test kimliği elde edildiğinden zincirin ilk ön koşulu oldukça kolaydı. https://google.com.tr WebPageTest arayüzü aracılığıyla wpt-vpn.stage.mozaws.net:

WebPageTest’i kullanarak traceroute çalıştırma

Traceroute’u çalıştırdıktan sonra WebPageTest bizi sonraki adımlarda kullanılan test kimliğini içeren bir URL’ye yönlendirdi:

‍Ama yine de bir şekilde sahte olduğumuzu göstermemiz gerekiyordu. 127.0.0.1 Bu komut dosyasındaki güvenlik açığı olan işlevlere erişmek için.

Aşağıdaki mantığı kullanarak bu koşulu yerine getirebildik:

Satır 70: /www/common.inc

if (isset($_SERVER["HTTP_FASTLY_CLIENT_IP"]))
  $_SERVER["REMOTE_ADDR"] = $_SERVER["HTTP_FASTLY_CLIENT_IP"];

Bu, uzak kullanıcılar olarak keyfi olarak ayarlamamıza olanak sağladı. $_SERVER[“REMOTE_ADDR”] bir göndererek HIZLI-MÜŞTERİ-IP istek başlığı şu şekilde ayarlandı: 127.0.0.1.

Tüm bu unsurları bir araya getirerek, sonunda kod yürütmeyi sağlamak için iki Burp Intruder saldırısı oluşturmayı başardık.

Bir Burp Intruder saldırısı, kötü amaçlı bir Zip dosyası yüklemek için kullanıldı ve bir diğeri, çıkarılan PHP dosyasına, sistemde varken erişmeye çalıştı. O zamanki yarış koşullarından yararlanmaya yönelik çözümümüz, Burp Intruder’ın ipliklerini ~200’e çıkarmaktı.

Günümüzde Turbo Intruder gibi araçlar kullanılarak gönderilen isteklerin hızı nedeniyle bu istismarı çok daha güvenilir hale getirmek mümkün.

Aşağıdaki ekran görüntüsünde görüldüğü gibi Mozilla’da kod yürütmek için bu tekniği kullanabildik:

wpt-vpn.stage.mozaws.net’ten phpinfo() çıktısı

Bu güvenlik açığını ilk kez bildirdiğimiz Bugzilla raporu artık herkese açık ve buradan görüntülenebilir.

Rapor, bu hataları yeniden oluşturmak isteyen test uzmanları için yeterli olması gereken kapsamlı yeniden oluşturma adımları içermektedir.

Mozilla’nın hata ödül programının bir parçası olarak bize 500$ ödül verildi.





Source link