Talos Vulnerability Report

TALOS-2016-0264

January 9, 2017

CVE Number

CVE-2016-9050

Summary

An exploitable out-of-bounds read vulnerability exists in the client message-parsing functionality of Aerospike Database Server 3.10.0.3. A specially crafted packet can cause an out-of-bounds read resulting in disclosure of memory within the process, the same vulnerability can also be used to trigger a denial of service. An attacker can simply connect to the port and send the packet to trigger this vulnerability.

Tested Versions

Aerospike Database Server 3.10.0.3

Product URLs

CVSSv3 Score

8.2 - CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:H

CWE

CWE-129 - Improper Validation of Array Index

Details

Aerospike Database Server is both a distributed and scalable NoSQL database that is used as a back-end for scalable web applications that need a key-value store. With a focus on performance, it is multi-threaded and retains its indexes entirely in ram with the ability to persist data to a solid-state drive or traditional rotational media.

In order to receive a packet from the client, the server spawns threads which execute the thr_demarshal function. At the beginning of this function, the server will receive data from the socket and then validate the protocol type. If the protocol type specifies that the packet is compressed (PROTOTYPEASMSGCOMPRESSED), it will decompress it with zlib and then continue to process the packet [1]. Later, when the protocol type is PROTOTYPEAS_MSG the server will pass the packet to the thr_tsvc_process_or_enqueue function [2].

Inside the thr_tsvc_process_or_enqueue function, the server will call the as_msg_peek_data_in_memory function [1]. This function will extract the specified namespace as defined within the packet and check to see if the storage_data_in_memory field [2] is set. The value of this field is defined within the configuration for the service. If the value of this field for the namespace is clear, then the thr_tsvc_enqueue function will be called [3].

The thr_tsvc_enqueue function will then check to see if the use_queue_per_device setting is specified within the configuration [1]. If this is the case, the server must peek into the packet to decide which device the transaction is to be written to [2]. Inside the as_msg_peek function, the server will read the AS_MSG_FIELD_TYPE_DIGEST_RIPE field out of the packet and store a pointer to the data in peek->keyd [3]. Due to this function not checking the minimum size of the field, an assumption made by the caller can be made to access data outside its bounds. This is done by the code at [4].

A client packet for Aerospike server is encoded in big-endian form and has the following structure. The first two bytes describe the protocol version and the protocol type. The version must be 0x02, where the protocol type can be one of two values. If ASCOMPRESSEDMSG(0x04) is specified, then the contents of data are zlib-encoded. Otherwise, the AS_MSG(0x03) value is used. The size of this data is defined by the sz field which is a 48-bit unsigned integer.

The contents of the data field has the following structure. Within this structure, the only fields that are important are n_fields and fields which are the values returned by as_msg_field_get defined in the vulnerability description.

In order to reach the described vulnerability, there must be two field types defined within fields. These types are NAMESPACE(0x0) and DIGESTRIPE(0x4). Each field-type contains a field_sz which defines the length of data and type. The contents of the NAMESPACE(0x0) field-type will be the namespace that a user is attempting to query. If the contents of the DIGESTRIPE field type is greater than 0 and less than 8, then this vulnerability is being triggered.