Talos Vulnerability Report

TALOS-2017-0341

FreeRDP Rdp Client License Read Challenge Packet Denial of Service Vulnerability

July 24, 2017
CVE Number

CVE-2017-2839

Summary

An exploitable denial of service vulnerability exists within the handling of challenge packets in FreeRDP 2.0.0-beta1+android11. A specially crafted challenge packet can cause the program termination leading to a denial of service condition. An attacker can compromise the server or use man in the middle to trigger this vulnerability.

Tested Versions

FreeRDP 2.0.0-beta1+android11 - Windows, OSX, Linux

Product URLs

http://www.freerdp.com/

CVSSv3 Score

6.5 - CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H

CWE

CWE-252: Unchecked Return Value

Details

FreeRDP is a remote desktop protocol implementation available for all of the major operating systems. Many of the commercial remote desktop protocol applications actually use this library as their core. The vulnerability arises due to failure to check the return value result.

BOOL license_read_platform_challenge_packet(rdpLicense* license, wStream* s)
{
    BYTE MacData[16];
    UINT32 ConnectFlags = 0;

    if (Stream_GetRemainingLength(s) < 4)
        return FALSE;


    license->EncryptedPlatformChallenge->type = BB_ANY_BLOB;
    license_read_binary_blob(s, license->EncryptedPlatformChallenge);  [1]
    license->EncryptedPlatformChallenge->type = BB_ENCRYPTED_DATA_BLOB;

    if (Stream_GetRemainingLength(s) < 16)
        return FALSE;

    if (!license_decrypt_platform_challenge(license))  [2]

The license structure is populated at, [1],and a return value check is omitted. This newly populated license is then passed into a decryption function directly. Below is the code for license_read_binary_blob, [1].

BOOL license_read_binary_blob(wStream* s, LICENSE_BLOB* blob)
{
    UINT16 wBlobType;


    Stream_Read_UINT16(s, wBlobType); /* wBlobType (2 bytes) */
    Stream_Read_UINT16(s, blob->length); /* wBlobLen (2 bytes) */
    
    if (Stream_GetRemainingLength(s) < blob->length)  [3]
        return FALSE;
        
    ...
    
    blob->type = wBlobType;
    blob->data = (BYTE*) malloc(blob->length);   [4]

In the read_blob function we can see the length is read in directly from the packet and then checked against the stream length, [3]. This will exit the function if the check fails and return false. Recall that the previous function does not check the return value so the type blob->data,[4], will not be initialized. The license_decrypt_platform_challenge function is shown below:

BOOL license_decrypt_platform_challenge(rdpLicense* license)
{
    BOOL rc;
    WINPR_RC4_CTX* rc4;
    
    ...
    
    rc = winpr_RC4_Update(rc4, license->EncryptedPlatformChallenge->length,
               license->EncryptedPlatformChallenge->data,       [5]
               license->PlatformChallenge->data);

The license object is passed in and the EncryptedPlatformChallenge is used without validation, [5]. Recall the EncryptedPlatformChallenge data field is not set due to incorrect length so when the RC4 function attempts to use it a null pointer access happens and a denial of service condition arises.

Crash Information

Crashed thread log = 
: Dispatch queue: com.apple.main-thread
0   com.apple.CoreGraphics          0x00007fff9109bb34 blt_pattern_blend_XXXX32 + 608
1   com.apple.CoreGraphics          0x00007fff91058de4 argb32_mark + 19951
2   libRIP.A.dylib                  0x00007fff8f7e4cec RIPLayerBltShape + 1319
3   libRIP.A.dylib                  0x00007fff8f7e2713 ripc_Render + 319
4   libRIP.A.dylib                  0x00007fff8f7df1a2 ripc_DrawRects + 438
5   com.apple.AppKit                0x00007fff900577cd __backing_store_DrawRects_block_invoke + 39
6   com.apple.AppKit                0x00007fff90056a77 backing_store_delegate + 768
7   com.apple.AppKit                0x00007fff900564fb backing_store_DrawRects + 1047
8   com.apple.CoreGraphics          0x00007fff91050be7 CGContextFillRects + 107
9   com.apple.CoreGraphics          0x00007fff91050b79 CGContextFillRect + 134
10  com.apple.CoreGraphics          0x00007fff91098001 CGContextDrawImages + 3688
11  com.apple.coreui                0x00007fff98fb858e _CUITileImageWithOperation + 365
12  com.apple.coreui                0x00007fff98fb4e78 DrawOnePartElementFromRenditionWithOperation + 993
13  com.apple.coreui                0x00007fff98fbdc5a -[CUIThemeFacet 
_drawSpecificRenditionKey:rendition:inFrame:context:alpha:operation:isFocused:isFlipped:] + 594
14  com.apple.coreui                0x00007fff98fbd91a -[CUIThemeFacet 
_drawSpecificRenditionKey:inFrame:context:isFocused:isFlipped:] + 163
15  com.apple.coreui                0x00007fff98fbbc32 -[CUIThemeFacet drawInFrame:isFocused:context:] + 137
16  com.apple.coreui                0x00007fff98fd8f68 CUICoreThemeRenderer::DrawWindowFrameStandardNew(CUIDescriptor 
const*) + 1558
17  com.apple.coreui                0x00007fff98f5a065 CUIRenderer::Draw(CGRect, CGContext*, __CFDictionary const*, 
__CFDictionary const**) + 2341
18  com.apple.coreui                0x00007fff98f5c992 CUIDraw + 175
19  com.apple.AppKit                0x00007fff8ffeed25 __44-[NSAppearance _drawInRect:context:options:]_block_invoke + 64
20  com.apple.AppKit                0x00007fff8fe55e91 -[NSCompositeAppearance _callCoreUIWithBlock:] + 183
21  com.apple.AppKit                0x00007fff8ffeecde -[NSAppearance _drawInRect:context:options:] + 127
22  com.apple.AppKit                0x00007fff900c0699 -[NSThemeFrame _maskCorners:clipRect:] + 259
23  com.apple.AppKit                0x00007fff90612b0d -[NSThemeFrame _drawTransparentTitlebarInRect:] + 173
24  com.apple.AppKit                0x00007fff900bd6b3 -[NSThemeFrame _drawUnifiedToolbar:] + 181
25  com.apple.AppKit                0x00007fff900bd480 -[NSThemeFrame _drawTitleBar:] + 104
26  com.apple.AppKit                0x00007fff900bd411 -[NSThemeFrame _drawFrameInterior:clip:] + 83
27  com.apple.AppKit                0x00007fff900bd3b1 -[NSThemeFrame drawFrame:] + 892
28  com.apple.AppKit                0x00007fff900bcf98 -[NSFrameView drawRect:] + 1098
29  com.apple.AppKit                0x00007fff900bcb33 -[NSThemeFrame drawRect:] + 280
30  com.apple.AppKit                0x00007fff8fffcc86 -[NSView _drawRect:clip:] + 3550
31  com.apple.AppKit                0x00007fff8fffacf5 -[NSView 
_recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:] + 3136
32  com.apple.AppKit                0x00007fff8fff9be0 -[NSThemeFrame 
_recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:] + 334
33  com.apple.AppKit                0x00007fff8fff7feb -[NSView _displayRectIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:] 
+ 2449
34  com.apple.AppKit                0x00007fff8fff33f5 -[NSView displayIfNeeded] + 1950
35  com.apple.AppKit                0x00007fff8fff2c3c -[NSWindow displayIfNeeded] + 232
36  com.apple.AppKit                0x00007fff9067741b ___NSWindowGetDisplayCycleObserver_block_invoke6365 + 476
37  com.apple.AppKit                0x00007fff8fff25d6 __37+[NSDisplayCycle currentDisplayCycle]_block_invoke + 941
38  com.apple.QuartzCore            0x00007fff86da5f71 CA::Transaction::run_commit_handlers(CATransactionPhase) + 85
39  com.apple.QuartzCore            0x00007fff86da542c CA::Context::commit_transaction(CA::Transaction*) + 160
40  com.apple.QuartzCore            0x00007fff86da50ec CA::Transaction::commit() + 508
41  com.apple.QuartzCore            0x00007fff86db0977 CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned 
long, void*) + 71
42  com.apple.CoreFoundation        0x00007fff88e20067 
__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
43  com.apple.CoreFoundation        0x00007fff88e1ffd7 __CFRunLoopDoObservers + 391
44  com.apple.CoreFoundation        0x00007fff88dfeef8 CFRunLoopRunSpecific + 328
45  com.apple.HIToolbox             0x00007fff8f2b7935 RunCurrentEventLoopInMode + 235
46  com.apple.HIToolbox             0x00007fff8f2b7677 ReceiveNextEventCommon + 184
47  com.apple.HIToolbox             0x00007fff8f2b75af _BlockUntilNextEventMatchingListInModeWithFilter + 71
48  com.apple.AppKit                0x00007fff8fe9adf6 _DPSNextEvent + 1067
49  com.apple.AppKit                0x00007fff8fe9a226 -[NSApplication _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 
454
50  com.apple.AppKit                0x00007fff8fe8ed80 -[NSApplication run] + 682
51  com.apple.AppKit                0x00007fff8fe58368 NSApplicationMain + 1176
52  libdyld.dylib                   0x00007fff86cf45ad start + 1

log name is: ./crashlogs/1.crashlog.txt
---
exception=EXC_CRASH:signal=11:is_exploitable= no:instruction_disassembly=.byte 0xc4 #bad   
opcode:instruction_address=0x00007fff9109bb34:access_type=:access_address=0x0000000000000000:

Exploit Proof-of-Concept

Run included Python server and connect FreeRDP Client to it.

Timeline

2017-05-24 - Vendor Disclosure
2017-07-24 - Public Release

Credit

Discovered by Tyler Bohan of Cisco Talos.