hacktricks/network-services-pentesting/11211-memcache/README.md
carlospolop 63bd9641c0 f
2023-06-05 20:33:24 +02:00

19 KiB

11211 - Pentesting Memcache

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

Información del protocolo

Memcached (pronunciación: mem-cached, mem-cash-dee) es un sistema de caché de memoria distribuida de propósito general. A menudo se utiliza para acelerar sitios web dinámicos impulsados por bases de datos mediante el almacenamiento en caché de datos y objetos en RAM para reducir la cantidad de veces que se debe leer una fuente de datos externa (como una base de datos o una API). (De wikipedia)
Aunque Memcached admite SASL, la mayoría de las instancias están expuestas sin autenticación.

Puerto predeterminado: 11211

PORT      STATE SERVICE
11211/tcp open  unknown

Enumeración

Manual

Para extraer toda la información guardada dentro de una instancia de memcache, necesitas:

  1. Encontrar slabs con items activos
  2. Obtener los nombres de las claves de los slabs detectados anteriormente
  3. Exfiltrar los datos guardados obteniendo los nombres de las claves

Recuerda que este servicio es solo una caché, por lo que los datos pueden aparecer y desaparecer.

echo "version" | nc -vn -w 1 <IP> 11211      #Get version
echo "stats" | nc -vn -w 1 <IP> 11211        #Get status
echo "stats slabs" | nc -vn -w 1 <IP> 11211  #Get slabs
echo "stats items" | nc -vn -w 1 <IP> 11211  #Get items of slabs with info
echo "stats cachedump <number> 0" | nc -vn -w 1 <IP> 11211  #Get key names (the 0 is for unlimited output size)
echo "get <item_name>" | nc -vn -w 1 <IP> 11211  #Get saved info

#This php will just dump the keys, you need to use "get <item_name> later"
sudo apt-get install php-memcached
php -r '$c = new Memcached(); $c->addServer("localhost", 11211); var_dump( $c->getAllKeys() );'

Manual2

Descripción

Memcached es un sistema de almacenamiento en caché distribuido de alta velocidad que se utiliza comúnmente para acelerar las aplicaciones web mediante el almacenamiento en caché de objetos en la memoria RAM. Memcached se ejecuta en un servidor y las aplicaciones web se conectan a él a través de una red para almacenar y recuperar datos en caché.

Escaneo

Para escanear un servidor en busca de Memcached, podemos usar la herramienta nmap con el script memcached-info:

nmap -sV --script=memcached-info <target>

Explotación

Una vez que hemos identificado un servidor Memcached, podemos intentar explotar su configuración predeterminada para realizar un ataque de amplificación de reflexión. Para hacer esto, podemos usar la herramienta memcrashed:

git clone https://github.com/649/Memcrashed-DDoS-Exploit.git
cd Memcrashed-DDoS-Exploit
python3 memcrashed.py <target>

También podemos intentar realizar una fuga de información utilizando el comando stats de Memcached:

echo "stats" | nc <target> 11211

Esto nos dará información sobre el servidor Memcached, incluyendo estadísticas de uso y configuración. Si el servidor está configurado para permitir la lectura de claves, también podemos usar el comando get para recuperar valores de caché:

echo "get <key>" | nc <target> 11211

Mitigación

Para mitigar los ataques de amplificación de reflexión de Memcached, se recomienda deshabilitar el acceso público a los servidores Memcached y limitar el acceso a través de una red privada o una VPN. También se puede configurar Memcached para que solo escuche en interfaces de red específicas y se pueden implementar listas blancas de direcciones IP para limitar aún más el acceso.

sudo apt install libmemcached-tools
memcstat --servers=127.0.0.1 #Get stats
memcdump --servers=127.0.0.1 #Get all items
memccat  --servers=127.0.0.1 <item1> <item2> <item3> #Get info inside the item(s)

Automático

nmap -n -sV --script memcached-info -p 11211 <IP>   #Just gather info
msf > use auxiliary/gather/memcached_extractor      #Extracts saved data
msf > use auxiliary/scanner/memcached/memcached_amp #Check is UDP DDoS amplification attack is possible 

Extrayendo claves de Memcache

Si tu versión de memcached es superior a 1.4.31, lee la siguiente sección para conocer un método avanzado de extracción de claves.

El protocolo de memcache proporciona comandos para espiar los datos que están organizados por fragmentos (categorías de datos de un rango de tamaño dado). Sin embargo, hay algunas limitaciones significativas:

  1. Solo puedes extraer claves por clase de fragmento (claves con un tamaño de contenido aproximado)
  2. Solo puedes extraer una página por clase de fragmento (1MB de datos)
  3. Esta es una característica no oficial que podría eliminarse en cualquier momento.

La segunda limitación es probablemente la más difícil porque 1MB de varios gigabytes es casi nada. Aún así, puede ser útil observar cómo se usan un subconjunto de tus claves. Pero esto puede depender de tu caso de uso. Si no te importan los detalles técnicos, simplemente salta a la sección de herramientas para aprender sobre qué herramientas te permiten extraer todo fácilmente. Alternativamente, sigue la siguiente guía y prueba los comandos usando telnet contra tu configuración de memcached. Cómo funciona Primero necesitas saber cómo memcache organiza su memoria. Si inicias memcache con la opción "-vv", verás las clases de fragmentos que crea. Por ejemplo:

$ 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
[...]

En la configuración impresa anteriormente, memcache mantendrá en forma 6898 piezas de datos entre 121 y 152 bytes en una sola losa de tamaño 1MB (6898*152). Todas las losas tienen un tamaño predeterminado de 1MB. Use el siguiente comando para imprimir todas las losas existentes actualmente:

stats slabs

Si has añadido una única clave a un memcached 1.4.13 vacío con

set mykey 0 60 1
1
STORED

Ahora verás el siguiente resultado para el comando "stats slabs":

stats slabs
STAT 1:chunk_size 96
STAT 1:chunks_per_page 10922
STAT 1:total_pages 1
STAT 1:total_chunks 10922
STAT 1:used_chunks 1
STAT 1:free_chunks 0
STAT 1:free_chunks_end 10921
STAT 1:mem_requested 71
STAT 1:get_hits 0
STAT 1:cmd_set 2
STAT 1:delete_hits 0
STAT 1:incr_hits 0
STAT 1:decr_hits 0
STAT 1:cas_hits 0
STAT 1:cas_badval 0
STAT 1:touch_hits 0
STAT active_slabs 1
STAT total_malloced 1048512
END

El ejemplo muestra que solo tenemos un tipo de fragmento activo, el #1. Nuestra clave, siendo de solo un byte, encaja en esto como el tamaño de fragmento más pequeño posible. Las estadísticas de fragmentos muestran que actualmente solo existe una página de la clase de fragmentos y que solo se utiliza un fragmento. Lo más importante es que muestra un contador para cada operación de escritura (set, incr, decr, cas, touch) y uno para gets. ¡Usando estos, puedes determinar una tasa de aciertos! También puedes obtener otro conjunto de información usando "stats items" con contadores interesantes sobre evicciones y contadores de falta de memoria.

stats items
STAT items:1:number 1
STAT items:1:age 4
STAT items:1:evicted 0
STAT items:1:evicted_nonzero 0
STAT items:1:evicted_time 0
STAT items:1:outofmemory 0
STAT items:1:tailrepairs 0
STAT items:1:reclaimed 0
STAT items:1:expired_unfetched 0
STAT items:1:evicted_unfetched 0
END

Lo que ya podemos adivinar... Dados los datos estadísticos por clase de losas, ya podemos adivinar muchas cosas sobre el comportamiento de la aplicación:

  1. ¿Cómo es la proporción de caché para diferentes tamaños de contenido?
    • ¿Qué tan bueno es el almacenamiento en caché de grandes fragmentos de HTML?
  2. ¿Cuánta memoria gastamos en diferentes tamaños de contenido?
    • ¿Cuánto gastamos en contadores numéricos simples?
    • ¿Cuánto gastamos en nuestros datos de sesión?
    • ¿Cuánto gastamos en grandes fragmentos de HTML?
  3. ¿Cuántos objetos grandes podemos almacenar en caché en total?

Por supuesto, para responder a las preguntas, es necesario conocer los objetos de caché de su aplicación. Ahora: ¿Cómo volcar claves? Las claves se pueden volcar por clase de losas utilizando el comando "stats cachedump".

stats cachedump <slab class> <number of items to dump>

Para volcar nuestra única clave en la clase #1, ejecutamos:

stats cachedump 1 1000
ITEM mykey [1 b; 1350677968 s]
END

El comando "cachedump" devuelve un elemento por línea. El primer número entre llaves indica el tamaño en bytes, el segundo el timestamp de creación. Dado el nombre de la clave, ahora también puedes volcar su valor usando.

get mykey
VALUE mykey 0 1
1
END

Aquí está: itera sobre todas las clases de fragmentos que desees, extrae los nombres de las claves y, si es necesario, vuelca su contenido.

VOLCADO DE CLAVES DE MEMCACHE (VERSIÓN 1.4.31+)

En la versión 1.4.31 y superior de memcache, hay un nuevo comando para volcar las claves de memoria en modo no bloqueante (lea https://github.com/memcached/memcached/wiki/ReleaseNotes1431). Este método es seguro para ejecutar en producción. La salida no es consistente, pero es lo suficientemente buena para encontrar claves, su tiempo exacto de expiración (EXP) y el último tiempo de acceso (LA). Debido a la gran cantidad de salida generada, se recomienda utilizar el comando 'nc'. Ejemplos:

echo 'lru_crawler metadump all' | nc 127.0.0.1 11211 | head -1
key=0dLLX%253Amemcache_test_key exp=1590718787 la=1590718487 cas=2238881166 fetch=yes

echo 'lru_crawler metadump all' | nc 127.0.0.1 11211 | grep ee6ba58566e234ccbbce13f9a24f9a28
key=VQRFX%253Aee6ba58566e234ccbbce13f9a24f9a28 exp=-1 la=1590386157 cas=1776204003 fetch=yes
key=0dLLX%253Aee6ba58566e234ccbbce13f9a24f9a28 exp=-1 la=1590712292 cas=2225524871 fetch=yes

EXP=-1 significa que el elemento nunca expira. EXP=1590718787 (vie may 29 02:19:47 GMT 2020) guarda la marca de tiempo Unix cuando el elemento debería expirar. LA=1590712292 (lun may 25 05:55:57 GMT 2020) guarda la marca de tiempo Unix cuando se accedió por última vez al elemento.

HERRAMIENTAS DE VOLCADO

Existen diferentes herramientas de volcado, a veces solo scripts, que te ayudan a imprimir las claves de memcache:

Lenguajes de programación Herramientas Funcionalidad
PHP simple script Imprime los nombres de las claves.
Perl simple script Imprime las claves y los valores.
Ruby simple script Imprime los nombres de las claves.
Perl memdump Herramienta en el módulo CPAN Memcached-libmemcached ached/)
PHP memcache.php GUI de monitoreo de Memcache que también permite el volcado de claves.
libmemcached peep ¡Congela tu proceso de memcached! Ten cuidado al usar esto en producción. Aún así, puedes sortear la limitación de 1MB y realmente volcar todas las claves.

Solución de problemas

Límite de datos de 1MB

Ten en cuenta que antes de memcached 1.4 no puedes almacenar objetos mayores de 1MB debido al tamaño máximo de slab predeterminado.

¡Nunca establezcas un tiempo de espera > 30 días!

Si intentas "establecer" o "agregar" una clave con un tiempo de espera mayor que el máximo permitido, es posible que no obtengas lo que esperas porque memcached trata el valor como una marca de tiempo Unix. Además, si la marca de tiempo está en el pasado, no hará nada en absoluto. Tu comando fallará silenciosamente.

Por lo tanto, si deseas utilizar el tiempo de vida máximo, especifica 2592000. Ejemplo:

set my_key 0 2592000 1
1

Desaparición de claves en desbordamiento

A pesar de que la documentación dice algo sobre el desbordamiento de 64 bits, usando "incr" hace que el valor desaparezca. Es necesario crearlo de nuevo usando "add" / "set".

Replicación

memcached en sí no admite la replicación. Si realmente lo necesita, debe usar soluciones de terceros:

  • repcached: replicación asíncrona multi-maestro (conjunto de parches memcached 1.2)
  • Interfaz de memcached de Couchbase: Use CouchBase como reemplazo de memcached
  • yrmcds: almacenamiento de clave-valor maestro-esclavo compatible con memcached
  • twemproxy (también conocido como nutcracker): proxy con soporte memcached

Hoja de trucos de comandos

{% content-ref url="memcache-commands.md" %} memcache-commands.md {% endcontent-ref %}

Shodan

  • port:11211 "STAT pid"
  • "STAT pid"

Referencias

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥