####################################################################### Luigi Auriemma Application: yaSSL http://www.yassl.com Versions: <= 1.8.0 Platforms: Windows and *nix Bugs: A] buffer-overflow in ProcessOldClientHello B] buffer-overflow in "input_buffer& operator>>" C] invalid memory access in HASHwithTransform::Update Exploitation: remote Date: 04 Jan 2008 Author: Luigi Auriemma e-mail: aluigi@autistici.org web: aluigi.org ####################################################################### 1) Introduction 2) Bugs 3) The Code 4) Fix ####################################################################### =============== 1) Introduction =============== yaSSL is an open source SSL library mainly used in MySQL and in other projects. On MySQL, if SSL support is enabled, is possible to use this vulnerability for pre-authentication code execution. ####################################################################### ======= 2) Bugs ======= ------------------------------------------- A] buffer-overflow in ProcessOldClientHello ------------------------------------------- The buffer which contains the data received by the client in the Hello packet has the following structure (from 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_; ... where ID_LEN is 32 elements long, MAX_SUITE_SZ 64 and RAN_LEN (Random) is 32. The ProcessOldClientHello function called when an old version of the Hello packet is received doesn't have the needed checks for limiting the amount of data which will fill these 3 fields leading to a buffer-overflow vulnerability exploitable for executing code remotely. From 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] buffer-overflow in "input_buffer& operator>>" ------------------------------------------------ Another buffer-overflow is located in the function used for handling the normal Hello packet but in this case doesn't seem possible (or easily possible) to exploit this vulnerability for executing code. From 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] invalid memory access in HASHwithTransform::Update ----------------------------------------------------- The usage of a too big size value in the Hello packet leads to a crash of the library through the reading of data outside the memory containing the incoming packet. From 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); ... ####################################################################### =========== 3) The Code =========== http://aluigi.org/poc/yasslick.zip http://aluigi.org/poc/mysqlo.zip ####################################################################### ====== 4) Fix ====== A mail has been sent to the developers yesterday during my tests only to inform them of the vulnerabilities. UPDATE 15 Jan 2008 CVS has been patched the 11 Jan 2008 but the current stable (now 1.8.0 is still vulnerable). #######################################################################