Talos Vulnerability Report

TALOS-2017-0337

FreeRDP Rdp Client Recv RDP Code Execution Vulnerability

July 24, 2017
CVE Number

CVE-2017-2835

Summary

An exploitable code execution vulnerability exists in the RDP receive 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 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 reception of a RDP packet with the server.

static int rdp_recv_tpkt_pdu(rdpRdp* rdp, wStream* s)
{
    UINT16 length;
    UINT16 pduType;
    UINT16 pduLength;
    UINT16 pduSource;
    UINT16 channelId = 0;
    UINT16 securityFlags = 0;
    int nextPosition;


    if (!rdp_read_header(rdp, s, &length, &channelId)) [1]
    {   

    ...

    if (rdp->settings->UseRdpSecurityLayer)
    {
        if (!rdp_read_security_header(s, &securityFlags)) [2]
        {
            ...

        if (securityFlags & (SEC_ENCRYPT | SEC_REDIRECTION_PKT))
        {
            if (!rdp_decrypt(rdp, s, length - 4, securityFlags)) [3]
            {

At [1], the RDP header is read in and a local variable, length, is assigned a value directly from the attacker controlled packet. Another value, [2], is read in from the packet to determine if encryption is set on this packet. This check is simply anding a value in the packet with a constant and is easily passed. The value of length is then subtracted from four, [3], 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 00 28 02 f0 80 68  00 01 03 eb 70 [03] 08 04  |...(...h....p...| <-------
00000010  00 00 16 00 17 00 ea 03  ea 03 01 00 00 01 08 00  |................|
00000020  1f 00 00 00 01 00 ea 03  03 00 00 2c 02 f0 80 68  |...........,...h|
00000030  00 01 03 eb 70 1e 00 00  00 00 1a 00 17 00 ea 03  |....p...........|
00000040  ea 03 01 00 00 01 0c 00  14 00 00 00 04 00 00 00  |................|
00000050  ea 03 00 00 03 00 00 2c  02 f0 80 68 00 01 03 eb  |.......,...h....|
00000060  70 1e 00 00 00 00 1a 00  17 00 ea 03 ea 03 01 00  |p...............|
00000070  00 01 0c 00 14 00 00 00  02 00 00 00 ea 03 00 00  |................|
00000080  03 00 00 d1 02 f0 80 68  00 01 03 eb 70 80 c2 00  |.......h....p...|
00000090  00 00 00 be 00 17 00 ea  03 ea 03 01 00 00 01 b0  |................|

Crash Information

Crashed thread log = 
: Dispatch queue: com.apple.main-thread
0   libgmalloc.dylib                0x00000001037ef54a GuardMalloc_mallocInternal + 1136
1   libgmalloc.dylib                0x00000001037eee70 GuardMalloc_calloc + 81
2   libsystem_malloc.dylib          0x00007fff94c2b9a6 malloc_zone_calloc + 78
3   libsystem_malloc.dylib          0x00007fff94c2c462 calloc + 49
4   libobjc.A.dylib                 0x00007fff9988a330 allocateBuckets(unsigned int) + 30
5   libobjc.A.dylib                 0x00007fff9987fc53 cache_t::reallocate(unsigned int, unsigned int) + 43
6   libobjc.A.dylib                 0x00007fff9987f693 cache_fill + 177
7   libobjc.A.dylib                 0x00007fff9987edfc lookUpImpOrForward + 423
8   libobjc.A.dylib                 0x00007fff99879591 objc_msgSend + 209
9   com.apple.AppKit                0x00007fff8ffa8a52 -[NSCell dealloc] + 364
10  com.apple.AppKit                0x00007fff8ffa88cd -[NSActionCell dealloc] + 116
11  com.apple.AppKit                0x00007fff8ffa8dfd -[NSButtonCell dealloc] + 395
12  com.apple.AppKit                0x00007fff8ffa85b9 -[NSControl dealloc] + 83
13  com.apple.AppKit                0x00007fff9018d510 -[NSAlert dealloc] + 104
14  com.apple.CoreFoundation        0x00007fff88dab5a8 -[__NSArrayI dealloc] + 120
15  libobjc.A.dylib                 0x00007fff9987eb3b (anonymous namespace)::AutoreleasePoolPage::pop(void*) + 477
16  com.apple.CoreFoundation        0x00007fff88dbec12 _CFAutoreleasePoolPop + 50
17  com.apple.Foundation            0x00007fff887659ea -[NSAutoreleasePool drain] + 153
18  com.apple.Foundation            0x00007fff887a25ba _NSAppleEventManagerGenericHandler + 121
19  com.apple.AE                    0x00007fff87c47261 aeDispatchAppleEvent(AEDesc const*, AEDesc*, unsigned int, unsigned char*) 
+ 531
20  com.apple.AE                    0x00007fff87c46fe8 dispatchEventAndSendReply(AEDesc const*, AEDesc*) + 31
21  com.apple.AE                    0x00007fff87c46f04 aeProcessAppleEvent + 288
22  com.apple.HIToolbox             0x00007fff8f2c7af9 AEProcessAppleEvent + 55
23  com.apple.AppKit                0x00007fff8fe9b290 _DPSNextEvent + 2245
24  com.apple.AppKit                0x00007fff8fe9a226 -[NSApplication _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 
454
25  com.apple.AppKit                0x00007fff8fe8ed80 -[NSApplication run] + 682
26  com.apple.AppKit                0x00007fff8fe58368 NSApplicationMain + 1176
27  libdyld.dylib                   0x00007fff86cf45ad start + 1

log name is: ./crashlogs/1.crashlog.txt
---
exception=EXC_CRASH:signal=11:is_exploitable=yes:instruction_disassembly=movq   %rax,CONSTANT(%rdi,%rsi):instruction_address=0x00000001037ef54a: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: ' calloc ' 

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.