0x00 前言
国庆前的那篇文章我搭建好了redis的测试环境。
这篇文章介绍一下redis基本使用方法。
然后复现一下通过redis拿权限的一些常用利用方式。
0x01 连接方式
(1)在命令行下使用telnet连接redis
telnet是一个基本的远程登陆命令,在linux和windows下的安装方式都很简单,这里就不再赘述了。 > telnet redis-server的ip地址 端口
连接成功后页面会变空白
要注意连接后第一次输入的命令没有回显(类似linux输入密码),输完直接回车就行了。 输入 info
命令查看基本信息
quit
命令断开连接
有密码的情况下连接后用
> auth 密码
命令进行登陆,否则无权限执行其他命令。 ping
命令在redis中用于检测连接是否成功,若成功redis-server会返回PONG。
(2)在命令行下使用redis-cli连接redis
linux下安装redis就会有redis-cli。
windows可以在这里下载:
https://github.com/microsoftarchive/redis/releases
下载.zip解压后里面有redis-cli.exe
首先cd到redis-cli所在目录,输入以下命令连接 (cmd)
redis-cli.exe
-h
redis-server的ip地址
-p
端口
redis-cli和telnet的区别是用tab键可以进行命令补全,交互性更佳
有密码的情况下需要在连接后使用 > auth 密码
命令登陆,否则无权限执行其他命令
或者直接在连接时用 -a
参数指定密码(出于安全性考虑不推荐这么做)
(3)使用图形化工具AnotherRedisDesktopManager连接
下载地址https://github.com/qishibo/AnotherRedisDesktopManager/releases
使用方法略
0x02 redis常用命令
(1)配置相关
查看所有配置 >
config get
*
查看某个配置 >
config get
配置名
修改配置 > config set
配置名 新的配置值
一些需要注意的配置 dbfilename
(备份文件名) dir
(备份文件存放路径) rdbcompression
(备份时是否压缩数据) save
(自动备份相关配置) requirepass(redis登陆密码)
masterauth(主节点密码)
slaveof
(主节点位置) protected-mode
(安全模式) (2)Key相关
redis存储数据的方式是key-value,key可以理解为变量,value就是变量的值,redis可以存储很多个key。 redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。因为不是本文重点,这里我只演示最简单的string类型相关操作命令。 创建key >
set
key名 key值
查看key值 >
get
key名
删除key >
del
key名
查找key >
KEYS
匹配模式
清空所有数据 >
flushall
(3)数据库相关
redis有0-15号共16个数据库(可以在配置文件中修改数量),每次连接后默认使用0号数据库 切换数据库 >
select
索引[0-15]
查看当前库中key的数量 >
dbsize
使用 info
命令可以看到每个库中key的数量
生产环境下使用 keys *
命令前最好先看一下数量,否则key太多全部读到内存中很可能导致服务直接挂掉。 flushall
命令会清空所有库中的内容,不管你当前在哪个库。 如果只是要清空当前库,请使用 flushdb
(4)备份相关
redis是内存型数据库,服务重启后所有数据就会丢失,redis 最初设计的目的就不 是用于持久性的数据存储。 但实际环境下有时需要进行redis数据的持久化,于是redis提供了【数据备份和恢复功能】,也就是这个功能成为了漏洞利用的切入点。
redis中本来有一些数据
在centos上用#
ps
aux
命令查看redis进程号
然后kill掉,再重新启动
重新连接发现数据都不见了
重新创建一些数据
查看配置中备份文件位置和文件名
输入命令 save
,即可看到文件已备份
再次重启后发现数据没有丢失(redis重启后会自动读取配置文件中dir路径下的dbfilename指定的文件进行恢复)
配置文件:
0x03 备份文件内容的研究
清空数据库后备份
备份文件的内容(二进制文件需用 xxd
命令查看),可见备份文件除了会写入数据,还会写入一些其他内容,利用的时候需考虑到这一点
尝试备份php代码,发现key和value都可以成功写入,key在前value在后
尝试备份超长重复字符串,发现key和value都会被压缩,同时发现备份文件是覆盖写入的(之前的备份内容不见了)
调整配置rdbcompression改为no,再次备份发现数据可以完整写入
切换数据库后备份,发现备份的是所有库中的内容
【结论】
1、备份会写入数据之外的内容,利用时需要被写文件有一定容错性。
2、需要关注一下备份的顺序(按key的字符顺序排列),比如之前如果人已经利用过写了webshell,而你的key备份在他后面,可能会导致你的webshell不生效。
3、备份前最好关闭压缩功能使数据可以完整写入。
4、暂未发现如何使redis备份单个库,通过切换库避免写入其他数据的方法不可行。
0x04 利用方式1:写计划任务
记录等下需要修改的配置项的值以便事后恢复(之后的其他利用方式皆如此) >
config get
dir
> config get
dbfilename
设置路径和文件名 > config set
dir /var/spool/cron/
> config set
dbfilename 用户名
新建一个key,值为需要执行的计划任务,注意前后都要加回车符号 > set
key名 需要执行的计划任务内容
保存 > save
可以看到计划任务被成功写入
#
cat
/var/log/cron
查看日志看到计划任务成功执行(ip地址写错了,不要在意那些细节,能成功执行就行。。。)
0x05 利用方式2:写ssh公钥
windows和linux下创建ssh公私钥的方式不同,因为不是本文重点所以这里只记录windows下的操作。 cmd下输入命令 ssh-keygen
,然后会提示选择位置、输入密码,全部回车就行了,会在默认位置下生成无需密码的ssh公私钥对。
默认位置为C:\Users\你的用户名\.ssh id_rsa
是私钥,自己保存好不要给任何人 id_rsa.pub
是公钥,是我们需要写到目标机器上的
用文本编辑器打开id_rsa.pub,删除最后面的用户名信息(灰色部分),然后复制下所有的内容
设置目录时出错,debug发现centos上没有.ssh文件夹,redis只能写文件但是不能创建目录,所以这种情况下写公钥这种方法不可用
但我们的测试环境下可以手动给它生成一个.ssh目录,实际环境中大多数服务器上也是有此目录的。
然后设置路径和文件名 >
config set
dir /用户家目录/.ssh/
>
config set
dbfilename “authorized_keys”
创建key,写入公钥内容(注意前后各加三个回车符\n)
save
后发现成功写入(之前写计划任务的payload忘了删也写进去了,不要在意。。。)
之后发现ssh连接不用输入密码即可登陆
0x06 利用方式3:写webshell
设置路径和文件名以及webshell的内容,然后 save
,已经很熟练了
查看webshell内容,至于为什么要在payload前后加回车是为了避免可能出现的吞字符现象
用
hackbar测试执行命令成功
0x07 后记
这周文章对redis如何使用以及一些常用的利用方式做了介绍和演示。 三种利用方式:
写计划任务,写ssh公钥,写webshell都可以获得运行redis的用户权限。具体使用哪一种要根据实际环境来选择。
不过其实我高估了自己的产出能力,已知的redis利用方式不止这些,受限于个人时间精力问题没能全部写出来。
不想给自己挖坑了,下周如果还写redis,我会补充剩下的利用方式,然后可能测试一下redis内已有大量数据的情况下利用方式是否可行。
不过也可能弃坑,写点别的东西,到底写什么只有下周的我才知道啦。毕竟干这一行的,看到什么都要学。
0x08 参考文献
https://www.runoob.com/redis/
https://www.freebuf.com/vuls/148758.html
https://zhuanlan.zhihu.com/p/36529010
https://www.jianshu.com/p/2790a860f151
END.