参考:
https://www.redteaming.top/2019/07/15/%E6%B5%85%E6%9E%90Redis%E4%B8%ADSSRF%E7%9A%84%E5%88%A9%E7%94%A8/
Redis默认端口6379
如果存在未授权问题,那么任何人都可以往这台Redis服务器上传输命令
一般Redis攻击有
写shell(最常用),写密钥,写crontab反弹shell, info获得敏感信息,其中写密钥和写crontab不是那么的好用
在讲攻击之前,要讲一下RESP协议
Redis服务器与客户端通过RESP协议的通信。
resp协议从redis1.2引入。
这个协议把服务器与客户端之间的数据以一种序列化的形式处理并传输
在RESP中,某些数据的类型取决于第一个字节:
对于Simple Strings
,回复的第一个字节是+
对于error
,回复的第一个字节是-
对于Integer
,回复的第一个字节是:
对于Bulk Strings
,回复的第一个字节是$
,发送给服务器的命令就是放在数组中的BulkStrings类型
对于array
,回复的第一个字节是*
此外,RESP
能够使用稍后指定的Bulk Strings
或Array
的特殊变体来表示Null
值。
在RESP中,协议的不同部分始终以"\r\n"(CRLF)
结束。
同时每个类型字节后紧跟着该类型的长度,然后是CRLF,然后是该类型的值
说了这么多,肯定不会很懂,上图
即发送的时候,是用三个元素的数组(*3),第一个元素是三个长度的BulkString($3)其值为set,第二个元素是四个长度的BulkSting($4)其值为name,第三个元素是四个长度长的BulkString($4)其值为test,服务器返回SimpleString(+)OK,以下类推
是http协议出现常用的一个协议,SSRF的万金油。
格式:gopher://IP:port/_{TCP/IP数据流}
写shell的话,redis需执行的命令应该类似这样
攻击脚本如下(主要用于ssrf)
这样的话,我们就得到了payload,直接curl一下,就写入shell了
连上后 使用info命令
高版本不好用,因为高版本的redis权限是无法往/root目录写入的.
而这个方法则需要往/root/.ssh写入ssh公钥达到无密码ssh链接的目的
首先在攻击机上生成一对不需要密码的公钥私钥
然后依次输入
然后ssh免密登录 ssh -i id_rsa [email protected]
仅在centos系统奏效,Ubuntu不行
因为默认redis写文件后是644的权限,但ubuntu要求执行定时任务文件/var/spool/cron/crontabs/
权限必须是600也就是-rw-------
才会执行,否则会报错(root) INSECURE MODE (mode 0600 expected)
,而Centos的定时任务文件/var/spool/cron/
权限644也能执行
因为redis保存RDB会存在乱码,在Ubuntu上会报错,而在Centos上不会报错
由于系统的不同,crontrab定时文件位置也会不同
Centos的定时任务文件在/var/spool/cron/
Ubuntu定时任务文件在/var/spool/cron/crontabs/
Centos和Ubuntu均存在的(需要root权限)/etc/crontab
PS:高版本的redis默认启动是redis
权限,故写这个文件是行不通的
把上面那个脚本改改就能实现ssrf了
作者:ConsT27
原文地址:http://const27.com/
推荐阅读