Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date: Sun, 25 Jul 2021 09:21:33 -0000
From: "Jonas Dellinger" <jdellinger@...l2tor.com>
To: oss-security@...ts.openwall.com
Subject: CVE-2020-28020: Integer overflow in Exim that can lead to RCE: Some
 questions to the Qualys researchers who designed the exploit

Hi all,

I've been reading through the 21Nails Exim security advisory [1] and
one vulnerability particularly interested me: CVE-2020-28020, an integer
overflow in receive_msg() that can lead to RCE when sending crafted
emails. I'm having a hard time fully understanding the exploit outlined
by the Qualys researchers and have a couple of questions to them (quoting
the advisory):

> we first allocate a 1GB mmap block (mblock1) by sending a mail that
> contains a 256MB header of bare '\n' characters; the next member of
> mblock1's storeblock structure initially points to a heap block
> (hblock, which immediately follows data that we control);

What data precedes hblock and how is it controlled by the attacker?

> we allocate a third 1GB mmap block (mblock3) by sending a mail that
> contains a 512MB header; this overflows the integer header_size, and
> forward-overflows mblock3 (Digression 1a), into mblock2 and mblock1:
> we overwrite mblock2's next pointer with NULL (to avoid a crash in
> store_release() at line 1788) and we partially overwrite mblock1's
> next pointer (with a single null byte).

How do you remotely make allocations that overwrite the desired pointers?
Is my understanding correct that you overwrite the first byte of mblock1's
next pointer with zero? How does that ensure that it points to the "fake
storeblock" structure?

> 3/ Information disclosure:
>
> - First, we send an EHLO command that allocates a large string in raw
> malloc() memory.
>
> - Second, we send an invalid RCPT TO command that allocates a small
> string in POOL_MAIN memory (an error message); this small POOL_MAIN
> string overwrites the beginning of the large malloc() string.

Why does the POOL_MAIN allocation collide with the raw malloc() one?
I understand that you make the entire heap look like free POOL_MAIN
memory using the "fake storeblock" structure, but how come that the
small POOL_MAIN string lands exactly on the large raw malloc() string?

Thanks a lot!

[1] https://www.qualys.com/2021/05/04/21nails/21nails.txt

Powered by blists - more mailing lists

Please check out the Open Source Software Security Wiki, which is counterpart to this mailing list.

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.