Skip to content

Commit 4dca546

Browse files
committed
Malicious RDP server security fixes
This commit includes fixes for a set of 21 vulnerabilities in rdesktop when a malicious RDP server is used. All vulnerabilities was identified and reported by Eyal Itkin. * Add rdp_protocol_error function that is used in several fixes * Refactor of process_bitmap_updates * Fix possible integer overflow in s_check_rem() on 32bit arch * Fix memory corruption in process_bitmap_data - CVE-2018-8794 * Fix remote code execution in process_bitmap_data - CVE-2018-8795 * Fix remote code execution in process_plane - CVE-2018-8797 * Fix Denial of Service in mcs_recv_connect_response - CVE-2018-20175 * Fix Denial of Service in mcs_parse_domain_params - CVE-2018-20175 * Fix Denial of Service in sec_parse_crypt_info - CVE-2018-20176 * Fix Denial of Service in sec_recv - CVE-2018-20176 * Fix minor information leak in rdpdr_process - CVE-2018-8791 * Fix Denial of Service in cssp_read_tsrequest - CVE-2018-8792 * Fix remote code execution in cssp_read_tsrequest - CVE-2018-8793 * Fix Denial of Service in process_bitmap_data - CVE-2018-8796 * Fix minor information leak in rdpsnd_process_ping - CVE-2018-8798 * Fix Denial of Service in process_secondary_order - CVE-2018-8799 * Fix remote code execution in in ui_clip_handle_data - CVE-2018-8800 * Fix major information leak in ui_clip_handle_data - CVE-2018-20174 * Fix memory corruption in rdp_in_unistr - CVE-2018-20177 * Fix Denial of Service in process_demand_active - CVE-2018-20178 * Fix remote code execution in lspci_process - CVE-2018-20179 * Fix remote code execution in rdpsnddbg_process - CVE-2018-20180 * Fix remote code execution in seamless_process - CVE-2018-20181 * Fix remote code execution in seamless_process_line - CVE-2018-20182
1 parent 1f13bf5 commit 4dca546

16 files changed

+250
-71
lines changed

Diff for: asn.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323
/* Parse an ASN.1 BER header */
2424
RD_BOOL
25-
ber_parse_header(STREAM s, int tagval, int *length)
25+
ber_parse_header(STREAM s, int tagval, uint32 *length)
2626
{
2727
int tag, len;
2828

Diff for: bitmap.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -794,15 +794,15 @@ process_plane(uint8 * in, int width, int height, uint8 * out, int size)
794794
replen = revcode;
795795
collen = 0;
796796
}
797-
while (collen > 0)
797+
while (indexw < width && collen > 0)
798798
{
799799
color = CVAL(in);
800800
*out = color;
801801
out += 4;
802802
indexw++;
803803
collen--;
804804
}
805-
while (replen > 0)
805+
while (indexw < width && replen > 0)
806806
{
807807
*out = color;
808808
out += 4;
@@ -824,7 +824,7 @@ process_plane(uint8 * in, int width, int height, uint8 * out, int size)
824824
replen = revcode;
825825
collen = 0;
826826
}
827-
while (collen > 0)
827+
while (indexw < width && collen > 0)
828828
{
829829
x = CVAL(in);
830830
if (x & 1)
@@ -844,7 +844,7 @@ process_plane(uint8 * in, int width, int height, uint8 * out, int size)
844844
indexw++;
845845
collen--;
846846
}
847-
while (replen > 0)
847+
while (indexw < width && replen > 0)
848848
{
849849
x = last_line[indexw * 4] + color;
850850
*out = x;

Diff for: cliprdr.c

+6
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ cliprdr_process(STREAM s)
118118
uint16 type, status;
119119
uint32 length, format;
120120
uint8 *data;
121+
struct stream packet = *s;
121122

122123
in_uint16_le(s, type);
123124
in_uint16_le(s, status);
@@ -127,6 +128,11 @@ cliprdr_process(STREAM s)
127128
logger(Clipboard, Debug, "cliprdr_process(), type=%d, status=%d, length=%d", type, status,
128129
length);
129130

131+
if (!s_check_rem(s, length))
132+
{
133+
rdp_protocol_error("cliprdr_process(), consume of packet from stream would overrun", &packet);
134+
}
135+
130136
if (status == CLIPRDR_ERROR)
131137
{
132138
switch (type)

Diff for: constants.h

+3
Original file line numberDiff line numberDiff line change
@@ -751,6 +751,9 @@ enum RDP_DESKTOP_ORIENTATION
751751
#define ENC_SALTED_CHECKSUM 0x0010
752752
#define NO_BITMAP_COMPRESSION_HDR 0x0400
753753

754+
/* [MS-RDPBCGR], TS_BITMAP_DATA, flags */
755+
#define BITMAP_COMPRESSION 0x0001
756+
754757
/* orderFlags, [MS-RDPBCGR] 2.2.7.1.3 */
755758
#define NEGOTIATEORDERSUPPORT 0x0002
756759
#define ZEROBOUNDSDELTASSUPPORT 0x0008

Diff for: cssp.c

+16-1
Original file line numberDiff line numberDiff line change
@@ -595,6 +595,7 @@ cssp_read_tsrequest(STREAM token, STREAM pubkey)
595595
STREAM s;
596596
int length;
597597
int tagval;
598+
struct stream packet;
598599

599600
s = tcp_recv(NULL, 4);
600601

@@ -622,6 +623,7 @@ cssp_read_tsrequest(STREAM token, STREAM pubkey)
622623

623624
// receive the remainings of message
624625
s = tcp_recv(s, length);
626+
packet = *s;
625627

626628
// parse the response and into nego token
627629
if (!ber_in_header(s, &tagval, &length) ||
@@ -632,6 +634,12 @@ cssp_read_tsrequest(STREAM token, STREAM pubkey)
632634
if (!ber_in_header(s, &tagval, &length) ||
633635
tagval != (BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 0))
634636
return False;
637+
638+
if (!s_check_rem(s, length))
639+
{
640+
rdp_protocol_error("cssp_read_tsrequest(), consume of version from stream would overrun",
641+
&packet);
642+
}
635643
in_uint8s(s, length);
636644

637645
// negoToken [1]
@@ -653,7 +661,14 @@ cssp_read_tsrequest(STREAM token, STREAM pubkey)
653661
if (!ber_in_header(s, &tagval, &length) || tagval != BER_TAG_OCTET_STRING)
654662
return False;
655663

656-
token->end = token->p = token->data;
664+
if (!s_check_rem(s, length))
665+
{
666+
rdp_protocol_error("cssp_read_tsrequest(), consume of token from stream would overrun",
667+
&packet);
668+
}
669+
670+
s_realloc(token, length);
671+
s_reset(token);
657672
out_uint8p(token, s->p, length);
658673
s_mark_end(token);
659674
}

Diff for: lspci.c

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
/* -*- c-basic-offset: 8 -*-
22
rdesktop: A Remote Desktop Protocol client.
33
Support for the Matrox "lspci" channel
4-
Copyright (C) 2005 Matrox Graphics Inc.
4+
Copyright (C) 2005 Matrox Graphics Inc.
5+
Copyright 2018 Henrik Andersson <hean01@cendio.se> for Cendio AB
56
67
This program is free software: you can redistribute it and/or modify
78
it under the terms of the GNU General Public License as published by
@@ -134,6 +135,12 @@ lspci_process(STREAM s)
134135
unsigned int pkglen;
135136
static char *rest = NULL;
136137
char *buf;
138+
struct stream packet = *s;
139+
140+
if (!s_check(s))
141+
{
142+
rdp_protocol_error("lspci_process(), stream is in unstable state", &packet);
143+
}
137144

138145
pkglen = s->end - s->p;
139146
/* str_handle_lines requires null terminated strings */

Diff for: mcs.c

+18-2
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,16 @@ mcs_out_domain_params(STREAM s, int max_channels, int max_users, int max_tokens,
4545
static RD_BOOL
4646
mcs_parse_domain_params(STREAM s)
4747
{
48-
int length;
48+
uint32 length;
49+
struct stream packet = *s;
4950

5051
ber_parse_header(s, MCS_TAG_DOMAIN_PARAMS, &length);
52+
53+
if (!s_check_rem(s, length))
54+
{
55+
rdp_protocol_error("mcs_parse_domain_params(), consume domain params from stream would overrun", &packet);
56+
}
57+
5158
in_uint8s(s, length);
5259

5360
return s_check(s);
@@ -89,8 +96,9 @@ mcs_recv_connect_response(STREAM mcs_data)
8996
{
9097
UNUSED(mcs_data);
9198
uint8 result;
92-
int length;
99+
uint32 length;
93100
STREAM s;
101+
struct stream packet;
94102
RD_BOOL is_fastpath;
95103
uint8 fastpath_hdr;
96104

@@ -99,6 +107,8 @@ mcs_recv_connect_response(STREAM mcs_data)
99107

100108
if (s == NULL)
101109
return False;
110+
111+
packet = *s;
102112

103113
ber_parse_header(s, MCS_CONNECT_RESPONSE, &length);
104114

@@ -112,6 +122,12 @@ mcs_recv_connect_response(STREAM mcs_data)
112122

113123
ber_parse_header(s, BER_TAG_INTEGER, &length);
114124
in_uint8s(s, length); /* connect id */
125+
126+
if (!s_check_rem(s, length))
127+
{
128+
rdp_protocol_error("mcs_recv_connect_response(), consume connect id from stream would overrun", &packet);
129+
}
130+
115131
mcs_parse_domain_params(s);
116132

117133
ber_parse_header(s, BER_TAG_OCTET_STRING, &length);

Diff for: orders.c

+6
Original file line numberDiff line numberDiff line change
@@ -1259,11 +1259,17 @@ process_secondary_order(STREAM s)
12591259
uint16 flags;
12601260
uint8 type;
12611261
uint8 *next_order;
1262+
struct stream packet = *s;
12621263

12631264
in_uint16_le(s, length);
12641265
in_uint16_le(s, flags); /* used by bmpcache2 */
12651266
in_uint8(s, type);
12661267

1268+
if (!s_check_rem(s, length + 7))
1269+
{
1270+
rdp_protocol_error("process_secondary_order(), next order pointer would overrun stream", &packet);
1271+
}
1272+
12671273
next_order = s->p + (sint16) length + 7;
12681274

12691275
switch (type)

Diff for: proto.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ RD_BOOL rdp_connect(char *server, uint32 flags, char *domain, char *password, ch
164164
char *directory, RD_BOOL reconnect);
165165
void rdp_reset_state(void);
166166
void rdp_disconnect(void);
167+
void rdp_protocol_error(const char *message, STREAM s);
167168
/* rdpdr.c */
168169
int get_device_index(RD_NTHANDLE handle);
169170
void convert_to_unix_filename(char *filename);
@@ -224,7 +225,7 @@ void tcp_run_ui(RD_BOOL run);
224225
/* asn.c */
225226
RD_BOOL ber_in_header(STREAM s, int *tagval, int *length);
226227
void ber_out_header(STREAM s, int tagval, int length);
227-
RD_BOOL ber_parse_header(STREAM s, int tagval, int *length);
228+
RD_BOOL ber_parse_header(STREAM s, int tagval, uint32 *length);
228229
void ber_out_integer(STREAM s, int value);
229230
void ber_out_sequence(STREAM s, STREAM contents);
230231

0 commit comments

Comments
 (0)