oss-sec mailing list archives

Re: [CVE-2020-28018] Use-After-Free on Exim Question


From: "harris.johnson.x" <harris.johnson.x () protonmail com>
Date: Wed, 12 May 2021 14:46:31 +0000

Greetings OSS-Security!

I took a look at that flaw too...but I wonder if there is a good technique to groom the heap to get that allocation 
right before the objective data. There are some limits on using a MAIL cmd, first u cannot use it if another MAIL cmd 
was successful. Second it calls smtp_reset() after finished. The only way 'd be using RSET so u can use MAIL again, but 
it will free all the subsequent heap buffers and return yield to the ptr specified on smtp_reset().

The only time in which u can send a MAIL cmd to alloc it would be between the second part of the cmd sent in the first 
TLS session, and the initialization of the new TLS session. After the initialization of the first TLS session lot of 
allocations happen, this will in fact extend the heap from the top chunk.

Once TLS connection is dropped out, and we start on plaintext again, after sending the EHLO cmd, smtp_reset() will be 
called, which will finally end up on freeing all subsequent heap buffers, except from the one pointed to by reset_point 
in the middle, which it's yield is just restored to point to it. At this point, top chunk size increased thanks to all 
the recently released chunks consequent to each other. And the objective struct is intact on the top chunk.

As u mentioned to "null p0int3r", there is an interesting parameter for MAIL cmd that lets you use encoding so it is an 
string, but then converted to binary data when copied to the allocated memory, so it bypasses any stuff related to 
parsing or NULL bytes. That specific parameter uses store_get(), so it hangs from the POOL_MAIN memory. This means the 
only way to perform an independent malloc() (so memory from top chunk is stolen, including the objective data) is first 
filling the current block, so in the store.c code, size will be > yield_length[store_pool], and will call malloc, so 
finally returning to us pointer to objective data to be overwrite with ours. Also, it will be better for that malloc() 
to have a really high request size, so the malloc() request does not reuse a freed chunk with specific requirements to 
be returned (if any).

R u guys using any specific technique to groom the heap / get the chunk returned by store_get() on that struct?

Good luck!

---
Harris Johnson

Current thread: