yaSSL是一个开源的SSL的开发库。 yaSSL实现上存在多个远程溢出及无效内存访问问题,远程攻击者可能利用此漏洞控制服务器。 ------------------------------------------- A] ProcessOldClientHello缓冲区溢出 ------------------------------------------- 用于包含客户端所接收的Hello报文中的数据的缓冲区结构如下(源自yassl_imp.hpp): class ClientHello : public HandShakeBase { ProtocolVersion client_version_; Random random_; uint8 id_len_; // session id length opaque session_id_[ID_LEN]; uint16 suite_len_; // cipher suite length opaque cipher_suites_[MAX_SUITE_SZ]; uint8 comp_len_; // compression length CompressionMethod compression_methods_; ... 这里ID_LEN长度为32个单元,MAX_SUITE_SZ为64,RAN_LEN (Random)为32。如果接收到了旧版的Hello报文的话,所调用的ProcessOldClientHello函数没有执行必要的检查来限制填充上述3个字段的数据数量,导致缓冲区溢出漏洞。 以下是handshake.cpp中的漏洞代码: void ProcessOldClientHello(input_buffer& input, SSL& ssl) ... ClientHello ch; ... for (uint16 i = 0; i < ch.suite_len_; i += 3) { byte first = input[AUTO]; if (first) // sslv2 type input.read(len, SUITE_LEN); // skip else { input.read(&ch.cipher_suites_[j], SUITE_LEN); j += SUITE_LEN;...
yaSSL是一个开源的SSL的开发库。 yaSSL实现上存在多个远程溢出及无效内存访问问题,远程攻击者可能利用此漏洞控制服务器。 ------------------------------------------- A] ProcessOldClientHello缓冲区溢出 ------------------------------------------- 用于包含客户端所接收的Hello报文中的数据的缓冲区结构如下(源自yassl_imp.hpp): class ClientHello : public HandShakeBase { ProtocolVersion client_version_; Random random_; uint8 id_len_; // session id length opaque session_id_[ID_LEN]; uint16 suite_len_; // cipher suite length opaque cipher_suites_[MAX_SUITE_SZ]; uint8 comp_len_; // compression length CompressionMethod compression_methods_; ... 这里ID_LEN长度为32个单元,MAX_SUITE_SZ为64,RAN_LEN (Random)为32。如果接收到了旧版的Hello报文的话,所调用的ProcessOldClientHello函数没有执行必要的检查来限制填充上述3个字段的数据数量,导致缓冲区溢出漏洞。 以下是handshake.cpp中的漏洞代码: void ProcessOldClientHello(input_buffer& input, SSL& ssl) ... ClientHello ch; ... for (uint16 i = 0; i < ch.suite_len_; i += 3) { byte first = input[AUTO]; if (first) // sslv2 type input.read(len, SUITE_LEN); // skip else { input.read(&ch.cipher_suites_[j], SUITE_LEN); j += SUITE_LEN; } } ch.suite_len_ = j; if (ch.id_len_) input.read(ch.session_id_, ch.id_len_); if (randomLen < RAN_LEN) memset(ch.random_, 0, RAN_LEN - randomLen); input.read(&ch.random_[RAN_LEN - randomLen], randomLen); ... ------------------------------------------------ B] input_buffer& operator>>缓冲区溢出 ------------------------------------------------ 用于处理Hello报文的函数中存在另一个缓冲区溢出,但基本不太可能利用这个溢出执行代码。以下是yassl_imp.cpp中的漏洞代码: input_buffer& operator>>(input_buffer& input, ClientHello& hello) ... hello.id_len_ = input[AUTO]; if (hello.id_len_) input.read(hello.session_id_, ID_LEN); // Suites byte tmp[2]; tmp[0] = input[AUTO]; tmp[1] = input[AUTO]; ato16(tmp, hello.suite_len_); input.read(hello.cipher_suites_, hello.suite_len_); ... ----------------------------------------------------- C] HASHwithTransform::Update无效内存访问 ----------------------------------------------------- 在Hello报文中使用了过大的大小值会由于越界读取内存而导致函数库崩溃。以下是hash.cpp中的漏洞代码: void HASHwithTransform::Update(const byte* data, word32 len) { // do block size increment word32 blockSz = getBlockSize(); byte* local = reinterpret_cast<byte*>(buffer_); while (len) { word32 add = min(len, blockSz - buffLen_); memcpy(&local[buffLen_], data, add); ...