CVE-2017-2835
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.
FreeRDP 2.0.0-beta1+android11 - Windows, OSX, Linux
8.8 - CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:H
CWE-129: Improper Validation of Array Index
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 |................|
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 '
Run included Python server and connect FreeRDP Client to it.
2017-05-24 - Vendor Disclosure
2017-07-24 - Public Release
Discovered by Tyler Bohan of Cisco Talos.