MatrixSSL 会话恢复漏洞
MatrixSSL 4.5.1-open 及更早版本中存在一个问题,导致无法安全检查 SessionID 字段,从而导致滥用全零 MasterSecret,进而可以解密机密数据。
MatrixSSL 4.5.1-open 及更早版本
TLS 恢复会话解密
MatrixSSL 服务器通过一个列表来存储协商的会话信息。
static sslSessionEntry_t g_sessionTable[SSL_SESSION_TABLE_SIZE];
// SSL_SESSION_TABLE_SIZE is 32
typedef struct
{
unsigned char id[SSL_MAX_SESSION_ID_SIZE]; // 32
unsigned char masterSecret[SSL_HS_MASTER_SIZE]; // 48
const sslCipherSpec_t *cipher;
unsigned char majVer;
unsigned char minVer;
short extendedMasterSecret; /* was the extension used? */
psTime_t startTime;
int32 inUse;
DLListEntry chronList;
} sslSessionEntry_t;
SessionID 字段的前四个字节是一个小端序序列号,范围从 0 到 31。

MatrixSSL 通过将接收到的会话 ID 的长度与四字节快速索引进行匹配,来判断会话是否为恢复会话。
然而,当存储列表初始化时,MasterSecret 全为零。
因此,恶意客户端可以发送一个字节的 SessionID 来尝试使用全零 MasterSecret 进行会话恢复。当服务器接收到一个字节的 sessionid 时,后续字节默认为 0。因此,它可以被验证并索引到列表中,而列表中对应序列号的 MasterSecret 可能仍为 0。如果发生这种情况,我们就能计算出密钥并解密 TLS 通信数据。
./matrixssl/matrixssl.c —> int32 matrixResumeSession(ssl_t *ssl)


添加用于调试的控制台输出:

测试结果:


使用全零 MasterSecret 进行解密!
