check stream sizes when reading ClientInfoPDU

This commit is contained in:
rdp.effort
2013-01-11 01:18:11 +01:00
parent dc967dcc89
commit f320fc3530
2 changed files with 54 additions and 17 deletions

View File

@@ -49,15 +49,18 @@ static const char* const INFO_TYPE_LOGON_STRINGS[] =
* @param settings settings
*/
void rdp_read_server_auto_reconnect_cookie(STREAM* s, rdpSettings* settings)
BOOL rdp_read_server_auto_reconnect_cookie(STREAM* s, rdpSettings* settings)
{
ARC_SC_PRIVATE_PACKET* autoReconnectCookie;
autoReconnectCookie = settings->ServerAutoReconnectCookie;
if(stream_get_left(s) < 4+4+4+16)
return FALSE;
stream_read_UINT32(s, autoReconnectCookie->cbLen); /* cbLen (4 bytes) */
stream_read_UINT32(s, autoReconnectCookie->version); /* version (4 bytes) */
stream_read_UINT32(s, autoReconnectCookie->logonId); /* LogonId (4 bytes) */
stream_read(s, autoReconnectCookie->arcRandomBits, 16); /* arcRandomBits (16 bytes) */
return TRUE;
}
/**
@@ -115,6 +118,8 @@ BOOL rdp_read_extended_info_packet(STREAM* s, rdpSettings* settings)
UINT16 cbClientDir;
UINT16 cbAutoReconnectLen;
if(stream_get_left(s) < 4)
return FALSE;
stream_read_UINT16(s, clientAddressFamily); /* clientAddressFamily */
stream_read_UINT16(s, cbClientAddress); /* cbClientAddress */
@@ -126,6 +131,8 @@ BOOL rdp_read_extended_info_packet(STREAM* s, rdpSettings* settings)
ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) stream_get_tail(s), cbClientAddress / 2, &settings->ClientAddress, 0, NULL, NULL);
stream_seek(s, cbClientAddress);
if(stream_get_left(s) < 2)
return FALSE;
stream_read_UINT16(s, cbClientDir); /* cbClientDir */
if (stream_get_left(s) < cbClientDir)
@@ -140,6 +147,8 @@ BOOL rdp_read_extended_info_packet(STREAM* s, rdpSettings* settings)
if (!rdp_read_client_time_zone(s, settings))
return FALSE;
if(stream_get_left(s) < 10)
return FALSE;
stream_seek_UINT32(s); /* clientSessionId, should be set to 0 */
stream_read_UINT32(s, settings->PerformanceFlags); /* performanceFlags */
@@ -225,6 +234,9 @@ BOOL rdp_read_info_packet(STREAM* s, rdpSettings* settings)
UINT16 cbAlternateShell;
UINT16 cbWorkingDir;
if(stream_get_left(s) < 18) // invalid packet
return FALSE;
stream_seek_UINT32(s); /* CodePage */
stream_read_UINT32(s, flags); /* flags */
@@ -468,53 +480,71 @@ BOOL rdp_send_client_info(rdpRdp* rdp)
return rdp_send(rdp, s, MCS_GLOBAL_CHANNEL_ID);
}
void rdp_recv_logon_info_v1(rdpRdp* rdp, STREAM* s)
BOOL rdp_recv_logon_info_v1(rdpRdp* rdp, STREAM* s)
{
UINT32 cbDomain;
UINT32 cbUserName;
if(stream_get_left(s) < 4+52+4+512+4)
return FALSE;
stream_read_UINT32(s, cbDomain); /* cbDomain (4 bytes) */
stream_seek(s, 52); /* domain (52 bytes) */
stream_read_UINT32(s, cbUserName); /* cbUserName (4 bytes) */
stream_seek(s, 512); /* userName (512 bytes) */
stream_seek_UINT32(s); /* sessionId (4 bytes) */
return TRUE;
}
void rdp_recv_logon_info_v2(rdpRdp* rdp, STREAM* s)
BOOL rdp_recv_logon_info_v2(rdpRdp* rdp, STREAM* s)
{
UINT32 cbDomain;
UINT32 cbUserName;
if(stream_get_left(s) < 2+4+4+4+4+558)
return FALSE;
stream_seek_UINT16(s); /* version (2 bytes) */
stream_seek_UINT32(s); /* size (4 bytes) */
stream_seek_UINT32(s); /* sessionId (4 bytes) */
stream_read_UINT32(s, cbDomain); /* cbDomain (4 bytes) */
stream_read_UINT32(s, cbUserName); /* cbUserName (4 bytes) */
stream_seek(s, 558); /* pad */
if(stream_get_left(s) < cbDomain+cbUserName)
return FALSE;
stream_seek(s, cbDomain); /* domain */
stream_seek(s, cbUserName); /* userName */
return TRUE;
}
void rdp_recv_logon_plain_notify(rdpRdp* rdp, STREAM* s)
BOOL rdp_recv_logon_plain_notify(rdpRdp* rdp, STREAM* s)
{
if(stream_get_left(s) < 576)
return FALSE;
stream_seek(s, 576); /* pad */
return TRUE;
}
void rdp_recv_logon_error_info(rdpRdp* rdp, STREAM* s)
BOOL rdp_recv_logon_error_info(rdpRdp* rdp, STREAM* s)
{
UINT32 errorNotificationType;
UINT32 errorNotificationData;
if(stream_get_left(s) < 4)
return FALSE;
stream_read_UINT32(s, errorNotificationType); /* errorNotificationType (4 bytes) */
stream_read_UINT32(s, errorNotificationData); /* errorNotificationData (4 bytes) */
return TRUE;
}
void rdp_recv_logon_info_extended(rdpRdp* rdp, STREAM* s)
BOOL rdp_recv_logon_info_extended(rdpRdp* rdp, STREAM* s)
{
UINT32 cbFieldData;
UINT32 fieldsPresent;
UINT16 Length;
if(stream_get_left(s) < 6)
return FALSE;
stream_read_UINT16(s, Length); /* The total size in bytes of this structure */
stream_read_UINT32(s, fieldsPresent); /* fieldsPresent (4 bytes) */
@@ -522,23 +552,34 @@ void rdp_recv_logon_info_extended(rdpRdp* rdp, STREAM* s)
if (fieldsPresent & LOGON_EX_AUTORECONNECTCOOKIE)
{
if(stream_get_left(s) < 4)
return FALSE;
stream_read_UINT32(s, cbFieldData); /* cbFieldData (4 bytes) */
rdp_read_server_auto_reconnect_cookie(s, rdp->settings);
if(rdp_read_server_auto_reconnect_cookie(s, rdp->settings) == FALSE)
return FALSE;
}
if (fieldsPresent & LOGON_EX_LOGONERRORS)
{
if(stream_get_left(s) < 4)
return FALSE;
stream_read_UINT32(s, cbFieldData); /* cbFieldData (4 bytes) */
rdp_recv_logon_error_info(rdp, s);
if(rdp_recv_logon_error_info(rdp, s) == FALSE)
return FALSE;
}
if(stream_get_left(s) < 570)
return FALSE;
stream_seek(s, 570); /* pad */
return TRUE;
}
BOOL rdp_recv_save_session_info(rdpRdp* rdp, STREAM* s)
{
UINT32 infoType;
if(stream_get_left(s) < 4)
return FALSE;
stream_read_UINT32(s, infoType); /* infoType (4 bytes) */
//printf("%s\n", INFO_TYPE_LOGON_STRINGS[infoType]);
@@ -546,20 +587,16 @@ BOOL rdp_recv_save_session_info(rdpRdp* rdp, STREAM* s)
switch (infoType)
{
case INFO_TYPE_LOGON:
rdp_recv_logon_info_v1(rdp, s);
break;
return rdp_recv_logon_info_v1(rdp, s);
case INFO_TYPE_LOGON_LONG:
rdp_recv_logon_info_v2(rdp, s);
break;
return rdp_recv_logon_info_v2(rdp, s);
case INFO_TYPE_LOGON_PLAIN_NOTIFY:
rdp_recv_logon_plain_notify(rdp, s);
break;
return rdp_recv_logon_plain_notify(rdp, s);
case INFO_TYPE_LOGON_EXTENDED_INF:
rdp_recv_logon_info_extended(rdp, s);
break;
return rdp_recv_logon_info_extended(rdp, s);
default:
break;

View File

@@ -75,7 +75,7 @@ void rdp_write_system_time(STREAM* s, SYSTEM_TIME* system_time);
void rdp_get_client_time_zone(STREAM* s, rdpSettings* settings);
BOOL rdp_read_client_time_zone(STREAM* s, rdpSettings* settings);
void rdp_write_client_time_zone(STREAM* s, rdpSettings* settings);
void rdp_read_server_auto_reconnect_cookie(STREAM* s, rdpSettings* settings);
BOOL rdp_read_server_auto_reconnect_cookie(STREAM* s, rdpSettings* settings);
BOOL rdp_read_client_auto_reconnect_cookie(STREAM* s, rdpSettings* settings);
void rdp_write_client_auto_reconnect_cookie(STREAM* s, rdpSettings* settings);
void rdp_write_auto_reconnect_cookie(STREAM* s, rdpSettings* settings);