Open HTTP Redirect 开放重定向漏洞:URL 跳转校验缺陷与绕过技术

Open HTTP Redirect 开放重定向漏洞:URL 跳转校验缺陷与绕过技术

    • 前言
    • [1. Open HTTP Redirect 核心理论基础](#1. Open HTTP Redirect 核心理论基础)
      • [1.1 漏洞本质与定义](#1.1 漏洞本质与定义)
      • [1.2 漏洞成立的三大必要条件](#1.2 漏洞成立的三大必要条件)
      • [1.3 完整钓鱼攻击链路](#1.3 完整钓鱼攻击链路)
      • [1.4 服务端跳转 vs 客户端跳转(DOM 型)](#1.4 服务端跳转 vs 客户端跳转(DOM 型))
      • [1.5 常见攻击场景与业务危害](#1.5 常见攻击场景与业务危害)
      • [1.6 漏洞在安全榜单中的定位](#1.6 漏洞在安全榜单中的定位)
    • [2. DVWA Open HTTP Redirect(Low)](#2. DVWA Open HTTP Redirect(Low))
      • [2.1 页面黑盒探测](#2.1 页面黑盒探测)
      • [2.2 黑盒漏洞利用实操](#2.2 黑盒漏洞利用实操)
        • [2.2.1 直接构造恶意跳转 URL](#2.2.1 直接构造恶意跳转 URL)
        • [2.2.2 伪装可信域名钓鱼链接(实战场景)](#2.2.2 伪装可信域名钓鱼链接(实战场景))
      • [2.3 源码审计(无校验直接跳转)](#2.3 源码审计(无校验直接跳转))
    • [3. DVWA Open HTTP Redirect(Medium)](#3. DVWA Open HTTP Redirect(Medium))
      • [3.1 黑盒探测](#3.1 黑盒探测)
        • [3.1.1 基础功能测试](#3.1.1 基础功能测试)
        • [3.1.2 验证协议过滤防护机制](#3.1.2 验证协议过滤防护机制)
        • [3.1.3 黑盒推导校验规则](#3.1.3 黑盒推导校验规则)
      • [3.2 黑盒攻击实操](#3.2 黑盒攻击实操)
        • [3.2.1 协议相对 URL 绕过原理](#3.2.1 协议相对 URL 绕过原理)
        • [3.2.2 构造 `//evil.com` 恶意 Payload](#3.2.2 构造 //evil.com 恶意 Payload)
        • [3.2.3 攻击复现步骤](#3.2.3 攻击复现步骤)
        • [3.2.4 正则过滤存在的逻辑缺陷](#3.2.4 正则过滤存在的逻辑缺陷)
      • [3.3 源码审计](#3.3 源码审计)
    • [4. DVWA Open HTTP Redirect(High)](#4. DVWA Open HTTP Redirect(High))
      • [4.1 黑盒探测](#4.1 黑盒探测)
        • [4.1.1 抓包对比 Low/Medium 行为差异](#4.1.1 抓包对比 Low/Medium 行为差异)
        • [4.1.2 复用 Medium 的 Payload 测试(完全失效)](#4.1.2 复用 Medium 的 Payload 测试(完全失效))
        • [4.1.3 黑盒推导校验规则](#4.1.3 黑盒推导校验规则)
      • [4.2 黑盒攻击绕过实操](#4.2 黑盒攻击绕过实操)
        • [4.2.1 子串匹配校验漏洞原理](#4.2.1 子串匹配校验漏洞原理)
        • [4.2.2 外部域名拼接 info.php 构造 Payload](#4.2.2 外部域名拼接 info.php 构造 Payload)
        • [4.2.3 完整攻击复现](#4.2.3 完整攻击复现)
      • [4.3 High 级别源码审计](#4.3 High 级别源码审计)
    • [5. DVWA Open HTTP Redirect(Impossible)](#5. DVWA Open HTTP Redirect(Impossible))
      • [5.1 源码审计](#5.1 源码审计)
      • [5.2 四级对比总结(Low/Medium/High/Impossible)](#5.2 四级对比总结(Low/Medium/High/Impossible))
      • [5.3 最终安全修复方案](#5.3 最终安全修复方案)
    • 免责声明

前言

上一篇我们详细拆解了 CSRF 跨站请求伪造漏洞的攻防全流程,相信大家对"借助用户身份伪造请求"的攻击思路已经有了清晰的认识。今天我们继续 Web 漏洞系列,来聊一个经常被低估、但在真实钓鱼和社工攻击中极其好用的漏洞------Open HTTP Redirect(开放重定向)

很多开发者觉得"不就是个跳转吗,能有什么危害",但恰恰是这种轻视,让开放重定向成为了钓鱼攻击的绝佳跳板 。一个存在漏洞的可信域名跳转 ,能让钓鱼链接的可信度提升数个等级 ,用户看到熟悉的域名后往往放松警惕,最终被诱导至恶意站点窃取账号凭证


1. Open HTTP Redirect 核心理论基础

1.1 漏洞本质与定义

开放重定向漏洞(Open Redirect) ,又称 URL 跳转漏洞,对应的标准漏洞编号为 CWE-601: URL Redirection to Untrusted Site

漏洞的本质一句话就能说清:Web 应用程序接收用户可控的参数来构造跳转目标 URL,但没有对该 URL 进行严格的合法性校验,导致攻击者可以构造恶意链接,将用户重定向到任意外部站点。

用最直白的话讲:网站有个跳转功能,本来是跳转到自己站内的页面,但因为没校验,攻击者可以改成跳转到钓鱼网站,而且链接前面还是正经域名,用户看不出来。

典型的漏洞 URL 长这样:

复制代码
https://trusted-site.com/login?redirect=https://evil.com/phish

用户看到域名是 trusted-site.com(可信站点),放心点进去,结果啪一下就跳到了攻击者控制的 evil.com,整个过程行云流水,几乎没有感知。


1.2 漏洞成立的三大必要条件

不是所有带跳转的地方都有漏洞,必须同时满足以下三个条件:

条件一:跳转目标 URL 完全或部分由用户可控

  • 参数名常见的有:redirecturlnextgotoreturn_urlredirect_urijumptarget 等等
  • 用户输入的内容能直接或间接影响最终的跳转地址

条件二:服务端未对跳转目标做严格的白名单校验

  • 完全没校验
  • 校验了但能被绕过
  • 用了黑名单、关键字匹配等不靠谱的校验方式

条件三:跳转是服务端 3xx 响应或客户端自动触发

  • 服务端通过 Location 响应头触发 302/301 跳转(最常见)
  • 前端通过 window.locationmeta refresh 等方式跳转(DOM 型)
  • 用户不需要额外点击确认,访问即跳转

1.3 完整钓鱼攻击链路

开放重定向最经典的用法就是钓鱼,完整攻击链路分四步走:

第一步:寻找可信站点的跳转漏洞

攻击者在目标公司的官网、登录页、OAuth 授权页等地方,寻找存在开放重定向漏洞的 URL 参数。

第二步:构造恶意跳转链接

把正常的跳转目标替换成攻击者的钓鱼站点地址,得到一个"披着可信域名外衣"的恶意链接:

复制代码
https://银行官网.com/login?redirect=https://钓鱼网站.com/fake-login

第三步:社工诱导用户点击

通过邮件、短信、QQ/微信等渠道,把链接发给受害者,话术通常是"您的账户异常,请点击链接登录核实"。

第四步:用户跳转至钓鱼站点被窃取信息

用户看到链接是正经银行域名,放下戒心点击 → 浏览器先访问银行官网 → 官网 302 跳转到钓鱼网站 → 钓鱼网站高仿银行登录页 → 用户输入账号密码 → 攻击者拿到凭证。

整个过程中,用户的注意力都在"域名是不是官方的"上,很少有人会去注意 URL 后面 ?redirect= 那串参数。


1.4 服务端跳转 vs 客户端跳转(DOM 型)

开放重定向按触发位置分两大类,攻击效果略有区别:

类型 触发位置 典型特征 可利用性
服务端重定向 后端代码 返回 302/301 状态码 + Location 头 高,最常见,钓鱼效果最好
客户端重定向(DOM型) 前端 JS 代码 window.location = url 跳转 中,可能被浏览器策略限制

额外提一句:DOM 型开放重定向在某些场景下甚至可以升级为 XSS------如果跳转支持 javascript: 伪协议的话,直接就能执行 JS 代码,危害直接上一个档次。


1.5 常见攻击场景与业务危害

很多人觉得开放重定向就是个"低危小漏洞",其实它的危害被严重低估了。

主要攻击场景:

  1. 钓鱼诈骗(最主流)

    这是开放重定向的本职工作。用可信域名当幌子,把用户骗到高仿钓鱼页偷账号密码,成功率比直接发陌生域名高得多。

  2. OAuth 授权令牌窃取

    如果 OAuth 的 redirect_uri 校验不严,或者可信域内存在开放重定向,攻击者可以把授权码/access_token 拐到自己的服务器,直接接管用户账号。

  3. 绕过 SSRF 防护

    有些 SSRF 防护只校验请求的域名是不是内网,攻击者可以让服务端先请求一个带开放重定向的外网地址,再由重定向跳到内网,变相绕过防护。

  4. 恶意软件分发

    把下载链接伪装成可信站点的跳转,用户以为是官方下载,实际下的是木马病毒。

  5. 绕过邮件安全网关

    企业邮件网关通常会过滤恶意域名的链接,但开放重定向的链接主域名是可信的,很容易绕过检测进到用户收件箱。


1.6 漏洞在安全榜单中的定位

  • CWE 编号:CWE-601 --- URL Redirection to Untrusted Site(开放重定向的标准定义)
  • OWASP Top 10 :虽然没有单独列项,但常被归类到 A01:2021 - Broken Access Control (访问控制失效)或 A03:2021 - Injection(注入)的范畴,属于"不起眼但到处都是"的基础漏洞
  • CTF 定位:属于 Web 方向的基础考点,经常和 SSRF、XSS、CSRF、OAuth 等知识点结合出题,单独考的话一般是送分题,但组合起来就是难题
  • 漏洞评级 :单独的开放重定向一般评 低危到中危 ,但如果能结合 OAuth 偷 token、配合 SSRF 打内网,直接升级为 高危甚至严重

一句话总结:开放重定向本身伤害不高,但作为"攻击链的粘合剂"极其好用,经常是组合拳里的关键一环。


对,接下来就是 Low 级别,我们按黑盒探测 → 漏洞利用 → 源码审计的顺序来。


2. DVWA Open HTTP Redirect(Low)

2.1 页面黑盒探测

先不看源码,我们以渗透测试者的视角,先摸清楚这个页面的功能。

进入 DVWA 的 Open HTTP Redirect 模块,首先看到页面上有三个链接,分别指向 info.php?id=1info.php?id=2info.php?id=3,看起来是跳转到不同的信息页面。

随便点一个,比如第一个,抓包看一下:

黑盒初步结论:

base 复制代码
GET /vulnerabilities/open_redirect/source/low.php?redirect=info.php?id=1 HTTP/1.1
  • 存在一个 redirect 参数,用来控制跳转目标
  • 服务端返回 302 状态码,通过 Location 头触发跳转
  • 目前传的是站内相对路径 info.php?id=1

那问题来了:如果我把 redirect 参数改成一个外部网址,会发生什么?这就是我们要验证的漏洞点。


2.2 黑盒漏洞利用实操

Low 级别,顾名思义,就是最菜的级别,一般没有任何防护。我们直接来测。

2.2.1 直接构造恶意跳转 URL

测试思路:redirect 参数的值直接换成一个外部域名,看能不能跳过去。

构造 Payload:

base 复制代码
vulnerabilities/open_redirect/source/low.php?redirect=https://www.baidu.com

把这个 URL 在抓到的包里面改一下。

结果: 啪一下,很快啊,直接跳到百度首页了。

说明 Low 级别完全没有任何校验,你传什么 URL 它就跳什么,连是站内还是站外都不检查。


2.2.2 伪装可信域名钓鱼链接(实战场景)

光跳个百度没什么意思,我们来模拟真实的钓鱼场景。

假设攻击者的钓鱼网站是 https://evil.com/fake-login(高仿 DVWA 登录页),攻击者会构造这样的恶意链接:

base 复制代码
http://你的DVWA地址/vulnerabilities/open_redirect/source/low.php?redirect=https://evil.com/fake-login

然后把这个链接发给受害者,话术比如:

"系统升级,请点击链接重新登录:http://你的DVWA地址/..."

受害者一看,域名是正经的 DVWA 地址(或者真实场景下是公司官网、银行官网),放心点进去,结果直接被重定向到钓鱼页面,输入账号密码就中招了。

为什么钓鱼成功率高?

  • 链接主域名是可信的,用户不会怀疑
  • 跳转过程是服务端 302,速度极快,用户几乎察觉不到
  • 钓鱼页面可以做得和官方一模一样,普通用户根本分辨不出来

2.3 源码审计(无校验直接跳转)

Low 级别的源码非常简单,一共就几行,我们逐行来看:

php 复制代码
<?php

// 第1步:检查 redirect 参数是否存在且不为空
if (array_key_exists ("redirect", $_GET) && $_GET['redirect'] != "") {
    
    // 第2步:直接把 redirect 参数的值拼到 Location 头里,触发跳转
    header ("location: " . $_GET['redirect']);
    exit;
}

// 如果参数不存在或为空,返回500错误
http_response_code (500);
?>
<p>Missing redirect target.</p>
<?php
exit;
?>

代码逻辑拆解:

  1. 参数检查 :用 array_key_exists 判断 GET 请求里有没有 redirect 参数,并且值不为空
  2. 直接跳转 :拿到参数值后,没有做任何校验 ,直接拼到 Location 响应头里返回给浏览器
  3. 错误处理:参数缺失的话返回 500 状态码和提示文字

漏洞点就在第 4 行:

php 复制代码
header ("location: " . $_GET['redirect']);

$_GET['redirect'] 是用户完全可控的输入,开发者没有检查它是不是站内地址、是不是合法域名、是不是允许的协议,直接就拿来跳转了。

你传 info.php?id=1 它跳站内页,你传 https://evil.com 它就跳恶意网站,照单全收。

一句话总结 Low 级别: 完全没有任何安全防护,属于"开发者根本没想过跳转功能会被滥用"的典型反面教材。


3. DVWA Open HTTP Redirect(Medium)

好,接下来 Medium 级别。开发者觉得 Low 太菜了,加了点防护,但是------没加对,照样能绕。


3.1 黑盒探测

还是老规矩,先不看源码,从黑盒视角一步步摸。

3.1.1 基础功能测试

先把 DVWA 难度切到 Medium,进入 Open HTTP Redirect 模块。

页面看起来和 Low 级别一模一样,还是三个链接,点一下试试:

base 复制代码
vulnerabilities/open_redirect/source/medium.php?redirect=info.php?id=1

正常跳转,没问题,基础功能和 Low 一样。

3.1.2 验证协议过滤防护机制

那我们直接上 Low 级别的 Payload 试试,看还能不能用:

base 复制代码
medium.php?redirect=https://www.baidu.com

结果: 页面报错了,提示 Absolute URLs not allowed.(不允许使用绝对URL)。

说明 Medium 级别确实加了防护,不让直接跳 http://https:// 开头的绝对地址。

那我们再试几个变种,看看防护到底有多严:

测试 Payload 结果
https://baidu.com ❌ 被拦截
http://baidu.com ❌ 被拦截
HTTP://baidu.com ❓ 试试大写
//baidu.com ❓ 试试不带协议
ftp://baidu.com ❓ 试试其他协议
3.1.3 黑盒推导校验规则

经过一轮测试,我们大概能摸出 Medium 的校验规则:

  1. 过滤了 http://https:// 开头的绝对 URL

    • 只要参数里包含 http://https://,就直接拒绝
    • 大小写都试了,HTTP:// 也被拦,说明正则是不区分大小写的
  2. 相对路径没问题

    • info.php?id=1 这种站内相对路径正常跳转
    • 说明校验只针对"绝对URL",相对路径不受影响
  3. //baidu.com 这种不带协议的呢?

    • 这就是我们的突破口------协议相对 URL

3.2 黑盒攻击实操

3.2.1 协议相对 URL 绕过原理

先讲一个冷知识:URL 可以省略协议部分,只写 //域名,这种写法叫协议相对 URL(Protocol-relative URL)

比如 //www.baidu.com,浏览器会自动使用当前页面的协议(http 或 https)来补全这个 URL。

举个例子:

  • 你在 https://dvwa.com/ 页面上访问 //evil.com
  • 浏览器会自动补全为 https://evil.com
  • 效果和写完整的 https://evil.com 一模一样

为什么能绕过?

  • Medium 的正则只过滤 http://https:// 开头的字符串
  • 协议相对 URL 是 // 开头,不带 http 字样
  • 正则匹配不到,直接放行了
  • 但浏览器拿到 //evil.com 照样能跳转到外部站点

完美绕过分检。


3.2.2 构造 //evil.com 恶意 Payload

知道原理就简单了,构造 Payload:

base 复制代码
medium.php?redirect=//www.baidu.com

注意:前面没有 http:https:,直接就是两个斜杠。


3.2.3 攻击复现步骤

第一步:构造恶意链接

base 复制代码
http://你的DVWA地址/vulnerabilities/open_redirect/source/medium.php?redirect=//evil.com/fake-login

第二步:发给受害者

还是熟悉的社工话术,链接看起来还是正经的 DVWA 域名。

第三步:受害者点击跳转

用户点进去 → 服务端返回 302,Location 是 //evil.com/fake-login → 浏览器自动补全协议为 https://evil.com/fake-login → 成功跳转到钓鱼站点。

还有一种就是使用ftp://baidu.com

ftp://baidu.com:协议替换绕过,唤起系统 FTP 工具跳转外部站点;

传入该Payload后,Medium正则仅匹配http://https://,不含ftp关键字,校验直接放行

浏览器接收到Location: ftp://baidu.com响应头,会触发系统弹窗询问是否打开对应应用(你截图里的跳转唤起弹窗就是这个原理),同样达成跳转到外部非信任站点的效果,属于第二种绕过思路。


3.2.4 正则过滤存在的逻辑缺陷

为什么开发者加了防护还是被绕了?核心问题出在两个地方:

缺陷一:只过滤了协议头,没考虑协议相对 URL

开发者想的是"只要不让写完整的 http/https URL 就安全了",但忘了还有 // 这种写法。

缺陷二:黑名单思路本身就不靠谱

用黑名单过滤危险字符/字符串,永远是被动防御,攻击者总能找到你没考虑到的变种。今天你过滤了 http://,明天还有 //\\javascript:、各种编码绕过......

一句话总结: 黑名单防御防不胜防,白名单才是正道。


3.3 源码审计

Medium 级别的源码如下,我们逐行拆解:

php 复制代码
<?php

// 第1步:检查 redirect 参数是否存在且不为空
if (array_key_exists ("redirect", $_GET) && $_GET['redirect'] != "") {
    
    // 第2步:正则匹配,检查参数里有没有 http:// 或 https://
    if (preg_match ("/http:\/\/|https:\/\//i", $_GET['redirect'])) {
        // 匹配到了 → 拦截,返回500错误
        http_response_code (500);
        ?>
        <p>Absolute URLs not allowed.</p>
        <?php
        exit;
    } else {
        // 没匹配到 → 直接跳转
        header ("location: " . $_GET['redirect']);
        exit;
    }
}

// 参数缺失的情况
http_response_code (500);
?>
<p>Missing redirect target.</p>
<?php
exit;
?>

代码逻辑拆解:

  1. 参数校验 :先判断 redirect 参数有没有传、是不是空
  2. 正则过滤 :核心防护就在第 4 行的 preg_match
    • 正则表达式:/http:\/\/|https:\/\//i
    • 意思是:匹配 http:// 或者 https://,末尾的 /i 表示不区分大小写
    • 匹配到了就拦截,没匹配到就放行跳转

防护的缺陷:

这个正则只认 http://https:// 两种协议,其他的一概不管。所以:

Payload 正则是否匹配 结果
http://evil.com ✅ 匹配到 http:// ❌ 拦截
https://evil.com ✅ 匹配到 https:// ❌ 拦截
//evil.com ❌ 没有 http 字样 ✅ 放行 → 协议相对URL绕过
ftp://evil.com ❌ 是 ftp 不是 http ✅ 放行 → 协议替换绕过
javascript:alert(1) ❌ 没有 http ✅ 放行 → 伪协议绕过(DOM型可用)

一句话总结 Medium 级别: 用黑名单思路只封了 http/https 两个协议,没考虑协议相对 URL 和其他协议,属于"防了但没完全防"的典型反面教材。


好,接下来 High 级别。开发者觉得 Medium 的防护太菜了,换了个思路------强制要求跳转地址里必须包含 info.php,以为这样就只能跳站内页了。但还是太年轻。


4. DVWA Open HTTP Redirect(High)

4.1 黑盒探测

还是老规矩,先不看源码,从黑盒视角一步步摸。

4.1.1 抓包对比 Low/Medium 行为差异

把 DVWA 难度切到 High,进入 Open HTTP Redirect 模块。

页面看起来还是一样的,三个链接,点一下正常跳转:

base 复制代码
high.php?redirect=info.php?id=1

正常跳转,没问题。


4.1.2 复用 Medium 的 Payload 测试(完全失效)

先试试 Low 和 Medium 的 Payload 还能不能用:

测试1:直接外部URL(Low 级别 Payload)

base 复制代码
high.php?redirect=https://www.baidu.com

结果:报错,提示 You can only redirect to the info page.(你只能跳转到 info 页面)

测试2:协议相对URL(Medium 级别 Payload)

base 复制代码
high.php?redirect=//www.baidu.com

结果:还是报错,同样的提示。

测试3:ftp协议绕过

base 复制代码
high.php?redirect=ftp://baidu.com

结果:依然报错。

看来 Medium 级别的绕过手法在 High 这里完全失效了,防护升级了。


4.1.3 黑盒推导校验规则

报错信息很关键:You can only redirect to the info page.

"只能跳转到 info 页面"------那它是怎么判断你跳的是不是 info 页面的呢?

我们来做几组测试,摸清楚校验规则:

测试 Payload 结果 推测
info.php?id=1 ✅ 正常跳转 正常情况
info.php ✅ 正常跳转 不带参数也可以
INFO.PHP ❌ 报错 区分大小写
abcinfo.php ✅ 正常跳转 前面加东西也行?
info.php/../ ✅ 正常跳转 后面加东西也可以?
https://evil.com ❌ 报错 没有 info.php 就不行
https://evil.com/info.php ❓ 试试这个

关键测试:

base 复制代码
high.php?redirect=https://evil.com/info.php

结果: 居然跳转了!虽然跳的是 https://evil.com/info.php(一个不存在的页面),但确实成功跳转到了外部域名 evil.com

黑盒结论:

High 级别的校验规则是------只要 redirect 参数的值里包含 info.php 这个子串,就放行 ,不管这个 info.php 在 URL 的什么位置,也不管整个 URL 是不是站内地址。

这就好办了。


4.2 黑盒攻击绕过实操

4.2.1 子串匹配校验漏洞原理

High 级别用的是子串匹配 的校验思路:只要 URL 里有 info.php 这几个字,就认为你跳的是站内的 info 页面,是安全的。

但这个逻辑有个致命缺陷:info.php 可以出现在 URL 的任意位置,包括域名后面、参数里、路径里......

攻击者只要在恶意 URL 里随便找个地方塞上 info.php 这几个字,就能骗过校验。


4.2.2 外部域名拼接 info.php 构造 Payload

知道原理就简单了,我们有好几种构造方式:

方式一:路径拼接(最常用)

base 复制代码
high.php?redirect=https://evil.com/info.php

info.php 当成恶意站点上的一个路径,骗过校验。

方式二:参数拼接(更隐蔽)

base 复制代码
high.php?redirect=https://evil.com/phish?x=info.php

info.php 藏在 URL 参数里,不影响实际跳转目标。

方式三:锚点拼接

base 复制代码
high.php?redirect=https://evil.com/phish#info.php

info.php 放在锚点(#后面),完全不影响页面跳转。

三种方式都能成功绕过,实战推荐用参数拼接,最隐蔽。


4.2.3 完整攻击复现

第一步:构造恶意钓鱼链接

base 复制代码
http://你的DVWA地址/vulnerabilities/open_redirect/source/high.php?redirect=https://evil.com/fake-login?foo=info.php

注意看:redirect 参数的值是 https://evil.com/fake-login?foo=info.php

  • 真实目标:https://evil.com/fake-login(钓鱼页面)
  • 凑数用的:?foo=info.php(只是为了骗过校验,不影响实际跳转)

第二步:发给受害者

链接主域名还是正经的 DVWA 地址,用户看不出问题。

第三步:受害者点击跳转

用户点进去 → 服务端检查到 URL 里有 info.php,放行 → 302 跳转到 https://evil.com/fake-login?foo=info.php → 钓鱼页面正常显示(那个 foo=info.php 参数对钓鱼页面毫无影响)。

完美绕过,效果和 Low 级别一模一样。


4.3 High 级别源码审计

High 级别的源码如下,我们逐行拆解:

php 复制代码
<?php

// 第1步:检查 redirect 参数是否存在且不为空
if (array_key_exists ("redirect", $_GET) && $_GET['redirect'] != "") {
    
    // 第2步:用 strpos 检查参数里有没有 "info.php" 这个子串
    if (strpos($_GET['redirect'], "info.php") !== false) {
        // 找到了 info.php → 认为是合法的,直接跳转
        header ("location: " . $_GET['redirect']);
        exit;
    } else {
        // 没找到 info.php → 拦截,返回500错误
        http_response_code (500);
        ?>
        <p>You can only redirect to the info page.</p>
        <?php
        exit;
    }
}

// 参数缺失的情况
http_response_code (500);
?>
<p>Missing redirect target.</p>
<?php
exit;
?>

代码逻辑拆解:

  1. 参数校验 :先判断 redirect 参数有没有传、是不是空
  2. 关键字匹配 :核心防护就在第 4 行的 strpos
    • 函数:strpos(字符串, 子串)
    • 作用:查找子串在字符串中第一次出现的位置
    • !== false 表示:只要能找到 info.php 这几个字就行,不管它在什么位置
  3. 找到了就直接跳转,没找到就拦截报错

防护的致命缺陷:

strpos 只检查"有没有",不检查"在哪"。只要 URL 里任意位置出现了 info.php 这 8 个字符,就会被判定为合法。

所以:

Payload strpos 是否找到 info.php 结果
info.php?id=1 ✅ 开头就是 ✅ 正常跳转
https://evil.com/info.php ✅ 路径里有 ✅ 绕过 → 跳外部站点
https://evil.com/?x=info.php ✅ 参数里有 ✅ 绕过 → 跳外部站点
https://evil.com#info.php ✅ 锚点里有 ✅ 绕过 → 跳外部站点

开发者以为"强制要求包含 info.php = 只能跳站内 info 页面",但实际上只要在恶意 URL 里随便找个地方塞上 info.php 这几个字,就能轻松骗过校验。

一句话总结 High 级别: 子串匹配校验思路太想当然,只验证了"有没有关键字",没验证"是不是真的站内地址",属于典型的"防了但防错了地方"。


5. DVWA Open HTTP Redirect(Impossible)

5.1 源码审计

完整源码逐行解析:

php 复制代码
<?php
$target = "";

// 双重校验:参数存在 + 参数必须为纯数字
if (array_key_exists ("redirect", $_GET) && is_numeric($_GET['redirect'])) {
    // 将参数转为整数,通过switch硬编码白名单映射跳转地址
    switch (intval ($_GET['redirect'])) {
        case 1:
            $target = "info.php?id=1";
            break;
        case 2:
            $target = "info.php?id=2";
            break;
        case 99:
            $target = "https://digi.ninja";
            break;
    }
    // 存在匹配的预设地址才执行跳转
    if ($target != "") {
        header ("location: " . $target);
        exit;
    } else {
        ?>
        Unknown redirect target.
        <?php
        exit;
    }
}

?>
Missing redirect target.

三层闭环防御机制

  1. 输入类型强过滤

    is_numeric($_GET['redirect']) 限制 redirect 只能传入数字,彻底杜绝用户自定义URL字符串 ,攻击者无法传入 https://evil.com//evil.comftp://xxx 等任何恶意跳转Payload。

  2. 硬编码白名单映射(核心防御)

    跳转目标 $target 不由用户输入直接赋值,而是通过数字索引匹配后端预先写死的固定地址:

  • 1 → 固定跳转 info.php?id=1
  • 2 → 固定跳转 info.php?id=2
  • 99 → 固定跳转 https://digi.ninja
    除此之外所有数字都不会赋值 $target,直接提示未知跳转目标。
  1. 跳转数据源完全可控
    最终 header("location: " . $target) 拼接的变量是后端写死的静态字符串,全程无任何用户可控内容参与URL构造,不存在篡改跳转地址的空间。

漏洞结论

Impossible 级别完全不存在开放重定向漏洞 ,不存在任何绕过方式。即便内置了一条外部域名 https://digi.ninja,该地址也是后端固定写死,攻击者无法修改、替换成任意恶意站点,不会产生钓鱼风险。


5.2 四级对比总结(Low/Medium/High/Impossible)

难度 防护逻辑 核心缺陷 是否可绕过
Low 无任何校验,直接拼接用户输入跳转 完全信任用户可控参数 可,任意外部URL直接跳转
Medium 黑名单正则过滤http:///https:// 仅拦截网页协议,忽略协议相对URL、ftp等其他协议 可,//evil.comftp://evil.com绕过
High 子串匹配,校验URL包含info.php 仅检查关键字是否存在,不校验关键字位置与站点归属 可,恶意URL拼接info.php绕过
Impossible 数字强限制+硬编码白名单映射 无缺陷,用户无法控制跳转目标URL 不可绕过,彻底封堵漏洞

5.3 最终安全修复方案

  1. 禁止直接使用用户输入拼接跳转地址;
  2. 使用数字索引+固定白名单映射,由后端预设全部合法跳转地址;
  3. 若业务必须接收URL参数,采用完整域名白名单校验,而非黑名单/子串匹配;
  4. 外部域名跳转增加二次确认页面,阻断钓鱼攻击链路。

免责声明

  1. 本文所有内容仅用于网络安全技术研究与教学演示,所有测试均在本地授权搭建的 DVWA 靶场环境中进行,旨在帮助读者理解漏洞原理与防御机制。
  2. 请勿将本文涉及的技术与方法用于任何未经授权的真实系统测试。任何利用本文内容进行的非法攻击行为,均与作者无关,由使用者自行承担相应法律责任。
  3. 网络安全学习请严格遵守《中华人民共和国网络安全法》及相关法律法规,仅在获得明确书面授权的前提下开展安全测试。
相关推荐
Tsuki_tl5 小时前
UDP传输协议
网络·网络协议·udp·传输层·udp校验和·tcp与udp区别·面向数据报
信仰8745 小时前
HCIA-华为数通基础理论与实践08
网络·笔记·华为
代码的小搬运工8 小时前
网络请求(NSURL、NSURLRequest、NSURLSessionDataTask、协议回调与 JSON 数据的基本流向)
网络·数据库·json
头茬韭菜13 小时前
4.4 文件编辑安全 — 权限决策与脏写防护的工程实现
安全
蓝胖的四次元口袋13 小时前
服务器网络与系统基础-面试题
服务器·网络
Cx330❀14 小时前
【MySQL基础】一文吃透“表的约束”:从 Null/Default 到主外键的终极安全法则
linux·服务器·数据库·c++·mysql·安全
醉颜凉14 小时前
“三把钥匙开一把锁”:多签钱包深度解析与资产安全提升指南
安全·区块链
Haoxuekeji14 小时前
山东 AI 智能批改校园电子阅卷企业
大数据·人工智能·深度学习·安全·ai
程序员JerrySUN14 小时前
Jetson 刷机深度解析:flash.sh vs l4t_initrd_flash.sh(含安全与磁盘加密对比)
linux·网络·arm开发·安全·系统安全