MENU

URL跳转漏洞-容易忽视的漏洞

November 14, 2018 • Read: 1716 • 安全测试阅读设置

 URL跳转漏洞

不是点击url跳转么,什么这样也算一个漏洞?

漏洞成因

  1. URL跳转的实现方式:
  • META标签内跳转
  • Javascript跳转
  • header头跳转

通过以GET或POST方式接收要跳转的URL,再通过以上的几种方式来跳转到目标的URL;
一方面,由于用户的输入会进入到meta,JavaScript,http头都可能发生相应的漏洞,例如xss等
同时,URL跳转是将用户从信任站点导向到不信任站点,如果同时跳转时带有敏感信息,也可以被第三方获取到。

下面为模拟两种跳转代码:

<?php
if(isset($_GET["url"])) {
$target = $_GET['url'];
//使用服务器端302跳转
//header("location: ".$target);

//使用html的方式跳转
echo "<script>window.location.href=\"$target\"</script>";
exit;
} else {
echo "Please input the URL";
}
?>

使用html直接跳转:

使用服务端302跳转:

漏洞影响

WooYun-2013-26212-我是如何漫游腾讯内部网络的

某里巴巴存在任意URL跳转漏洞(提交被驳回故公开)技术交流

挖掘思路

常见位置

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

常见的参数名:

redirect
redirect_to
redirect_url
url
jump
jump_to
target
to
link
linkto
domain

利用方式

后面假设源域名为:www.landgrey.me 要跳转过去的域为:evil.com

1. 直接跳转

没做任何限制,参数后直接跟要跳转过去的网址就行:

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

2. 协议一致性

当程序员校验跳转的网址协议必须为 https 时 (有时候跳转不过去不会给提示):

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

3. 域名字符串检测欺骗

  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

一个京东的实例:

  1. 还有的会检测域名结尾是不是当前域名,是的话才会跳转,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
  1. 可信站多次重定向绕过

利用已知可重定向到自己域名的可信站点的重定向,来最终重定向自己控制的站点。

一种是利用程序自己的公共白名单可信站点,如 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

4. 畸形地址绕过

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

案例一:这个案例 ,通过添加多余的 "/"(%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 个特殊字符:

";", "/", "\", "?", ":", "@", "=", "&", "."

一个 “协议型” 的网址示例:

http://user:pass@testweb.com/path/;help.php?q=abc#lastpage

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//..

上面的方法有些是有案例,有些是别人总结的,有些是有原理依循的,比如第 4 条,利用 "@" 符号前的 "www.landgrey.me" 是指 "www.evil.com" 域的一个用户名来绕过。

5. 其它绕过思路

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

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

0x02:防护方法

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

总结

学习了url跳转漏洞才知道,洞无大小。重要是的安全

参考文章:
URL 跳转漏洞 bypass 小结

Archives QR Code Tip
QR Code for this page
Tipping QR Code