Summary
An out-of-bounds (OOB) read vulnerability has been detected in ntlm_av_pair_get
function due to a corrupted NTLM_AV_PAIR
linked-list.
Product
FreeRDP
Tested Version
Development version - master branch (May 22, 2020)
Details: Out-of-bound read in ntlm_av_pair_get
The ntlm_av_pair_get
function in ntlm_av_pairs.c
performs a call to ntlm_av_pair_get_id(pAvPair)
(line 173), where pAvPair
is a pointer to a linked-list of NTLM_AV_PAIR
. The problem here is that pAvPairList may be a corrupted linked-list:
/* winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c */
NTLM_AV_PAIR* ntlm_av_pair_get(NTLM_AV_PAIR* pAvPairList, size_t cbAvPairList, NTLM_AV_ID AvId,
size_t* pcbAvPairListRemaining)
{
size_t cbAvPair = cbAvPairList;
NTLM_AV_PAIR* pAvPair = pAvPairList;
if (!ntlm_av_pair_check(pAvPair, cbAvPair))
pAvPair = NULL;
while (pAvPair)
{
UINT16 id = ntlm_av_pair_get_id(pAvPair);
The corruption is a result of a previously read malformed linked-list member values. Let’s take a closer look at how this corruption occurs:
/* winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c */
int ntlm_construct_authenticate_target_info(NTLM_CONTEXT* context)
{
...
ChallengeTargetInfo = (NTLM_AV_PAIR*)context->ChallengeTargetInfo.pvBuffer;
...
AvEOL = ntlm_av_pair_get(ChallengeTargetInfo, cbChallengeTargetInfo, MsvAvEOL, NULL);
As you can see above, ChallengeTargetInfo
is the linked-list which is passed as an argument to ntlm_av_pair_get
function, and that, in turn, is equal to context->ChallengeTargetInfo.pvBuffer
. Next we will see how context->ChallengeTargetInfo
is used in the ntlm_read_message_fields_buffer
function:
/* winpr/libwinpr/sspi/NTLM/ntlm_message.c */
ntlm_read_ChallengeMessage(NTLM_CONTEXT* context, PSecBuffer buffer)
{
...
if (ntlm_read_message_fields_buffer(s, &(message->TargetInfo)) < 0)
goto fail;
context->ChallengeTargetInfo.pvBuffer = message->TargetInfo.Buffer;
...
At this point, the problem is that the FreeRDP client is reading these offsets directly from the server, without checking they are correct.
So, a malicious attacker could set a malicious offset and when ntlm_av_pair_get_id
will be called, the program will try to access a non-existent list member:
/* winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c */
static INLINE UINT16 ntlm_av_pair_get_id(const NTLM_AV_PAIR* pAvPair)
{
UINT16 AvId;
Data_Read_UINT16(&pAvPair->AvId, AvId);
return AvId;
}
As a result, OOB reads can occurs resulting in accessing memory that has not been allocated by FreeRDP process.
Impact
This issue may lead to Out-of-Bounds read.
CVE
- CVE-2020-11097
Coordinated Disclosure Timeline
This report was subject to the GHSL coordinated disclosure policy.
- 05/22/2020: Vendor contacted
- 05/26/2020: Vendor acknowledges report
- 06/22/2020: Bug fixed and patch released by the vendor
Supporting Resources
- https://github.com/FreeRDP/FreeRDP/security/advisories/GHSA-c8x2-c3c9-9r3f
- https://github.com/FreeRDP/FreeRDP/commit/58a3122250d54de3a944c487776bcd4d1da4721e#diff-758f5a86ba21ec7cc3805bbc33db6fea
Credit
This issue was discovered and reported by GHSL team member @antonio-morales (Antonio Morales).
Contact
You can contact the GHSL team at securitylab@github.com
, please include the GHSL-2020-104
in any communication regarding this issue.