Skip to content
KitploitKITPLOIT
उपकरणब्लॉग
जमा करें
उपकरणब्लॉग
जमा करें

हैकिंग, पेनटेस्ट और साइबर सुरक्षा उपकरण आपके सुरक्षा शस्त्रागार के लिए!

Kitploit हैकिंग, साइबर सुरक्षा और पेंटेस्टिंग टूल्स की एक निर्देशिका है। कमजोरियों को खोजने, सिस्टम का विश्लेषण करने, परीक्षण को स्वचालित करने और अपनी सुरक्षा को मजबूत करने के लिए नवीनतम प्रोजेक्ट अपडेट खोजें।

··फ़ीड·संपर्क·गोपनीयता·© 2026 Kitploit

टूल निर्देशिका

श्रेणियाँ

सभी श्रेणियाँ देखें
Loading categories
cve-2023-5217-poc — ब्राउज़र WebCodecs या MediaRecorder इंटरफ़ेस से CVE-2023-5217 को ट्रिगर करने के लिए एक PoC। | Kitploit
उपकरण/GitHubGitHub/ut-security/cve-2023-5217-poc
भेद्यता विश्लेषणशोषणवेब एप्लिकेशन शोषणफज़िंगलर्निंग और शिक्षाबाइनरी शोषण
GitHubut-security/cve-2023-5217-poc

cve-2023-5217-poc

ब्राउज़र WebCodecs या MediaRecorder इंटरफ़ेस से CVE-2023-5217 को ट्रिगर करने के लिए एक PoC।

रिपॉजिटरी देखें
16312 साल पहलेअभी तक समीक्षित नहीं

सबसे लोकप्रिय

सभी देखें →

हमारे समुदाय द्वारा सबसे अधिक उपयोग किए जाने वाले उपकरण खोजें।

सभी उपकरण खोजें

हमारे उपकरणों का संग्रह ब्राउज़ करें

सभी उपकरण देखें →
साझा करें

CVE-2023-5217: libvpx VP8 एन्कोडिंग हीप ओवरफ़्लो PoC

CVE-2023-5217 एक in-the-wild शोषित libvpx कमजोरी है जो Google के थ्रेट एनालिसिस ग्रुप के Clément Lecigne द्वारा Chrome को लक्षित करने के लिए पाई गई थी।

यह रिपॉजिटरी WebCodecs और MediaRecorder API का उपयोग करके ब्राउज़र में CVE-2023-5217 को ट्रिगर करने का तरीका दिखाती है। CVE-2023-5217 एक नियंत्रित ओवरफ़्लो लंबाई और एक बार-बार छोटे 4-बाइट मान के ओवरराइट के साथ हीप बफर ओवरफ़्लो की अनुमति देता है। यह वर्तमान में ज्ञात नहीं है कि CVE-2023-5217 का जंगली में कैसे शोषण किया गया।

सार्वजनिक प्रकटीकरण के समय, libvpx में दो पैच और Chromium में एक पैच थे जिन्होंने CVE-2023-5217 को ठीक किया। libvpx पैच में VP8 थ्रेड संख्या परिवर्तनों को अक्षम करना और मल्टीथ्रेडेड एन्कोडिंग के लिए एक परीक्षण शामिल था। Chromium पैच ने WebCodecs में थ्रेड्स की संख्या को समायोजित करना अक्षम कर दिया।

अंतर्निहित समस्या libvpx v1.13.0 Ugly Duckling में

सारांश

libvpx एक लाइब्रेरी है जो VP8/VP9 एन्कोडिंग और डिकोडिंग को संभालती है।

CVE-2023-5217 में मुख्य समस्या यह है कि libvpx VP8 एन्कोडिंग सत्र में फ्रेम की ऊंचाई बढ़ाते समय थ्रेड्स की संख्या कम करने से एक नियंत्रित लंबाई का रैखिक हीप ओवरफ़्लो और एक बार-बार छोटे 4-बाइट मान का नियंत्रित ओवरराइट होता है। फ्रेम की ऊंचाई में अंतर ओवरराइट की लंबाई को नियंत्रित करता है, और नई फ्रेम चौड़ाई उस 4-बाइट मान को नियंत्रित करती है जो बार-बार लिखा जाता है। इस कमजोरी का कई बार शोषण किया जा सकता है ताकि प्रत्येक बाद के कॉन्फ़िग में ऊंचाई कम करके लगातार अलग-अलग छोटे 4-बाइट मान लिखे जा सकें।

विवरण

libvpx VP8 एन्कोडर mt_current_mb_col नामक एक ऐरे बनाए रखता है जो एन्कोडर थ्रेड द्वारा काम किए जा रहे वर्तमान कॉलम को संग्रहीत करता है। यह ऐरे केवल तभी आवंटित होता है जब एक से अधिक थ्रेड हों, और इसका आकार mb_rows का फलन है, जहाँ mb_rows = frame_height >> 4 और frame_height को निकटतम 16 के गुणज में पूर्णांकित किया जाता है।

root@kitploit:~
// https://github.com/webmproject/libvpx/blob/6512f994da13e2f27e6a7bd449efee0a374b55b7/vp8/common/alloccommon.c#L85
// The width and height are rounded up to a multiple of 16 and then assigned to `mb_rows` and `mb_cols`
int vp8_alloc_frame_buffers(VP8_COMMON *oci, int width, int height) {
    ...
    // Round up the width/height up to the nearest multiple of 16
    if ((width & 0xf) != 0) width += 16 - (width & 0xf);
    if ((height & 0xf) != 0) height += 16 - (height & 0xf);
    ...
    oci->mb_rows = height >> 4;
    oci->mb_cols = width >> 4;
    ...
}
// https://github.com/webmproject/libvpx/blob/6512f994da13e2f27e6a7bd449efee0a374b55b7/vp8/encoder/onyx_if.c#L1232
// This snippet shows the allocation of `mt_current_mb_col`
void vp8_alloc_compressor_data(VP8_COMP *cpi) {
  ...
  // Only allocate if we have more than 1 thread
  if (cpi->oxcf.multi_threaded > 1) {
    int i;

    vpx_free(cpi->mt_current_mb_col);
    // sizeof(*cpi->mt_current_mb_col) is 4
    CHECK_MEM_ERROR(&cpi->common.error, cpi->mt_current_mb_col,
                    vpx_malloc(sizeof(*cpi->mt_current_mb_col) * cm->mb_rows));
    for (i = 0; i < cm->mb_rows; ++i)
      vpx_atomic_init(&cpi->mt_current_mb_col[i], 0);
  }
  ...
}

जब libvpx एक फ्रेम को एन्कोड करना समाप्त करता है, तो यह mt_current_mb_col में एन्कोड किए गए कॉलमों की संख्या और mt_sync_range को संग्रहीत करता है।

root@kitploit:~
// https://github.com/webmproject/libvpx/blob/6512f994da13e2f27e6a7bd449efee0a374b55b7/vp8/encoder/onyx_if.c#L1212
// Snippet where the mt_sync_range value is set, based on the width.
void vp8_alloc_compressor_data(VP8_COMP *cpi) {
    ...
#if CONFIG_MULTITHREAD
  if (width < 640) {
    cpi->mt_sync_range = 1;
  } else if (width <= 1280) {
    cpi->mt_sync_range = 4;
  } else if (width <= 2560) {
    cpi->mt_sync_range = 8;
  } else {
    cpi->mt_sync_range = 16;
  }
#endif
  ...
}
// https://github.com/webmproject/libvpx/blob/6512f994da13e2f27e6a7bd449efee0a374b55b7/vp8/encoder/encodeframe.c#L560
// Function where the attacker chosen value is written
static void encode_mb_row(...) {
  ...
  const int nsync = cpi->mt_sync_range; // This value is set in vp8_alloc_compressor_data
  vpx_atomic_int rightmost_col = VPX_ATOMIC_INIT(cm->mb_cols + nsync);
  ...
  if (vpx_atomic_load_acquire(&cpi->b_multi_threaded) != 0) {
    current_mb_col = &cpi->mt_current_mb_col[mb_row];
  }
  ...
  if (vpx_atomic_load_acquire(&cpi->b_multi_threaded) != 0) {
    // current_mb_col is a reference to mt_current_mb_col
    vpx_atomic_store_release(current_mb_col,
                             vpx_atomic_load_acquire(&rightmost_col));
  }
  ...
}

mt_current_mb_col को ओवरफ़्लो करने के लिए, हमें तीन एन्कोडिंग कॉन्फ़िगरेशन की आवश्यकता है:

  1. configinit: प्रारंभिकरण के दौरान, libvpx initial_width और initial_height सेट करता है। ये बाद के कॉन्फ़िगरेशन की अधिकतम संभावित सीमाएँ हैं। यहाँ थ्रेड्स की संख्या मायने नहीं रखती। हमें मध्यवर्ती कॉन्फ़िग की आवश्यकता है क्योंकि कोई भी बाद का चौड़ाई/ऊंचाई संयोजन हमने जो शुरू किया उससे बड़ा नहीं हो सकता।
  2. configvuln: पुनर्विन्यास के दौरान, यदि एक से अधिक थ्रेड का उपयोग किया जाता है तो libvpx configvuln.height के आधार पर संवेदनशील mt_current_mb_col आवंटन बनाता है। यह नई ऊंचाई configinit.initial_height से छोटी होनी चाहिए अन्यथा हमें एक त्रुटि मिलेगी।
  3. configattack: पुनर्विन्यास के दौरान, यदि केवल एक थ्रेड का उपयोग किया जाता है तो libvpx mt_current_mb_col को पुनः आवंटित नहीं करेगा, इसे संवेदनशील स्थिति में छोड़ देगा। libvpx बार-बार पहले से आवंटित सीमाओं के बाहर (configattack.width >> 4) + 1 मान (जहाँ 1 चर mt_sync_range है और चौड़ाई निकटतम 16 के गुणज में पूर्णांकित की जाती है) लिखेगा जब निम्नलिखित शर्त पूरी होती है:
root@kitploit:~
\text{ceil}(\text{config}_{\text{init}}.\text{height}/16) \geq \text{ceil}(\text{config}_{\text{attack}}.\text{height}/16) \gt \text{ceil}(\text{config}_{\text{vuln}}.\text{height}/16)$$

mt_current_mb_col overflow

अधिक ठोस रूप से, मान लें कि हम configinit के साथ width = 1200, height = 1200, threads = 4 के साथ एक VP8 एन्कोडिंग कॉन्फ़िगरेशन प्रारंभ करते हैं। हमला इस प्रकार है:

  1. configvuln एन्कोडर को width = 500 (512 round up), height = 700 (704 round up), और threads = 2 के साथ पुनर्विन्यस्त करता है। चर mb_rows को 704/16=44 पर सेट किया जाता है, और ऐरे mt_current_mb_col को (44)*4 = 176 बाइट्स में आवंटित किया जाता है। mt_current_mb_col में लिखा गया मान 512/16 + 1 = 33 है।
  2. configattack एन्कोडर को width = 18 (32 round up), height = 1000 (1008 round up), और threads = 1 के साथ पुनर्विन्यस्त करता है। क्योंकि mt_current_mb_col केवल तभी पुनः आवंटित होता है जब एक से अधिक थ्रेड हों, यह उसी आकार में रहता है, फिर भी mb_rows अब 1008/16 = 63 पर सेट हो गया है। जब libvpx encode_mb_row को कॉल करता है, तो यह mt_current_mb_col आवंटन से (63-44)*4 = 68 बाइट्स आगे ओवरराइट करेगा, बार-बार मान 32/16 + 1 = 3 लिखता है, जहाँ 32 round-up की गई चौड़ाई है, और 1 mt_sync_range मान है।
  3. एक हमलावर configattack की ऊंचाई से छोटी लेकिन फिर भी configvuln से बड़ी ऊंचाई के साथ इस कमजोरी का पुनः शोषण कर सकता है ताकि एक और मान लिखा जा सके। उदाहरण के लिए, एक हमलावर configattack' को width = 34 और height = 990 के साथ बना सकता है, mb_rows = 992/16 = 62 और mb_cols = 48/16 = 3 सेट करके, मूल आवंटन से केवल (62-44)*4 = 64 बाइट्स आगे मान 4 लिखता है।

शोषण

इस कमजोरी का शोषण करने के लिए, एक हमलावर को एन्कोडिंग की ऊंचाई, चौड़ाई और थ्रेड्स की संख्या को नियंत्रित करने में सक्षम होना चाहिए। पहले दो सीधे हैं, लेकिन बाद वाले के लिए उन स्थानों को खोजने की आवश्यकता है जहाँ एन्कोडिंग थ्रेड्स की संख्या पुनर्विन्यस्त की जाती है।

root@kitploit:~
// https://github.com/webmproject/libvpx/blob/67bfb41ed8598edfb25bd6f245f9c39a68808548/vp8/vp8_cx_iface.c#L301
static vpx_codec_err_t set_vp8e_config(VP8_CONFIG *oxcf,
 ...
  oxcf->multi_threaded = cfg.g_threads;

Firefox

Firefox में, हम VP8TrackEncoder में एन्कोड किए जा रहे फ्रेम क्षेत्र को समायोजित करके थ्रेड्स की संख्या को नियंत्रित कर सकते हैं। यदि फ्रेम क्षेत्र 307,200 (640x480 फ्रेम) से बड़ा है और मशीन में 2 से अधिक कोर हैं, तो एक से अधिक थ्रेड का उपयोग किया जाएगा।

root@kitploit:~
// https://searchfox.org/mozilla-central/source/dom/media/encoder/VP8TrackEncoder.cpp#97
nsresult CreateEncoderConfig(...) {
  ...
  int32_t number_of_cores = PR_GetNumberOfProcessors();
  if (aWidth * aHeight > 1920 * 1080 && number_of_cores >= 8) {
    config->g_threads = 4;  // 4 threads for > 1080p.
  } else if (aWidth * aHeight > 1280 * 960 && number_of_cores >= 6) {
    config->g_threads = 3;  // 3 threads for 1080p.
  } else if (aWidth * aHeight > 640 * 480 && number_of_cores >= 3) {
    config->g_threads = 2;  // 2 threads for qHD/HD.
  } else {
    config->g_threads = 1;  // 1 thread for VGA or less
  }
  ...

हमने पाया कि MediaRecorder API VP8TrackEncoder पर निर्भर करता है, और हम रिकॉर्ड किए जा रहे कैनवास के आकार को बदलकर चौड़ाई और ऊंचाई को समायोजित कर सकते हैं। इसे कॉल करने के तरीके के लिए नीचे MediaRecorder अनुभाग देखें।

Chrome

Chrome भी इसी तरह एन्कोड किए जा रहे फ्रेम क्षेत्र के आधार पर थ्रेड्स की संख्या को समायोजित करता है, जो कोर की संख्या के लिए समायोजित किया जाता है।

root@kitploit:~
// https://source.chromium.org/chromium/chromium/src/+/main:media/video/vpx_video_encoder.cc;l=84
EncoderStatus SetUpVpxConfig(...) {
  ...
  // Set the number of threads based on the image width and num of cores.
  config->g_threads = GetNumberOfThreadsForSoftwareEncoding(opts.frame_size);
}

// https://source.chromium.org/chromium/chromium/src/+/main:media/base/video_encoder.cc;drc=f5bdc89c7395ed24f1b8d196a3bdd6232d5bf771;l=33
int GetNumberOfThreadsForSoftwareEncoding(gfx::Size frame_size) {
  int area = frame_size.GetCheckedArea().ValueOrDefault(1);
  // Default to 1 thread for less than VGA.
  int desired_threads = 1;

  if (area >= 3840 * 2160) {
    desired_threads = 16;
  } else if (area >= 2560 * 1080) {
    desired_threads = 8;
  } else if (area >= 1280 * 720) {
    desired_threads = 4;
  } else if (area >= 640 * 480) {
    desired_threads = 2;
  }

  // Clamp to the number of available logical processors/cores.
  desired_threads =
      std::min(desired_threads, base::SysInfo::NumberOfProcessors());

  return desired_threads;
}

यह पथ WebCodecs VideoEncoding API द्वारा प्रयोग किया जाता है, जहाँ हम सीधे एन्कोडिंग चौड़ाई/ऊंचाई को संशोधित कर सकते हैं। यह कैसे काम करता है यह देखने के लिए WebCodecs अनुभाग देखें।

MediaRecorder

फ़ाइल mediarecorder.html दिखाती है कि कैसे एक कैनवास से MediaRecorder सत्र बनाया जाए और VP8 एन्कोडिंग पुनर्विन्यास को ट्रिगर करने के लिए चौड़ाई/ऊंचाई को समायोजित किया जाए ताकि संवेदनशील ब्राउज़र में CVE-2023-5217 को ट्रिगर किया जा सके। कैनवास की चौड़ाई और ऊंचाई पैरामीटर को समायोजित करते समय, हम यह सुनिश्चित करने के लिए setTimeout का उपयोग करते हैं कि VP8 एन्कोडिंग सत्र को पुनर्विन्यस्त होने के लिए पर्याप्त समय मिले। विश्वसनीयता के लिए टाइमआउट पैरामीटर को समायोजित किया जा सकता है।

Status

  • ✅ Firefox: Firefox रेंडरर में क्रैश ट्रिगर करता है।
  • ❌ Chromium browsers: Chromium-आधारित ब्राउज़र MediaRecorder सत्र में एन्कोडर को पुनर्विन्यस्त करते समय थ्रेड्स की संख्या नहीं बदलते [code]।
  • ❌ Safari: WebKit MediaRecorder सत्रों के लिए VP8 का समर्थन नहीं करता [code]।

Firefox डेमो

Firefox पर परीक्षण करने के लिए, आप इस CVE को पैच किए जाने से पहले एक ASAN बिल्ड प्राप्त करने के लिए fuzzfetch का उपयोग कर सकते हैं, कमांड fuzzfetch --build 2023-09-27 -a के साथ, फिर सीधे mediarecorder.html खोलें।

Firefox demo

WebCodecs

फ़ाइलें webcodecs.html और webcodecs.js दिखाती हैं कि कैसे एक वर्कर में WebCodecs API का उपयोग करके संवेदनशील ब्राउज़र में CVE-2023-5217 को ट्रिगर किया जाए। WebCodecs में फ्रेम को एन्कोड करने के कॉल पर हमारा MediaRecorder की तुलना में अधिक नियंत्रण है, लेकिन फिर भी तीनों चरणों को करने के लिए परिवर्तन के लिए टाइमआउट पर निर्भर हैं।

Status

  • ✅ Chromium browsers: टैब क्रैश ट्रिगर करता है। WebCodecs के लिए यह Chromium पैच प्रारंभिक ट्राइएज में शामिल था।
  • ❌ Firefox: Firefox WebCodecs एन्कोडिंग का समर्थन नहीं करता (डिकोडिंग एक कॉन्फ़िग फ्लैग के पीछे सक्षम है)।
  • 🚧 Safari: Safari WebCodecs एन्कोडिंग का समर्थन करता है, लेकिन मुझे कोई क्रैश प्राप्त नहीं हो सका।

Chromium डेमो

Chromium पर परीक्षण करने के लिए, आप python get_asan_chrome.py --version 117.0.5938.131 कमांड के साथ Chrome का एक संवेदनशील संस्करण प्राप्त करने के लिए get_asan_chrome.py का उपयोग कर सकते हैं। फिर आपको SSL के साथ एक स्थानीय HTTP सर्वर प्रारंभ करने की आवश्यकता होगी। सर्वर कुंजी उत्पन्न करने और सर्वर प्रारंभ करने के लिए gen_server_key.sh और server.py देखें। फिर आप परिणाम देखने के लिए संवेदनशील Chromium में पेज खोल सकते हैं।

Chromium demo

WebCodecs + MediaRecorder संयुक्त

combined.html देखें जो WebCodecs नहीं मिलने पर फ़ॉलबैक के रूप में MediaRecorder का उपयोग करता है। इस संयुक्त फ़ाइल का उपयोग एक ही पेज के साथ Chrome और Firefox दोनों को लक्षित करने के लिए किया जाएगा।

निष्कर्ष

यह कमजोरी जटिल मीडिया लाइब्रेरीज़ को दूरस्थ हमलावर के सामने उजागर करने की चुनौतियों और खतरों को प्रदर्शित करती है। RLBox जैसे उपकरणों का उपयोग करके, ब्राउज़र मीडिया लाइब्रेरीज़ में संभावित कमजोरियों को अलग कर सकते हैं। Firefox इसे पहले से ही चुनिंदा लाइब्रेरीज़ में शामिल करता है।

पढ़ने के लिए धन्यवाद! योगदान का स्वागत है। किसी भी अन्य अंतर्दृष्टि के साथ Issue दर्ज करने या PR खोलने में संकोच न करें। अभी तलाशने के लिए बचा है यह देखना कि यह छोटा 4-बाइट ओवरराइट कोड निष्पादन की ओर कैसे ले जा सकता है।

Anand Balaji को पिछले ड्राफ्ट पर प्रतिक्रिया के लिए धन्यवाद।

टूल डाउनलोड करें