URL重定向学习(含pikachu)

什么是重定向

URL重定向(URL redirection,或称网址重定向或网域名称转址),是指当使用者浏览某个网址时,将他导向到另一个网址的技术。

重定向原理


HTTP 协议的重定向响应的状态码为 3xx 。浏览器在接收到重定向响应的时候,会采用该响应提供的新的 URL ,并立即进行加载;大多数情况下,除了会有一小部分性能损失之外,重定向操作对于用户来说是不可见的。

重定向的分类

永久重定向
临时重定向
特殊重定向

URL重定向漏洞成因

1.写代码时没有考虑过任意URL跳转漏洞,或者根本不知道/不认为这是个漏洞;
2.写代码时考虑不周,用取子串、取后缀等方法简单判断,代码逻辑可被绕过;
3.对传入参数做一些奇葩的操作(域名剪切/拼接/重组)和判断,适得其反,反被绕过;
4.原始语言自带的解析URL、判断域名的函数库出现逻辑漏洞或者意外特性,可被绕过;
5.原始语言、服务器/容器特性、浏览器等对标准URL协议解析处理等差异性导致被绕过;

实现url跳转的方式

1.设定重定向映射
300=Multiple Choices
301=Moved Permanently
302=Found
303=See Other
304=Not Modified
305=Use Proxy
306=(Unused)
307=Temporary Redirect

其中以301、302、307最为常见,301代表永久转址,对于搜索引擎判定页面改变有直接影响,302代表暂时转址,通常用于页面暂时修改,之后会在恢复网址时使用。在搜索引擎优化上,将错误的302转址改成301转址对网站排名有相当作用。

2.借助 HTML 的 meta 元素的 HTML 重定向机制
例子:

<head> 
  <meta http-equiv="refresh" content="0;URL=http://www.example.com/" />
</head>

content 属性的值开头是一个数字,指示浏览器在等待该数字表示的秒数之后再进行跳转。建议始终将其设置为 0 来获取更好的可访问性。
显然,该方法仅适用于 HTML 页面(或类似的页面),然而并不能应用于图片或者其他类型的内容。
注意这种机制会使浏览器的回退按钮失效:可以返回含有这个头部的页面,但是又会立即跳转。

3.借助 DOM 的 JavaScript 重定向机制
window.location = “http://www.example.com/”;
与 HTML 重定向机制类似,这种方式并不适用于所有类型的资源,并且显然只有在支持 JavaScript的客户端上才能使用。另外一方面,它也提供了更多的可能性,比如在只有满足了特定的条件的情况下才可以触发重定向机制的场景。

4.三种重定向方法的优先级
1、HTTP 协议的重定向机制永远最先触发,即便是在没有传送任何页面——也就没有页面被(客户端)读取——的情况下。
2、HTML 的重定向机制 () 会在 HTTP 协议重定向机制未设置的情况下触发。
3、JavaScript 的重定向机制总是作为最后诉诸的手段,并且只有在客户端开启了 JavaScript 的情况下才起作用。
任何情况下,只要有可能,就应该采用 HTTP 协议的重定向机制,而不要使用 meta 标签。假如开发人员修改了 HTTP 重定向映射而忘记修改 HTML 页面的重定向映射,那么二者就会不一致,最终结果或者出现无限循环,或者导致其他噩梦的发生。

url转发和重定向区别

第一种是request.getRequestDispatcher().forward(request,response):
1、属于转发,也是服务器跳转,也可以叫做内部重定向,相当于方法调用,在执行当前文件的过程中转向执行目标文件,两个文件(当前文件和目标文件)属于同一次请求,前后页共用一个request,可以通过此来传递一些数据或者session信息,request.setAttribute()和request.getAttribute()。
2、在前后两次执行后,地址栏不变,仍是当前文件的地址。
3、不能转向到本web应用之外的页面和网站,所以转向的速度要快。
4、URL中所包含的“/”表示应用程序(项目)的路径。

第二种是response.sendRedirect():
1、属于重定向,也是客户端跳转,相当于客户端向服务端发送请求之后,服务器返回一个响应,客户端接收到响应之后又向服务端发送一次请求,一共是2次请求,前后页不共用一个request,不能读取转向前通过request.setAttribute()设置的属性值。
2、在前后两次执行后,地址栏发生改变,是目标文件的地址。
3、可以转向到本web应用之外的页面和网站,所以转向的速度相对要慢。
4、URL种所包含的"/"表示根目录的路径。

ssrf和url重定向区别

SSRF是服务器帮你去访问,url重定向其实也是服务器帮忙去访问,那么感觉SSRF可能能实现url重定向功能,也应该可以用来钓鱼,区别的话可能SSRF能帮忙探测内网,而url重定向是访问外网

常见的url跳转代码

Java:
response.sendRedirect(request.getParameter(“url”))

PHP:
$redirect_url = $_GET[‘url’];
header("Location: " . $redirect_url)

.NET:
string redirect_url = request.QueryString[“url”];
Response.Redirect(redirect_url);

Django:
redirect_url = request.GET.get(“url”)
HttpResponseRedirect(redirect_url)

Flask:
redirect_url = request.form[‘url’]
redirect(redirect_url)

Rails:
redirect_to params[:url]

常见参数名
redirect
redirect_to
redirect_url
url
jump
jump_to
target
to
link
linkto
domain

重定向的利用

使用场景
用户登录、统一身份认证处,认证完后会跳转
用户分享、收藏内容过后,会跳转
跨站点认证、授权后,会跳转
站内点击其它网址链接时,会跳转

利用方法
后面假设源域名为:www.landgrey.me 要跳转过去的域为:evil.com
直接跳转
https://www.landgrey.me/redirect.php?url=http://www.evil.com/untrust.html
协议一致性
当程序员校验跳转的网址协议必须为https时(有时候跳转不过去不会给提示):
https://www.landgrey.me/redirect.php?url=https://www.evil.com/untrust.html
域名字符串检测欺骗
1) 有的程序员会检测当前的域名字符串是否在要跳转过去的字符串中,是子字符串时才会跳转,php代码如:

<?php
$redirect_url = $_GET['url'];
if(strstr($redirect_url,"www.landgrey.me") !== false){
    header("Location: " . $redirect_url);
}
else{
    die("Forbidden");
}

即:https://www.landgrey.me/redirect.php?url=http://www.landgrey.me.www.evil.com/untrust.html

2)还有的会检测域名结尾是不是当前域名,是的话才会跳转,Django示例代码如下:
redirect_url = request.GET.get(“url”)
if redirect_url.endswith(‘landgrey.me’):
HttpResponseRedirect(redirect_url)
else:
HttpResponseRedirect(“https://www.landgrey.me”)

绕过:
https://www.landgrey.me/redirect.php?url=http://www.evil.com/www.landgrey.me
或者买个xxxlandgrey.me域名,然后绕过:
https://www.landgrey.me/redirect.php?url=http://xxxlandgrey.me

3)可信站多次重定向绕过
利用已知可重定向到自己域名的可信站点的重定向,来最终重定向自己控制的站点。
一种是利用程序自己的公共白名单可信站点,如www.baidu.com,其中百度有个搜索的缓存链接比如https://www.baidu.com/linkurl=iMwwNDM6ahaxKkSFuOG,可以最终跳转到自己网站,然后测试时:
https://www.landgrey.me/redirect.php?url=https://www.baidu.com/linkurl=iMwwNDM6ahaxKkSFuOG
就可以跳到自己的站点了
另一种类似,但是程序的跳转白名单比较严格,只能是自己域的地址,这时需要有一个目标其它域的任意跳转漏洞,比如https://auth.landgrey.me/jump.do?url=evil.com,然后测试时:
https://www.landgrey.me/redirect.php?url=https://auth.landgrey.me/jump.do?url=evil.com

畸形地址绕过
这一部分由于各种语言、框架和代码实现的不同,防护任意跳转代码的多种多样;导致绕过方式乍看起来很诡异,有多诡异?举三个案例:

案例一:这个案例 ,通过添加多余的"/"(%2F)符号,再对".“两次url编码成”%252E"绕过代码中对域名后".com"的切割, 构造类似
https://landgrey.me/%2Fevil%252Ecom
达到了任意URL跳转的目的。

案例二:这个案例,通过添加4个"/“前缀和”/…"后缀,构造类似
https://landgrey.me/redirect.php?url=www.evil.com/…

案例三:这个案例,通过"."字符,构造类似
https://landgrey.me/redirect.php?url=http://www.evil.com.landgrey.me

手工测试时,主要结合目标对输入的跳转处理和提示,根据经验来绕过;
自动化测试时,通常是根据目标和规则,事先生成payload,用工具(如burpsuite)在漏洞点处自动发包测试;

复杂的案例,在当时测试时一般有相关提示信息,不然就是自动化fuzzing出的,实际中手工bypass的难度和花费太大。

URL跳转漏洞复杂的真实例子也比较难找。黑盒测试,经常是测试成功也不能确定到底是哪里出的问题。要达到绕过效果,主要涉及以下9个特殊字符:
“;”, “/”, “”, “?”, “:”, “@”, “=”, “&”, “.”

10种bypass方式

  1. 单斜线"/"绕过
    https://www.landgrey.me/redirect.php?url=/www.evil.com
  2. 缺少协议绕过
    https://www.landgrey.me/redirect.php?url=//www.evil.com
  3. 多斜线"/"前缀绕过
    https://www.landgrey.me/redirect.php?url=///www.evil.com
    https://www.landgrey.me/redirect.php?url=www.evil.com
  4. 利用"@"符号绕过
    https://www.landgrey.me/redirect.php?url=https://www.landgrey.me@www.evil.com
  5. 利用反斜线""绕过
    https://www.landgrey.me/redirect.php?url=https://www.evil.com\www.landgrey.me
  6. 利用"#"符号绕过
    https://www.landgrey.me/redirect.php?url=https://www.evil.com#www.landgrey.me
  7. 利用"?"号绕过
    https://www.landgrey.me/redirect.php?url=https://www.evil.com?www.landgrey.me
  8. 利用"\"绕过
    https://www.landgrey.me/redirect.php?url=https://www.evil.com\www.landgrey.me
  9. 利用"."绕过
    https://www.landgrey.me/redirect.php?url=.evil (可能会跳转到www.landgrey.me.evil域名)
    https://www.landgrey.me/redirect.php?url=.evil.com (可能会跳转到evil.com域名)
    10.重复特殊字符绕过
    https://www.landgrey.me/redirect.php?url=///www.evil.com//…
    https://www.landgrey.me/redirect.php?url=www.evil.com//…

其它绕过思路

  1. 跳转到IP地址,而不是域名;
  2. 跳转到IPV6地址,而不是IPv4地址;
  3. 将要跳转到的IP地址用10进制、8进制、16进制形式表示;
  4. 更换协议,使用ftp、gopher协议等;
  5. 借鉴SSRF漏洞绕过的tricks;
  6. CRLF注入不能xss时,转向利用任意URL跳转漏洞;

自动化利用
参考Github上已总结的测试payload(很杂,一些可能根本没有实例,完全是YY),按情况替换里面的域名。在黑盒情况下,可以用来批量发包测试。

防护方法

  1. 代码固定跳转地址,不让用户控制变量
  2. 跳转目标地址采用白名单映射机制
    比如1代表auth.landgrey.me,2代表www.landgrey.me,其它不做任何动作
  3. 合理充分的校验校验跳转的目标地址,非己方地址时告知用户跳转风险

重定向循环


当后续的重定向路径重复之前的路径的时候,重定向循环就产生了。换句话说,就是陷入了无限循环当中,不会有一个最终的页面返回。
大多数情况下,这属于服务器端错误。如果服务器检测不到,就会返回 500 Internal Server Error 。假如你在修改了服务器配置不久就出现了这个问题,八成是遇到了重定向循环。
有时候,服务器端无法对其进行检测:重定向循环发生于多台服务器之间,对于每一台服务器来说,都无法获得一个全景图。在这种情况下,浏览器会负责进行检测,然后返回错误信息。

pikachu练习不安全的url跳转

在这里插入图片描述
发现根据url的不同, 页面也随之不同
将url的值改为其他网址:
http://localhost/pikachu-master/vul/urlredirect/urlredirect.php?url=https://www.baidu.com

在这里插入图片描述

成功跳转

防范


理论上讲,url跳转属于CSRF的一种,我们需要对传入的URL做有效性的认证,保证该URL来自于正确的地方,限制的方式同防止csrf一样可以包括:

  1. Referer的限制
    如果确定传递URL参数进入的来源,我们可以通过该方式实现安全限制,保证该URL的有效性,避免恶意用户自己生成跳转链接
  2. 有效性验证Token
    我们保证所有生成的链接都是来自于我们可信域的,通过在生成的链接里加入用户不可控的Token对生成的链接进行校验,可以避免用户生成自己的恶意链接从而被利用,但是如果功能本身要求比较开放,可能导致有一定的限制。
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值