What is Memcache?
Memcache is temporary data storage service which stores data in <key> :< value> format.
It improves the overall performance of the website by storing chunks of data in a cache.
Example Scenarios where memcache might be used
- If the application is having some huge chunk of static data which needs to be displayed to the user as is like List of Countries for a Registration Form or Bank IFSC codes and so on …
- The application is having s search functionality, where in it needs to cache the most searched items in a temporary location so as to fetch it as quickly as possible.
What is its importance in a Penetration Test?
Ideally, this service should be running in a protected environment behind firewalls; accessible only to the web server. If exposed over the internet then it can enable a pentester to add, update and delete the data being cached in the Memcache.
Identifying a Memcache Service
Memcache service runs on its default TCP Port 11211.
Understanding the Memcache structure
Memcache stores the data in chunks of memory called as slabs. Each slabs has multiple items with each item consisting of multiple <key> : <value> pairs which actually store the data.
Follow the steps below to dig out some data from Memcache.
1. Memcache Is accessible through telnet <ip: address> <port (default 11211)
2. Once connected to the terminal Type stats items
What exactly is an item? An item can be thought of as slabs of the actual key:value data. The stats items command simply details the statistics of all the items or slabs of data created by Memcache.
3. Knowledge of the slabs won’t give us much information. What we need is the key:value pair which is actually having all the data. Use stats cachedump <item: id> <number of keys you want to query> to query the number of keys stored in the slab (item).
stats cachedump 2 0
Here we are querying the item number 2 for all keys ( 0 means display all keys ) in the slab.
We see that there is a key named “names” which is using 32 bytes of data and its expiration time.
4. Now, let’s retrieve the data using the key that we have got. To do that we simply need to fire the command get <key_name>
Here we get information about the data that the key “names” is storing.
The number 0 indicates it is having no expiration time and 32 is the length of the string
hello world</br>Vegeta</br>Rohit which is being stored
5. We can also add, edit, and replace the key:data pair using the following set of commands
- a. >set mykey 0 0 11
- b.>hello world
Syntax for set is:
set <keyname> <some_flag> <expiration_in_millseconds> <length_of_data_to_follow>
b. get mykey
c. delete mykey
6. Memcache service allows complete removal of all the cached data by using a simple flush command. It accepts a numerical parameter which indicates the time after which the data can be flushed in seconds.
The above screen shot shows that first we are querying for the key “names”. Next, we fire the flush_all 1 command which basically instructs Memcache to clear all the data after 1 second.
This service is accessible programmatically using some of the most popular languages like Java, PHP, .NET, Python etc… by simply accessing their respective APIs or Application Programming Interfaces.
Using a simple PHP script, it’s possible to keep flushing the data. This will keep the web server busy.
$memcache = <b>new</b> Memcache;
$memcache->connect('127.0.0.1', 11211) or <a href="http://www.php.net/die">die</a> ("Could not connect"); <i>//connect to memcached server</i>
$mydata = "i want to cache this line"; <i>//your cacheble data</i>
$memcache->set('key', $mydata, <b>false</b>, 100); <i>//add it to memcached server</i>
Using the while(1) loop above, it is very easy to launch Denial of Service (DoS) attack on a website. Of course, it depends on how the website is actually using Memcache service. For example, let’s say the website’s home page is accessing some data like Most Searched Results or Most Viewed Profiles whose details are stored in Memcache. If this data is constantly flushed, then a call to access any data from the application to Memcache will result in an exception being thrown continuously leading to DoS.
What more I can do?
By looking through the keys in Memcache, you should find some data which is being used by the application to display it to the end user like a List of countries in a Select Box , or Most viewed Results etc… then there data can be modified in the cache in such a way that we can mount successful Client Side Attacks like Cross-Site Scripting
Now, let’s attempt to modify the key names to something that we want:
> delete names
> set names 0 0 30
Hmm… Looks like we were successful in implanting a stored cross-site script (XSS)!
Basically in the above attack, we are able to modify the data which was going to the client. Similarly, there could be a possibility of SQL Injection if the data present in Memcache was being stored in the database. It all depends on your ability to understand the application, the flow of data in that application and some patience while finding the right key.
How to fix this?
An important point to note is that, in this article we have been abusing the actual functionality of the Memcache service. Thus, a logical fix to this issue would be to
1) Bind the Memcache server to a particular Source IP Only.
2) Don’t expose this service in the DMZ environment or over the Internet.
3) If the business requirement dictates to expose the service over the internet, then make sure the service is running behind a firewall with access to a designated Source IP (mostly the web-servers IP).