# MySQL yaSSL SSL Hello Message Buffer Overflow
1. 漏洞介绍和分析
yaSSL是用于实现SSL的开源软件包。
yaSSL实现上存在多个远程溢出及无效内存访问问题,远程攻击者可能利用此漏洞控制服务器。
向堆栈缓冲区溢出的yaSSL(1.7.5和更早的版本)实现与MySQL捆绑< = 6.0。通过发送一个专门制作的HEllo 包 ,攻击者可以执行任意代码。
代码分析:
用于包含客户端所接收的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 increments
word32 blockSz = getBlockSize();
byte* local = reinterpret_cast(buffer_);
while (len) {
word32 add = min(len, blockSz - buffLen_);
memcpy(&local[buffLen_], data, add);
...
}
利用如下payload 发送我们构造的hello packeg 导致缓冲区溢出

2.漏洞修复
目前厂商已经发布了升级补丁以修复这个安全问题,补丁下载链接:
Apple Mac OS X Server 10.4.11
Apple SecUpdSrvr2008-007PPC.dmg
(PPC)
http://www.apple.com/support/downloads/securityupdate2008007serverppc. html
Apple SecUpdSrvr2008-007Univ.dmg
(Universal)
http://www.apple.com/support/downloads/securityupdate2008007serveruniv ersal.html
Apple Mac OS X 10.4.11
Apple SecUpd2008-007Intel.dmg
(Intel)
http://www.apple.com/support/downloads/securityupdate2008007clientinte l.html
Apple SecUpd2008-007PPC.dmg
(PPC)
http://www.apple.com/support/downloads/securityupdate2008007clientppc. html
Apple Mac OS X Server 10.5.5
Apple SecUpdSrvr2008-007.dmg
http://www.apple.com/support/downloads/securityupdate2008007serverleop ard.html
Apple Mac OS X 10.5.5
Apple SecUpd2008-007.dmg
http://www.apple.com/support/downloads/securityupdate2008007clientleop ard.html
Apple Mac OS X Server 10.5.5
Apple SecUpdSrvr2008-007.dmg
http://www.apple.com/support/downloads/securityupdate2008007serverleop ard.html
暂无评论