0x00 写在前面
wooyun主站也有过Memcached相关漏洞大多未经授权访问。事实上,即使部署得当Memcached,如果遇到安全意识差的程序员兄弟,也会出现Memcached导致敏感内存泄漏的安全风险。
也就是本文要说的Memcached注入
0x01 Memcached简介&安全性分析
Memcached 用于动态的高性能分布式内存对象缓存系统Web减少数据库负载的应用。
通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态和数据库驱动网站的速度。
用白话来说,当传统web将访问产生的临时数据存储在后端数据库(如user sessions),部署了Memcached的应用会将user sessions存储其他敏感信息RAM同时,增长率也减轻了后端数据库反复查询带来的负载。
Memcached创建者Dormando我很早就写了两篇文章,警告开发人员不要使用它们memcached存储Session。然而,许多开发者仍然为了性能或其他原因session存储在memcached中。这样做,一旦memcached被攻击会直接导致管理员或用户token泄露。
0x02 Memcached协议
当Memcache被部署后,我们应该如何添加数据?我们通过一个cheat sheet了解一下Memcached的协议。
Memcached语法由以下元素组成
{COMMAND}0x20{ARGUMENT}(LF|CRLF)
command字段有以下命令
- 存储操作(set, add, replace, append, prepend, cas)
- 检索操作 (get, gets)
- 删除操作 (delete)
- 增减操作 (incr, decr)
- touch
- slabs reassign
- slabs automove
- lru_crawler
- 统计操作(stats items, slabs, cachedump)
- 其他操作 (version, flush_all, quit)
以下是安全测试中一些有用的命令
Command | 描述 | 实例 |
get | 读某个值 | get mykey |
set | 强制设置键值 | set mykey 0 60 5 |
add | 添加新键值对 | add newkey 0 60 5 |
replace | 覆盖已经存在的key | replace key 0 60 5 |
flush_all | 让所有项目失效 | flush_all |
stats | 打印当前状态 | stats |
stats malloc | 打印内存状态 | stats malloc |
version | 打印Memcached版本 | version |
0x03 Memcached代码实现
部署好Memcached之后,调用Memcached的php代码是这样的。
1 2 3 4 5 6 7 |
|
为了反映漏洞的产生,我想这样写
1 2 3 4 5 6 7 8 9 10 11 |
|
set("key1 0 0 1\r\n1\r\nset injected 0 3600 10\r\n1234567890\r\n","1234567890",30)
是的,这里也可以看到问题。
执行刚才的命令时,server和client的通信是这样的(>表示发送到Memcached ,<表示从Memcached的返回)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
可见,对Memcached就协议而言,\r\n它可以用来分割命令,所以我们可以直接通过CLRF注入,将\r\n注入即将传入Memcached元素(例如cookies),执行命令。
0x04 Memcache Injection实例
最近的一次ctf在中间,有一个典型的基础CLRF的Memcache注入。(目前该站可以访问)
http://login2.chal.mmactf.link/login
login as admin
登录之后的请求是这样的
1 2 3 4 5 6 7 8 9 10 |
|
在测试http头注入的时候,我们发现将%0a注入到cookies中时,也就是请求:
Cookie: ss=%0ac4a613cdf3378b458be9a6d8de6c52c6ab260d1ee5c2d94df6fe260e580b16bb
返回如下
1 2 3 4 5 6 7 8 |
|
恩,memcached出错了,那不就是刚刚提到的error吗?
1 2 3 |
|
说明这里ss的value代入了memcached。
我们继续在cookies里面注入:ss=%0astats
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
|
果然返回了memcached的stats
现在来做我们最想做的一件事情,dump内存中的东西看看:我们利用cachedump
stats cachedump {slab class} {number of items to dump}
这里需要介绍下 memcached是以slab class进行分类的 比如:
1 2 3 4 5 6 |
|
我们可以看到每个class的编排
所以我们每一个都dump出来看看才好:
Cookie: %0astats cachedump 1 1000
返回为
MemcacheError:ERROR ITEM key [1 b; 1441762228 s] ITEM 12345 [20 b; 1441494967 s] END
当我遍历到class 3的时候:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
终于注入到我们所需要的class中去。
0x05 参考
: memcached Cheat Sheet
: https://www.blackhat.com/docs/us-14/materials/us-14-Novikov-The-New-Page-Of-Injections-Book-Memcached-Injections-WP.pdf
本文章来源于乌云知识库,文章版权归乌云知识库!