[exim-dev] [Bug 2199] New: Exim use-after-free vulnerability…

Top Page
Delete this message
Reply to this message
Author: admin
Date:  
To: exim-dev
New-Topics: [exim-dev] [Bug 2199] Exim use-after-free vulnerability while reading mail header
Subject: [exim-dev] [Bug 2199] New: Exim use-after-free vulnerability while reading mail header
https://bugs.exim.org/show_bug.cgi?id=2199

            Bug ID: 2199
           Summary: Exim use-after-free vulnerability while reading mail
                    header
           Product: Exim
           Version: 4.89
          Hardware: x86-64
                OS: Linux
            Status: NEW
          Severity: security
          Priority: medium
         Component: Delivery in general
          Assignee: nigel@???
          Reporter: meh@???
                CC: exim-dev@???


Created attachment 1049
--> https://bugs.exim.org/attachment.cgi?id=1049&action=edit
RIP-control PoC

Hi, we found a use-after-free vulnerability which is exploitable to RCE in the
SMTP server.

According to receive.c:1783, 
1783     if (!store_extend(next->text, oldsize, header_size))
1784       {
1785       uschar *newtext = store_get(header_size);
1786       memcpy(newtext, next->text, ptr);
1787       store_release(next->text);
1788       next->text = newtext;
1789       }


when the buffer used to parse header is not big enough, exim tries to extend
the next->text with store_extend function. If there is any other allocation
between the allocation and extension of this buffer, store_extend fails.
store.c
276 if ((char *)ptr + rounded_oldsize != (char *)(next_yield[store_pool]) ||
277     inc > yield_length[store_pool] + rounded_oldsize - oldsize)
278   return FALSE;


Then exim calls store_get, and store_get cut the current_block directly.
store.c
208 next_yield[store_pool] = (void *)((char *)next_yield[store_pool] + size);
209 yield_length[store_pool] -= size;
210
211 return store_last_get[store_pool];

However, in receive.c:1787, store_release frees the whole block, leaving the
new pointer points to a freed location. Any further usage of this buffer leads
to a use-after-free vulnerability.
To trigger this bug, BDAT command is necessary to perform an allocation by
raising an error. Through our research, we confirm that this vulnerability can
be exploited to remote code execution if the binary is not compiled with PIE.
An RIP controlling PoC is in attachment poc.py. The following is the gdb result
of this PoC:
Program received signal SIGSEGV, Segmentation fault.
0x00000000deadbeef in ?? ()
(gdb)

--
You are receiving this mail because:
You are on the CC list for the bug.