Talos Vulnerability Report

TALOS-2017-0338

FreeRDP Rdp Client Read Server Proprietary Certificate Denial of Service Vulnerability

July 24, 2017
CVE Number

CVE-2017-2836

Summary

An exploitable denial of service vulnerability exists within the reading of proprietary server certificates 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-190: Integer Overflow or Wraparound

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 in the parsing of proprietary certificates.

static BOOL certificate_process_server_public_key(rdpCertificate* certificate, wStream* s, UINT32 length)
{
    BYTE magic[4];
    UINT32 keylen;
    UINT32 bitlen;
    UINT32 datalen;
    UINT32 modlen;

    ... 

    Stream_Read_UINT32(s, keylen);
    Stream_Read_UINT32(s, bitlen);
    Stream_Read_UINT32(s, datalen);   
    modlen = keylen - 8;  [1]

    if (Stream_GetRemainingLength(s) < modlen + 8)  // count padding  [2]
        return FALSE;

    certificate->cert_info.ModulusLength = modlen;
    certificate->cert_info.Modulus = malloc(certificate->cert_info.ModulusLength);   [3]

    if (!certificate->cert_info.Modulus)
        return FALSE;

    Stream_Read(s, certificate->cert_info.Modulus, certificate->cert_info.ModulusLength);   [4]

In processing a servers proprietary certificate, the function calls out to read the public key. It takes the key length directly from the packet and decrements eight from it, [1]. It then does a check on the length by adding the eight back and comparing it to the stream length. The vulnerability arises here when a value less than eight is passed in. It passes the check but wraps around and causes a large allocation to be made, [3]. The denial of service arises at, [4] when the stream is now read into the oversized buffer and an out-of-bounds read occurs.

Crash Information

Crashed thread log = 
: Dispatch queue: com.apple.main-thread
0   com.apple.CoreGraphics          0x00007fff8e8fc4de argb32_image_mark_RGB32 + 423
1   com.apple.CoreGraphics          0x00007fff8e8fc29d argb32_image_mark_image + 1085
2   com.apple.CoreGraphics          0x00007fff8e8b3d92 argb32_image + 5050
3   libRIP.A.dylib                  0x00007fff8d02d4f2 ripl_Mark + 23
4   libRIP.A.dylib                  0x00007fff8d02d491 RIPLayerBltImage + 1185
5   libRIP.A.dylib                  0x00007fff8d02ad0a ripc_DrawImage + 1151
6   com.apple.CoreGraphics          0x00007fff8e90d37f CGContextDelegateDrawImage + 48
7   com.apple.AppKit                0x00007fff8d89b1c8 __backing_store_DrawImage_block_invoke + 70
8   com.apple.AppKit                0x00007fff8d896a77 backing_store_delegate + 768
9   com.apple.AppKit                0x00007fff8d89b137 backing_store_DrawImage + 525
10  com.apple.CoreGraphics          0x00007fff8e8a1813 CGContextDrawImageWithOptions + 571
11  com.apple.CoreGraphics          0x00007fff8e8d7b23 CGContextDrawImages + 2442
12  com.apple.coreui                0x00007fff967f7cce DrawNinePartImageWithOperation + 5357
13  com.apple.coreui                0x00007fff967f67c2 DrawNinePartElementFromRenditionWithOperation + 471
14  com.apple.coreui                0x00007fff967fdcce -[CUIThemeFacet 
_drawSpecificRenditionKey:rendition:inFrame:context:alpha:operation:isFocused:isFlipped:] + 710
15  com.apple.coreui                0x00007fff967fd91a -[CUIThemeFacet 
_drawSpecificRenditionKey:inFrame:context:isFocused:isFlipped:] + 163
16  com.apple.coreui                0x00007fff967fbc32 -[CUIThemeFacet drawInFrame:isFocused:context:] + 137
17  com.apple.coreui                0x00007fff96819500 CUICoreThemeRenderer::DrawWindowFrameStandardNew(CUIDescriptor 
const*) + 2990
18  com.apple.coreui                0x00007fff9679a065 CUIRenderer::Draw(CGRect, CGContext*, __CFDictionary const*, 
__CFDictionary const**) + 2341
19  com.apple.coreui                0x00007fff9679c992 CUIDraw + 175
20  com.apple.AppKit                0x00007fff8d82ed25 __44-[NSAppearance _drawInRect:context:options:]_block_invoke + 64
21  com.apple.AppKit                0x00007fff8d695e91 -[NSCompositeAppearance _callCoreUIWithBlock:] + 183
22  com.apple.AppKit                0x00007fff8d82ecde -[NSAppearance _drawInRect:context:options:] + 127
23  com.apple.AppKit                0x00007fff8d900699 -[NSThemeFrame _maskCorners:clipRect:] + 259
24  com.apple.AppKit                0x00007fff8de52b0d -[NSThemeFrame _drawTransparentTitlebarInRect:] + 173
25  com.apple.AppKit                0x00007fff8d8fd6b3 -[NSThemeFrame _drawUnifiedToolbar:] + 181
26  com.apple.AppKit                0x00007fff8d8fd480 -[NSThemeFrame _drawTitleBar:] + 104
27  com.apple.AppKit                0x00007fff8d8fd411 -[NSThemeFrame _drawFrameInterior:clip:] + 83
28  com.apple.AppKit                0x00007fff8d8fd3b1 -[NSThemeFrame drawFrame:] + 892
29  com.apple.AppKit                0x00007fff8d8fcf98 -[NSFrameView drawRect:] + 1098
30  com.apple.AppKit                0x00007fff8d8fcb33 -[NSThemeFrame drawRect:] + 280
31  com.apple.AppKit                0x00007fff8d83cc86 -[NSView _drawRect:clip:] + 3550
32  com.apple.AppKit                0x00007fff8d83acf5 -[NSView 
_recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:] + 3136
33  com.apple.AppKit                0x00007fff8d839be0 -[NSThemeFrame 
_recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:] + 334
34  com.apple.AppKit                0x00007fff8d837feb -[NSView 
_displayRectIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:] + 2449
35  com.apple.AppKit                0x00007fff8d8333f5 -[NSView displayIfNeeded] + 1950
36  com.apple.AppKit                0x00007fff8d832c3c -[NSWindow displayIfNeeded] + 232
37  com.apple.AppKit                0x00007fff8deb741b ___NSWindowGetDisplayCycleObserver_block_invoke6365 + 476
38  com.apple.AppKit                0x00007fff8d8325d6 __37+[NSDisplayCycle currentDisplayCycle]_block_invoke + 941
39  com.apple.QuartzCore            0x00007fff845e5f71 CA::Transaction::run_commit_handlers(CATransactionPhase) + 85
40  com.apple.QuartzCore            0x00007fff845e542c CA::Context::commit_transaction(CA::Transaction*) + 160
41  com.apple.QuartzCore            0x00007fff845e50ec CA::Transaction::commit() + 508
42  com.apple.QuartzCore            0x00007fff845f0977 CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned 
long, void*) + 71
43  com.apple.CoreFoundation        0x00007fff86660067 
__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
44  com.apple.CoreFoundation        0x00007fff8665ffd7 __CFRunLoopDoObservers + 391
45  com.apple.CoreFoundation        0x00007fff8663eef8 CFRunLoopRunSpecific + 328
46  com.apple.HIToolbox             0x00007fff8caf7935 RunCurrentEventLoopInMode + 235
47  com.apple.HIToolbox             0x00007fff8caf7677 ReceiveNextEventCommon + 184
48  com.apple.HIToolbox             0x00007fff8caf75af _BlockUntilNextEventMatchingListInModeWithFilter + 71
49  com.apple.AppKit                0x00007fff8d6dadf6 _DPSNextEvent + 1067
50  com.apple.AppKit                0x00007fff8d6da226 -[NSApplication _nextEventMatchingEventMask:untilDate:inMode:dequeue:]     + 454
51  com.apple.AppKit                0x00007fff8d6ced80 -[NSApplication run] + 682
52  com.apple.AppKit                0x00007fff8d698368 NSApplicationMain + 1176
53  libdyld.dylib                   0x00007fff845345ad start + 1

log name is: ./crashlogs/1.crashlog.txt
---
exception=EXC_CRASH:signal=11:is_exploitable= no:instruction_disassembly=cmpq   $CONSTANT,%rax:instruction_address=0x00007fff8e8fc4de: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.